|
|
|
|
@ -211,9 +211,25 @@ void UtunNode::runLoop() {
|
|
|
|
|
} |
|
|
|
|
m_ua = ua; |
|
|
|
|
|
|
|
|
|
m_instance = utun_instance_create(ua, m_configPath.toUtf8().constData()); |
|
|
|
|
/* Читаем конфиг и выставляем db_path ДО создания инстанса, чтобы topo_groups_init
|
|
|
|
|
* (внутри utun_instance_create_from_config) открыл общую SQLite-БД раньше auto_socket_init — |
|
|
|
|
* иначе auto_socket не сможет сохранить/переиспользовать порты (БД ещё не открыта). */ |
|
|
|
|
struct utun_config* cfg = parse_config(m_configPath.toUtf8().constData()); |
|
|
|
|
if (!cfg) { |
|
|
|
|
QMetaObject::invokeMethod(this, [this] { emit error("parse_config failed"); }); |
|
|
|
|
uasync_destroy(ua, 0); |
|
|
|
|
m_ua = nullptr; |
|
|
|
|
g_currentNode = nullptr; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
cfg->global.db_sync_enabled = 1; |
|
|
|
|
if (!m_dbPath.isEmpty()) |
|
|
|
|
snprintf(cfg->global.db_path, sizeof(cfg->global.db_path), "%s", m_dbPath.toUtf8().constData()); |
|
|
|
|
|
|
|
|
|
m_instance = utun_instance_create_from_config(ua, cfg); |
|
|
|
|
if (!m_instance) { |
|
|
|
|
QMetaObject::invokeMethod(this, [this] { emit error("utun_instance_create failed"); }); |
|
|
|
|
free_config(cfg); |
|
|
|
|
QMetaObject::invokeMethod(this, [this] { emit error("utun_instance_create_from_config failed"); }); |
|
|
|
|
uasync_destroy(ua, 0); |
|
|
|
|
m_ua = nullptr; |
|
|
|
|
g_currentNode = nullptr; |
|
|
|
|
@ -222,33 +238,6 @@ void UtunNode::runLoop() {
|
|
|
|
|
|
|
|
|
|
m_instance->test_user_ptr = this; |
|
|
|
|
|
|
|
|
|
/* enable db_sync for chat message P2P sync */ |
|
|
|
|
m_instance->config->global.db_sync_enabled = 1; |
|
|
|
|
if (!m_dbPath.isEmpty()) |
|
|
|
|
snprintf(m_instance->config->global.db_path, sizeof(m_instance->config->global.db_path), |
|
|
|
|
"%s", m_dbPath.toUtf8().constData()); |
|
|
|
|
|
|
|
|
|
/* topo_groups_init did not open topo_sqlite_db because db_path was empty at that time.
|
|
|
|
|
* Open the single shared SQLite connection here with FULLMUTEX (GUI reads from another thread). |
|
|
|
|
* db_sync_init and chat_core_init will reuse this handle. */ |
|
|
|
|
if (m_instance->config->global.db_path[0] && !m_instance->topo_sqlite_db) { |
|
|
|
|
char db_file[512]; |
|
|
|
|
snprintf(db_file, sizeof(db_file), "%s/chats.db", m_instance->config->global.db_path); |
|
|
|
|
int rc = sqlite3_open_v2(db_file, &m_instance->topo_sqlite_db, |
|
|
|
|
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL); |
|
|
|
|
if (rc == SQLITE_OK && m_instance->topo_sqlite_db) { |
|
|
|
|
sqlite3_exec(m_instance->topo_sqlite_db, "PRAGMA journal_mode=WAL", NULL, NULL, NULL); |
|
|
|
|
sqlite3_exec(m_instance->topo_sqlite_db, "PRAGMA foreign_keys=ON", NULL, NULL, NULL); |
|
|
|
|
sqlite3_exec(m_instance->topo_sqlite_db, "PRAGMA synchronous=NORMAL", NULL, NULL, NULL); |
|
|
|
|
sqlite3_exec(m_instance->topo_sqlite_db, "PRAGMA wal_autocheckpoint=10000", NULL, NULL, NULL); |
|
|
|
|
topo_node_sqlite_init(m_instance->topo_sqlite_db); |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_GENERAL, "SQLite (shared): %s db=%p", db_file, (void*)m_instance->topo_sqlite_db); |
|
|
|
|
} else { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "SQLite open failed: %s rc=%d", db_file, rc); |
|
|
|
|
if (m_instance->topo_sqlite_db) { sqlite3_close(m_instance->topo_sqlite_db); m_instance->topo_sqlite_db = NULL; } |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* set ua for gui_bridge before init, so GUI can post */ |
|
|
|
|
gui_bridge_set_uasync(ua); |
|
|
|
|
|
|
|
|
|
|