Allow running read-only sqlite queries from libuv worker threads. Needs so much more testing.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4172 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
2023-02-08 01:29:44 +00:00
parent ac60be14a5
commit b35d74ce36
7 changed files with 332 additions and 93 deletions

View File

@ -171,8 +171,12 @@ typedef struct _tf_ssb_t
tf_trace_t* trace;
const char* db_path;
sqlite3* db;
bool owns_db;
uv_mutex_t db_readers_lock;
sqlite3** db_readers;
int db_readers_count;
uv_loop_t own_loop;
uv_loop_t* loop;
@ -2064,7 +2068,7 @@ void tf_ssb_get_stats(tf_ssb_t* ssb, tf_ssb_stats_t* out_stats)
ssb->rpc_out = 0;
}
tf_ssb_t* tf_ssb_create(uv_loop_t* loop, JSContext* context, sqlite3* db)
tf_ssb_t* tf_ssb_create(uv_loop_t* loop, JSContext* context, const char* db_path)
{
tf_ssb_t* ssb = tf_malloc(sizeof(tf_ssb_t));
memset(ssb, 0, sizeof(*ssb));
@ -2082,6 +2086,8 @@ tf_ssb_t* tf_ssb_create(uv_loop_t* loop, JSContext* context, sqlite3* db)
ssb->context = JS_NewContext(ssb->runtime);
}
uv_mutex_init(&ssb->db_readers_lock);
JS_NewClassID(&_connection_class_id);
JSClassDef def =
{
@ -2090,15 +2096,8 @@ tf_ssb_t* tf_ssb_create(uv_loop_t* loop, JSContext* context, sqlite3* db)
};
JS_NewClass(JS_GetRuntime(ssb->context), _connection_class_id, &def);
if (db)
{
ssb->db = db;
}
else
{
sqlite3_open("db.sqlite", &ssb->db);
ssb->owns_db = true;
}
ssb->db_path = tf_strdup(db_path);
sqlite3_open(db_path, &ssb->db);
tf_ssb_db_init(ssb);
if (loop)
@ -2131,6 +2130,30 @@ sqlite3* tf_ssb_get_db(tf_ssb_t* ssb)
return ssb->db;
}
sqlite3* tf_ssb_acquire_db_reader(tf_ssb_t* ssb)
{
sqlite3* db = NULL;
uv_mutex_lock(&ssb->db_readers_lock);
if (ssb->db_readers_count)
{
db = ssb->db_readers[--ssb->db_readers_count];
}
else
{
sqlite3_open_v2(ssb->db_path, &db, SQLITE_OPEN_READONLY, NULL);
}
uv_mutex_unlock(&ssb->db_readers_lock);
return db;
}
void tf_ssb_release_db_reader(tf_ssb_t* ssb, sqlite3* db)
{
uv_mutex_lock(&ssb->db_readers_lock);
ssb->db_readers = tf_resize_vec(ssb->db_readers, sizeof(sqlite3*) * (ssb->db_readers_count + 1));
ssb->db_readers[ssb->db_readers_count++] = db;
uv_mutex_unlock(&ssb->db_readers_lock);
}
uv_loop_t* tf_ssb_get_loop(tf_ssb_t* ssb)
{
return ssb->loop;
@ -2289,10 +2312,7 @@ void tf_ssb_destroy(tf_ssb_t* ssb)
JS_FreeContext(ssb->context);
JS_FreeRuntime(ssb->runtime);
}
if (ssb->owns_db)
{
sqlite3_close(ssb->db);
}
sqlite3_close(ssb->db);
while (ssb->broadcasts)
{
tf_ssb_broadcast_t* broadcast = ssb->broadcasts;
@ -2307,6 +2327,12 @@ void tf_ssb_destroy(tf_ssb_t* ssb)
tf_free(ssb->debug_close[i].messages[j]);
}
}
for (int i = 0; i < ssb->db_readers_count; i++)
{
sqlite3_close(ssb->db_readers[i]);
}
uv_mutex_destroy(&ssb->db_readers_lock);
tf_free((void*)ssb->db_path);
tf_free(ssb);
}