|
|
|
|
@ -35,18 +35,9 @@ extern "C" {
|
|
|
|
|
|
|
|
|
|
static thread_local UtunNode* g_currentNode = nullptr; |
|
|
|
|
|
|
|
|
|
static volatile sig_atomic_t g_shutdown = 0; |
|
|
|
|
static struct UASYNC* g_signal_ua = nullptr; |
|
|
|
|
|
|
|
|
|
static void signal_handler(int sig) { |
|
|
|
|
(void)sig; |
|
|
|
|
g_shutdown = 1; |
|
|
|
|
if (g_signal_ua) uasync_wakeup(g_signal_ua); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
extern "C" void utun_node_signal_shutdown(void) { |
|
|
|
|
g_shutdown = 1; |
|
|
|
|
if (g_signal_ua) uasync_wakeup(g_signal_ua); |
|
|
|
|
if (g_currentNode) g_currentNode->requestStop(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
UtunNode::UtunNode(QObject* parent) : QObject(parent) {} |
|
|
|
|
@ -92,13 +83,32 @@ void UtunNode::setDebugCategories(const QString& categories) {
|
|
|
|
|
m_debugCategories = categories; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void UtunNode::requestStop() { |
|
|
|
|
m_stop = true; |
|
|
|
|
if (m_ua) uasync_wakeup(m_ua); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void UtunNode::stop() { |
|
|
|
|
if (!m_running) return; |
|
|
|
|
m_stop = true; |
|
|
|
|
requestStop(); |
|
|
|
|
if (m_thread.joinable()) m_thread.join(); |
|
|
|
|
finalize(); |
|
|
|
|
m_running = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void UtunNode::finalize() { |
|
|
|
|
if (!m_instance) return; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "finalize: cleanup start"); |
|
|
|
|
etcp_router_bind(m_instance, ETCP_RT_ID_CHAT, nullptr); |
|
|
|
|
chat_sync_destroy(m_instance); |
|
|
|
|
chat_core_destroy(m_instance); |
|
|
|
|
utun_instance_destroy(m_instance); |
|
|
|
|
m_instance = nullptr; |
|
|
|
|
uasync_destroy(m_ua, 0); |
|
|
|
|
m_ua = nullptr; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "finalize: cleanup done"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void UtunNode::send(uint64_t dstNodeId, const QByteArray& data) { |
|
|
|
|
if (!m_instance) return; |
|
|
|
|
struct ll_entry* entry = queue_entry_new(data.size()); |
|
|
|
|
@ -273,11 +283,13 @@ void UtunNode::runLoop() {
|
|
|
|
|
g_currentNode = nullptr; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
m_ua = ua; |
|
|
|
|
|
|
|
|
|
m_instance = utun_instance_create(ua, m_configPath.toUtf8().constData()); |
|
|
|
|
if (!m_instance) { |
|
|
|
|
QMetaObject::invokeMethod(this, [this] { emit error("utun_instance_create failed"); }); |
|
|
|
|
uasync_destroy(ua, 0); |
|
|
|
|
m_ua = nullptr; |
|
|
|
|
g_currentNode = nullptr; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
@ -319,6 +331,7 @@ void UtunNode::runLoop() {
|
|
|
|
|
utun_instance_destroy(m_instance); |
|
|
|
|
m_instance = nullptr; |
|
|
|
|
uasync_destroy(ua, 0); |
|
|
|
|
m_ua = nullptr; |
|
|
|
|
g_currentNode = nullptr; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
@ -336,31 +349,18 @@ void UtunNode::runLoop() {
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "chat_core + chat_sync initialized"); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "utun_node: entering poll loop"); |
|
|
|
|
|
|
|
|
|
g_signal_ua = ua; |
|
|
|
|
signal(SIGINT, signal_handler); |
|
|
|
|
signal(SIGTERM, signal_handler); |
|
|
|
|
|
|
|
|
|
while (!m_stop && !g_shutdown) { |
|
|
|
|
while (!m_stop) { |
|
|
|
|
uasync_poll(ua, 100); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "runLoop: poll exit m_stop=%d g_shutdown=%d", (int)m_stop, (int)g_shutdown); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "runLoop: poll exit m_stop=%d", (int)m_stop); |
|
|
|
|
|
|
|
|
|
signal(SIGINT, SIG_DFL); |
|
|
|
|
signal(SIGTERM, SIG_DFL); |
|
|
|
|
g_signal_ua = nullptr; |
|
|
|
|
|
|
|
|
|
etcp_router_bind(m_instance, ETCP_RT_ID_CHAT, nullptr); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "runLoop: etcp_router_unbind done"); |
|
|
|
|
chat_sync_destroy(m_instance); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "runLoop: chat_sync_destroy done"); |
|
|
|
|
chat_core_destroy(m_instance); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "runLoop: chat_core_destroy done"); |
|
|
|
|
utun_instance_destroy(m_instance); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "runLoop: utun_instance_destroy done"); |
|
|
|
|
m_instance = nullptr; |
|
|
|
|
uasync_destroy(ua, 0); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "runLoop: uasync_destroy done, emitting stopped"); |
|
|
|
|
g_currentNode = nullptr; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "runLoop: emitting stopped"); |
|
|
|
|
QMetaObject::invokeMethod(this, [this] { emit stopped(); }); |
|
|
|
|
} |
|
|
|
|
|