Browse Source

consolidate 3 SQLite connections into 1 shared handle

- utun_node.cpp: open topo_sqlite_db with FULLMUTEX + all PRAGMAs (WAL, FK, NORMAL sync, checkpoint)
- db_sync.c: reuse inst->topo_sqlite_db if available (shared_db flag)
- chat_core.c: reuse inst->topo_sqlite_db if available (shared_db flag)
- db_sync_destroy/chat_core_destroy: skip close on shared handle
- Only topo_groups_destroy closes the shared handle
- Fallback: each module opens own connection if topo_sqlite_db is NULL
topo_upd
Evgeny 3 months ago
parent
commit
29e2527b6b
  1. 21
      src/db_sync.c
  2. 25
      tools/chatgui/transport/chat_core.c
  3. 22
      tools/chatgui/transport/utun_node.cpp

21
src/db_sync.c

@ -58,6 +58,7 @@ struct DB_SYNC_INSTANCE {
struct DB_SYNC {
struct UTUN_INSTANCE* inst;
sqlite3* db;
uint8_t shared_db; /* db == inst->topo_sqlite_db, do not close */
uint64_t last_connected_tb;
struct DB_SYNC_INSTANCE* instances;
int instance_count, instance_capacity;
@ -110,7 +111,7 @@ static int db_sqlite_open(struct DB_SYNC* db, const char* path)
static void db_sqlite_close(struct DB_SYNC* db)
{
DEBUG_TRACE(DEBUG_CATEGORY_DB_SYNC, "");
if (!db->db) return;
if (!db->db || db->shared_db) return;
sqlite3_close(db->db);
db->db = NULL;
DEBUG_INFO(DEBUG_CATEGORY_DB_SYNC, "db_sync: SQLite closed");
@ -1376,13 +1377,17 @@ int db_sync_init(struct UTUN_INSTANCE* inst)
inst->db_sync = db;
const char* dp = inst->config->global.db_path;
char sp[512];
if (dp[0]) snprintf(sp, sizeof(sp), "%s/chats.db", dp);
else snprintf(sp, sizeof(sp), "/tmp/utun_db_sync");
if (db_sqlite_open(db, sp) != 0) {
DEBUG_WARN(DEBUG_CATEGORY_DB_SYNC, "SQLite open failed, sync disabled");
db->enabled = 0;
if (inst->topo_sqlite_db) {
db->db = inst->topo_sqlite_db; db->shared_db = 1;
DEBUG_INFO(DEBUG_CATEGORY_DB_SYNC, "db_sync: using shared SQLite db=%p", (void*)db->db);
} else {
char sp[512];
if (dp[0]) snprintf(sp, sizeof(sp), "%s/chats.db", dp);
else snprintf(sp, sizeof(sp), "/tmp/utun_db_sync");
if (db_sqlite_open(db, sp) != 0) {
DEBUG_WARN(DEBUG_CATEGORY_DB_SYNC, "SQLite open failed, sync disabled");
db->enabled = 0;
}
}
etcp_bind(inst, ETCP_RT_ID_DB_SYNC, db_sync_recv_cb);

25
tools/chatgui/transport/chat_core.c

@ -37,6 +37,7 @@
static struct chat_core_ctx {
struct UTUN_INSTANCE* inst;
sqlite3* db;
uint8_t shared_db; /* db == inst->topo_sqlite_db, do not close */
uint64_t my_node_id;
/* db_sync instances per channel */
@ -91,15 +92,20 @@ int chat_core_init(struct UTUN_INSTANCE* inst, const char* db_path) {
if (!inst || !db_path) return -1;
memset(&g_cc, 0, sizeof(g_cc));
int rc = sqlite3_open_v2(db_path, &g_cc.db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL);
if (rc != SQLITE_OK) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTIVITY, "%s: cannot open DB %s: %s",
CC_ID, db_path, sqlite3_errmsg(g_cc.db));
sqlite3_close(g_cc.db); g_cc.db = NULL; return -1;
if (inst->topo_sqlite_db) {
g_cc.db = inst->topo_sqlite_db; g_cc.shared_db = 1;
DEBUG_INFO(DEBUG_CATEGORY_CONNECTIVITY, "%s: using shared SQLite db=%p", CC_ID, (void*)g_cc.db);
} else {
int rc = sqlite3_open_v2(db_path, &g_cc.db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL);
if (rc != SQLITE_OK) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTIVITY, "%s: cannot open DB %s: %s",
CC_ID, db_path, sqlite3_errmsg(g_cc.db));
sqlite3_close(g_cc.db); g_cc.db = NULL; return -1;
}
sqlite3_exec(g_cc.db, "PRAGMA journal_mode=WAL", NULL, NULL, NULL);
sqlite3_exec(g_cc.db, "PRAGMA foreign_keys=ON", NULL, NULL, NULL);
}
sqlite3_exec(g_cc.db, "PRAGMA journal_mode=WAL", NULL, NULL, NULL);
sqlite3_exec(g_cc.db, "PRAGMA foreign_keys=ON", NULL, NULL, NULL);
g_cc.inst = inst;
g_cc.my_node_id = inst->node_id;
@ -229,7 +235,8 @@ void chat_core_destroy(struct UTUN_INSTANCE* inst) {
if (!g_cc.initialized) return;
g_cc.initialized = 0;
if (g_cc.db) { sqlite3_close(g_cc.db); g_cc.db = NULL; }
if (g_cc.db && !g_cc.shared_db) { sqlite3_close(g_cc.db); }
g_cc.db = NULL;
g_cc.inst = NULL;
DEBUG_INFO(DEBUG_CATEGORY_CONNECTIVITY, "%s: destroyed", CC_ID);
}

22
tools/chatgui/transport/utun_node.cpp

@ -26,6 +26,7 @@ extern "C" {
#include "chat_core.h"
#include "db_sync.h"
#include "gui_bridge.h"
#include "../src/topo_node_sqlite.h"
}
#define ETCP_RT_ID_CHAT 0x11
@ -260,6 +261,27 @@ void UtunNode::runLoop() {
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_INFO(DEBUG_CATEGORY_DEBUG, "SQLite (shared): %s db=%p", db_file, (void*)m_instance->topo_sqlite_db);
} else {
DEBUG_ERROR(DEBUG_CATEGORY_DEBUG, "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);

Loading…
Cancel
Save