forked from cory/tildefriends
Make blob store actually not block the main thread.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4352 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
62
src/ssb.db.c
62
src/ssb.db.c
@ -12,6 +12,7 @@
|
||||
#include "sodium/crypto_secretbox.h"
|
||||
#include "sodium/crypto_sign.h"
|
||||
#include "sqlite3.h"
|
||||
#include "uv.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -335,7 +336,7 @@ bool tf_ssb_db_store_message(tf_ssb_t* ssb, JSContext* context, const char* id,
|
||||
if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_int64(statement, 1, last_row_id) == SQLITE_OK &&
|
||||
sqlite3_bind_int(statement, 2, k_blob_id_len - 1) == SQLITE_OK)
|
||||
sqlite3_bind_int(statement, 2, k_blob_id_len - 1) == SQLITE_OK)
|
||||
{
|
||||
int r = SQLITE_OK;
|
||||
while ((r = sqlite3_step(statement)) == SQLITE_ROW)
|
||||
@ -445,6 +446,65 @@ bool tf_ssb_db_blob_get(tf_ssb_t* ssb, const char* id, uint8_t** out_blob, size_
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef struct _blob_store_work_t
|
||||
{
|
||||
uv_work_t work;
|
||||
tf_ssb_t* ssb;
|
||||
const uint8_t* blob;
|
||||
size_t size;
|
||||
char id[k_blob_id_len];
|
||||
bool is_new;
|
||||
tf_ssb_db_blob_store_callback_t* callback;
|
||||
void* user_data;
|
||||
} blob_store_work_t;
|
||||
|
||||
static void _tf_ssb_db_blob_store_work(uv_work_t* work)
|
||||
{
|
||||
blob_store_work_t* blob_work = work->data;
|
||||
tf_ssb_db_blob_store(blob_work->ssb, blob_work->blob, blob_work->size, blob_work->id, sizeof(blob_work->id), &blob_work->is_new);
|
||||
}
|
||||
|
||||
static void _tf_ssb_db_blob_store_after_work(uv_work_t* work, int status)
|
||||
{
|
||||
blob_store_work_t* blob_work = work->data;
|
||||
if (status != 0)
|
||||
{
|
||||
tf_printf("tf_ssb_db_blob_store_async -> uv_queue_work failed asynchronously: %s\n", uv_strerror(status));
|
||||
}
|
||||
if (blob_work->callback)
|
||||
{
|
||||
blob_work->callback(status == 0 ? blob_work->id : NULL, blob_work->is_new, blob_work->user_data);
|
||||
}
|
||||
tf_free(blob_work);
|
||||
}
|
||||
|
||||
void tf_ssb_db_blob_store_async(tf_ssb_t* ssb, const uint8_t* blob, size_t size, tf_ssb_db_blob_store_callback_t* callback, void* user_data)
|
||||
{
|
||||
blob_store_work_t* work = tf_malloc(sizeof(blob_store_work_t));
|
||||
*work = (blob_store_work_t)
|
||||
{
|
||||
.work =
|
||||
{
|
||||
.data = work,
|
||||
},
|
||||
.ssb = ssb,
|
||||
.blob = blob,
|
||||
.size = size,
|
||||
.callback = callback,
|
||||
.user_data = user_data,
|
||||
};
|
||||
int r = uv_queue_work(tf_ssb_get_loop(ssb), &work->work, _tf_ssb_db_blob_store_work, _tf_ssb_db_blob_store_after_work);
|
||||
if (r)
|
||||
{
|
||||
tf_printf("tf_ssb_db_blob_store_async -> uv_queue_work failed immediately: %s\n", uv_strerror(r));
|
||||
if (callback)
|
||||
{
|
||||
callback(NULL, false, user_data);
|
||||
}
|
||||
tf_free(work);
|
||||
}
|
||||
}
|
||||
|
||||
bool tf_ssb_db_blob_store(tf_ssb_t* ssb, const uint8_t* blob, size_t size, char* out_id, size_t out_id_size, bool* out_new)
|
||||
{
|
||||
bool result = false;
|
||||
|
Reference in New Issue
Block a user