async.h 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #ifndef NODE_SQLITE3_SRC_ASYNC_H
  2. #define NODE_SQLITE3_SRC_ASYNC_H
  3. #include <napi.h>
  4. #include <uv.h>
  5. #include "threading.h"
  6. // Generic uv_async handler.
  7. template <class Item, class Parent> class Async {
  8. typedef void (*Callback)(Parent* parent, Item* item);
  9. protected:
  10. uv_async_t watcher;
  11. NODE_SQLITE3_MUTEX_t
  12. std::vector<Item*> data;
  13. Callback callback;
  14. public:
  15. Parent* parent;
  16. public:
  17. Async(Parent* parent_, Callback cb_)
  18. : callback(cb_), parent(parent_) {
  19. watcher.data = this;
  20. NODE_SQLITE3_MUTEX_INIT
  21. uv_loop_t *loop;
  22. napi_get_uv_event_loop(parent_->Env(), &loop);
  23. uv_async_init(loop, &watcher, reinterpret_cast<uv_async_cb>(listener));
  24. }
  25. static void listener(uv_async_t* handle) {
  26. auto* async = static_cast<Async*>(handle->data);
  27. std::vector<Item*> rows;
  28. NODE_SQLITE3_MUTEX_LOCK(&async->mutex)
  29. rows.swap(async->data);
  30. NODE_SQLITE3_MUTEX_UNLOCK(&async->mutex)
  31. for(auto row : rows)
  32. async->callback(async->parent, row);
  33. }
  34. static void close(uv_handle_t* handle) {
  35. assert(handle != NULL);
  36. assert(handle->data != NULL);
  37. auto* async = static_cast<Async*>(handle->data);
  38. delete async;
  39. }
  40. void finish() {
  41. // Need to call the listener again to ensure all items have been
  42. // processed. Is this a bug in uv_async? Feels like uv_close
  43. // should handle that.
  44. listener(&watcher);
  45. uv_close((uv_handle_t*)&watcher, close);
  46. }
  47. void add(Item* item) {
  48. NODE_SQLITE3_MUTEX_LOCK(&mutex);
  49. data.emplace_back(item);
  50. NODE_SQLITE3_MUTEX_UNLOCK(&mutex)
  51. }
  52. void send() {
  53. uv_async_send(&watcher);
  54. }
  55. void send(Item* item) {
  56. add(item);
  57. send();
  58. }
  59. ~Async() {
  60. NODE_SQLITE3_MUTEX_DESTROY
  61. }
  62. };
  63. #endif