Refactor most uses of uv_queue_work to go through a helper that keeps track of thread business, traces, and is generally less code.

This commit is contained in:
2024-05-08 21:00:37 -04:00
parent 5ca5323782
commit 385524352c
6 changed files with 195 additions and 292 deletions

View File

@ -4,7 +4,6 @@
#include "mem.h"
#include "ssb.db.h"
#include "ssb.h"
#include "trace.h"
#include "util.js.h"
#include "sodium/crypto_box.h"
@ -302,8 +301,6 @@ static JSValue _tf_ssb_getAllIdentities(JSContext* context, JSValueConst this_va
typedef struct _active_identity_work_t
{
uv_work_t request;
tf_ssb_t* ssb;
JSContext* context;
const char* name;
const char* package_owner;
@ -322,29 +319,22 @@ static void _tf_ssb_getActiveIdentity_visit(const char* identity, void* user_dat
}
}
static void _tf_ssb_getActiveIdentity_work(uv_work_t* work)
static void _tf_ssb_getActiveIdentity_work(tf_ssb_t* ssb, void* user_data)
{
active_identity_work_t* request = work->data;
tf_ssb_record_thread_busy(request->ssb, true);
tf_trace_t* trace = tf_ssb_get_trace(request->ssb);
tf_trace_begin(trace, "_tf_ssb_getActiveIdentity_work");
sqlite3* db = tf_ssb_acquire_db_reader(request->ssb);
active_identity_work_t* request = user_data;
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
tf_ssb_db_identity_get_active(db, request->name, request->package_owner, request->package_name, request->identity, sizeof(request->identity));
tf_ssb_release_db_reader(request->ssb, db);
tf_ssb_release_db_reader(ssb, db);
if (!*request->identity)
{
tf_ssb_db_identity_visit(request->ssb, request->name, _tf_ssb_getActiveIdentity_visit, request);
tf_ssb_db_identity_visit(ssb, request->name, _tf_ssb_getActiveIdentity_visit, request);
}
tf_trace_end(trace);
tf_ssb_record_thread_busy(request->ssb, false);
}
static void _tf_ssb_getActiveIdentity_after_work(uv_work_t* work, int status)
static void _tf_ssb_getActiveIdentity_after_work(tf_ssb_t* ssb, int status, void* user_data)
{
active_identity_work_t* request = work->data;
active_identity_work_t* request = user_data;
JSContext* context = request->context;
if (request->result == 0)
{
@ -370,13 +360,12 @@ static void _tf_ssb_getActiveIdentity_after_work(uv_work_t* work, int status)
static JSValue _tf_ssb_getActiveIdentity(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
const char* name = JS_ToCString(context, argv[0]);
const char* package_owner = JS_ToCString(context, argv[1]);
const char* package_name = JS_ToCString(context, argv[2]);
active_identity_work_t* work = tf_malloc(sizeof(active_identity_work_t));
*work = (active_identity_work_t) {
.request = { .data = work },
.ssb = JS_GetOpaque(this_val, _tf_ssb_classId),
.context = context,
.name = tf_strdup(name),
.package_owner = tf_strdup(package_owner),
@ -387,18 +376,12 @@ static JSValue _tf_ssb_getActiveIdentity(JSContext* context, JSValueConst this_v
JS_FreeCString(context, package_owner);
JS_FreeCString(context, package_name);
int r = uv_queue_work(tf_ssb_get_loop(work->ssb), &work->request, _tf_ssb_getActiveIdentity_work, _tf_ssb_getActiveIdentity_after_work);
if (r)
{
_tf_ssb_getActiveIdentity_after_work(&work->request, r);
}
tf_ssb_run_work(ssb, _tf_ssb_getActiveIdentity_work, _tf_ssb_getActiveIdentity_after_work, work);
return result;
}
typedef struct _identity_info_work_t
{
uv_work_t request;
tf_ssb_t* ssb;
JSContext* context;
const char* name;
const char* package_owner;
@ -422,12 +405,12 @@ static void _tf_ssb_getIdentityInfo_visit(const char* identity, void* data)
;
}
static void _tf_ssb_getIdentityInfo_work(uv_work_t* work)
static void _tf_ssb_getIdentityInfo_work(tf_ssb_t* ssb, void* user_data)
{
identity_info_work_t* request = work->data;
tf_ssb_db_identity_visit(request->ssb, request->name, _tf_ssb_getIdentityInfo_visit, request);
identity_info_work_t* request = user_data;
tf_ssb_db_identity_visit(ssb, request->name, _tf_ssb_getIdentityInfo_visit, request);
sqlite3* db = tf_ssb_acquire_db_reader(request->ssb);
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
sqlite3_stmt* statement = NULL;
request->result = sqlite3_prepare(db,
"SELECT author, name FROM ( "
@ -467,12 +450,12 @@ static void _tf_ssb_getIdentityInfo_work(uv_work_t* work)
{
snprintf(request->active_identity, sizeof(request->active_identity), "%s", request->identities[0]);
}
tf_ssb_release_db_reader(request->ssb, db);
tf_ssb_release_db_reader(ssb, db);
}
static void _tf_ssb_getIdentityInfo_after_work(uv_work_t* work, int status)
static void _tf_ssb_getIdentityInfo_after_work(tf_ssb_t* ssb, int status, void* user_data)
{
identity_info_work_t* request = work->data;
identity_info_work_t* request = user_data;
JSContext* context = request->context;
JSValue result = JS_NewObject(context);
@ -514,13 +497,12 @@ static void _tf_ssb_getIdentityInfo_after_work(uv_work_t* work, int status)
static JSValue _tf_ssb_getIdentityInfo(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
const char* name = JS_ToCString(context, argv[0]);
const char* package_owner = JS_ToCString(context, argv[1]);
const char* package_name = JS_ToCString(context, argv[2]);
identity_info_work_t* work = tf_malloc(sizeof(identity_info_work_t));
*work = (identity_info_work_t) {
.request = { .data = work },
.ssb = JS_GetOpaque(this_val, _tf_ssb_classId),
.context = context,
.name = tf_strdup(name),
.package_owner = tf_strdup(package_owner),
@ -531,11 +513,7 @@ static JSValue _tf_ssb_getIdentityInfo(JSContext* context, JSValueConst this_val
JS_FreeCString(context, package_owner);
JS_FreeCString(context, package_name);
int r = uv_queue_work(tf_ssb_get_loop(work->ssb), &work->request, _tf_ssb_getIdentityInfo_work, _tf_ssb_getIdentityInfo_after_work);
if (r)
{
_tf_ssb_getIdentityInfo_after_work(&work->request, r);
}
tf_ssb_run_work(ssb, _tf_ssb_getIdentityInfo_work, _tf_ssb_getIdentityInfo_after_work, work);
return result;
}
@ -845,7 +823,6 @@ typedef struct _sql_work_t
uint8_t* rows;
size_t binds_count;
size_t rows_count;
uv_work_t request;
uv_async_t async;
uv_timer_t timeout;
uv_mutex_t lock;
@ -861,13 +838,10 @@ static void _tf_ssb_sql_append(uint8_t** rows, size_t* rows_count, const void* d
*rows_count += size;
}
static void _tf_ssb_sqlAsync_work(uv_work_t* work)
static void _tf_ssb_sqlAsync_work(tf_ssb_t* ssb, void* user_data)
{
sql_work_t* sql_work = work->data;
tf_ssb_record_thread_busy(sql_work->ssb, true);
tf_trace_t* trace = tf_ssb_get_trace(sql_work->ssb);
tf_trace_begin(trace, "sql_async_work");
sqlite3* db = tf_ssb_acquire_db_reader_restricted(sql_work->ssb);
sql_work_t* sql_work = user_data;
sqlite3* db = tf_ssb_acquire_db_reader_restricted(ssb);
uv_mutex_lock(&sql_work->lock);
sql_work->db = db;
uv_mutex_unlock(&sql_work->lock);
@ -975,9 +949,7 @@ static void _tf_ssb_sqlAsync_work(uv_work_t* work)
uv_mutex_lock(&sql_work->lock);
sql_work->db = NULL;
uv_mutex_unlock(&sql_work->lock);
tf_ssb_release_db_reader(sql_work->ssb, db);
tf_ssb_record_thread_busy(sql_work->ssb, false);
tf_trace_end(trace);
tf_ssb_release_db_reader(ssb, db);
}
static void _tf_ssb_sqlAsync_handle_close(uv_handle_t* handle)
@ -1003,12 +975,10 @@ static void _tf_ssb_sqlAsync_destroy(sql_work_t* work)
uv_close((uv_handle_t*)&work->async, _tf_ssb_sqlAsync_handle_close);
}
static void _tf_ssb_sqlAsync_after_work(uv_work_t* work, int status)
static void _tf_ssb_sqlAsync_after_work(tf_ssb_t* ssb, int status, void* user_data)
{
sql_work_t* sql_work = work->data;
tf_trace_t* trace = tf_ssb_get_trace(sql_work->ssb);
tf_trace_begin(trace, "sql_async_after_work");
JSContext* context = tf_ssb_get_context(sql_work->ssb);
sql_work_t* sql_work = user_data;
JSContext* context = tf_ssb_get_context(ssb);
uint8_t* p = sql_work->rows;
while (p < sql_work->rows + sql_work->rows_count)
{
@ -1093,7 +1063,6 @@ static void _tf_ssb_sqlAsync_after_work(uv_work_t* work, int status)
JS_FreeValue(context, sql_work->callback);
JS_FreeCString(context, sql_work->query);
_tf_ssb_sqlAsync_destroy(sql_work);
tf_trace_end(trace);
}
static void _tf_ssb_sqlAsync_timeout(uv_timer_t* timer)
@ -1120,10 +1089,6 @@ static JSValue _tf_ssb_sqlAsync(JSContext* context, JSValueConst this_val, int a
sql_work_t* work = tf_malloc(sizeof(sql_work_t));
*work = (sql_work_t)
{
.request =
{
.data = work,
},
.async =
{
.data = work,
@ -1183,11 +1148,7 @@ static JSValue _tf_ssb_sqlAsync(JSContext* context, JSValueConst this_val, int a
}
JS_FreeValue(context, value);
}
int r = uv_queue_work(tf_ssb_get_loop(ssb), &work->request, _tf_ssb_sqlAsync_work, _tf_ssb_sqlAsync_after_work);
if (r)
{
error_value = JS_ThrowInternalError(context, "uv_queue_work failed: %s", uv_strerror(r));
}
tf_ssb_run_work(ssb, _tf_ssb_sqlAsync_work, _tf_ssb_sqlAsync_after_work, work);
}
if (!JS_IsUndefined(error_value))
{
@ -1809,8 +1770,6 @@ static JSValue _tf_ssb_private_message_decrypt(JSContext* context, JSValueConst
typedef struct _following_t
{
uv_work_t work;
tf_ssb_t* ssb;
JSContext* context;
JSValue promise[2];
@ -1821,17 +1780,15 @@ typedef struct _following_t
const char* ids[];
} following_t;
static void _tf_ssb_following_work(uv_work_t* work)
static void _tf_ssb_following_work(tf_ssb_t* ssb, void* user_data)
{
following_t* following = work->data;
tf_ssb_record_thread_busy(following->ssb, true);
following->out_following = tf_ssb_db_following_deep(following->ssb, following->ids, following->ids_count, following->depth);
tf_ssb_record_thread_busy(following->ssb, false);
following_t* following = user_data;
following->out_following = tf_ssb_db_following_deep(ssb, following->ids, following->ids_count, following->depth);
}
static void _tf_ssb_following_after_work(uv_work_t* work, int status)
static void _tf_ssb_following_after_work(tf_ssb_t* ssb, int status, void* user_data)
{
following_t* following = work->data;
following_t* following = user_data;
JSContext* context = following->context;
if (status == 0)
{
@ -1878,14 +1835,8 @@ static JSValue _tf_ssb_following(JSContext* context, JSValueConst this_val, int
int ids_count = tf_util_get_length(context, argv[0]);
following_t* following = tf_malloc(sizeof(following_t) + sizeof(char*) * ids_count);
*following = (following_t)
{
.work =
{
.data = following,
},
*following = (following_t) {
.context = context,
.ssb = ssb,
};
JS_ToInt32(context, &following->depth, argv[1]);
@ -1903,11 +1854,7 @@ static JSValue _tf_ssb_following(JSContext* context, JSValueConst this_val, int
}
}
int r = uv_queue_work(tf_ssb_get_loop(ssb), &following->work, _tf_ssb_following_work, _tf_ssb_following_after_work);
if (r)
{
_tf_ssb_following_after_work(&following->work, r);
}
tf_ssb_run_work(ssb, _tf_ssb_following_work, _tf_ssb_following_after_work, following);
return result;
}