aboutsummaryrefslogtreecommitdiff
path: root/updater/sql/mac/src/async.h
diff options
context:
space:
mode:
authorRaindropsSys <raindrops@equestria.dev>2024-06-13 15:46:03 +0200
committerRaindropsSys <raindrops@equestria.dev>2024-06-13 15:46:03 +0200
commite44e2fe070484e06d384a31ef2699c3a2d5d474e (patch)
tree2d5eb5d1b01646270d18cf1f2d94519966d6e7de /updater/sql/mac/src/async.h
downloadfaunerie-e44e2fe070484e06d384a31ef2699c3a2d5d474e.tar.gz
faunerie-e44e2fe070484e06d384a31ef2699c3a2d5d474e.tar.bz2
faunerie-e44e2fe070484e06d384a31ef2699c3a2d5d474e.zip
GitHub migration
Diffstat (limited to 'updater/sql/mac/src/async.h')
-rwxr-xr-xupdater/sql/mac/src/async.h76
1 files changed, 76 insertions, 0 deletions
diff --git a/updater/sql/mac/src/async.h b/updater/sql/mac/src/async.h
new file mode 100755
index 0000000..f36e4cb
--- /dev/null
+++ b/updater/sql/mac/src/async.h
@@ -0,0 +1,76 @@
+#ifndef NODE_SQLITE3_SRC_ASYNC_H
+#define NODE_SQLITE3_SRC_ASYNC_H
+
+#include <napi.h>
+#include <uv.h>
+
+#include "threading.h"
+
+// Generic uv_async handler.
+template <class Item, class Parent> class Async {
+ typedef void (*Callback)(Parent* parent, Item* item);
+
+protected:
+ uv_async_t watcher;
+ NODE_SQLITE3_MUTEX_t
+ std::vector<Item*> data;
+ Callback callback;
+public:
+ Parent* parent;
+
+public:
+ Async(Parent* parent_, Callback cb_)
+ : callback(cb_), parent(parent_) {
+ watcher.data = this;
+ NODE_SQLITE3_MUTEX_INIT
+ uv_loop_t *loop;
+ napi_get_uv_event_loop(parent_->Env(), &loop);
+ uv_async_init(loop, &watcher, reinterpret_cast<uv_async_cb>(listener));
+ }
+
+ static void listener(uv_async_t* handle) {
+ auto* async = static_cast<Async*>(handle->data);
+ std::vector<Item*> rows;
+ NODE_SQLITE3_MUTEX_LOCK(&async->mutex)
+ rows.swap(async->data);
+ NODE_SQLITE3_MUTEX_UNLOCK(&async->mutex)
+ for(auto row : rows)
+ async->callback(async->parent, row);
+ }
+
+ static void close(uv_handle_t* handle) {
+ assert(handle != NULL);
+ assert(handle->data != NULL);
+ auto* async = static_cast<Async*>(handle->data);
+ delete async;
+ }
+
+ void finish() {
+ // Need to call the listener again to ensure all items have been
+ // processed. Is this a bug in uv_async? Feels like uv_close
+ // should handle that.
+ listener(&watcher);
+ uv_close((uv_handle_t*)&watcher, close);
+ }
+
+ void add(Item* item) {
+ NODE_SQLITE3_MUTEX_LOCK(&mutex);
+ data.emplace_back(item);
+ NODE_SQLITE3_MUTEX_UNLOCK(&mutex)
+ }
+
+ void send() {
+ uv_async_send(&watcher);
+ }
+
+ void send(Item* item) {
+ add(item);
+ send();
+ }
+
+ ~Async() {
+ NODE_SQLITE3_MUTEX_DESTROY
+ }
+};
+
+#endif