1 #include "node_api.h"
2 #include "assert.h"
3 #include "uv.h"
4 #include <stdlib.h>
5 #include "../../js-native-api/common.h"
6
MustNotCall(napi_async_cleanup_hook_handle hook,void * arg)7 static void MustNotCall(napi_async_cleanup_hook_handle hook, void* arg) {
8 assert(0);
9 }
10
11 struct AsyncData {
12 uv_async_t async;
13 napi_env env;
14 napi_async_cleanup_hook_handle handle;
15 };
16
CreateAsyncData()17 static struct AsyncData* CreateAsyncData() {
18 struct AsyncData* data = (struct AsyncData*) malloc(sizeof(struct AsyncData));
19 data->handle = NULL;
20 return data;
21 }
22
AfterCleanupHookTwo(uv_handle_t * handle)23 static void AfterCleanupHookTwo(uv_handle_t* handle) {
24 struct AsyncData* data = (struct AsyncData*) handle->data;
25 napi_status status = napi_remove_async_cleanup_hook(data->handle);
26 assert(status == napi_ok);
27 free(data);
28 }
29
AfterCleanupHookOne(uv_async_t * async)30 static void AfterCleanupHookOne(uv_async_t* async) {
31 uv_close((uv_handle_t*) async, AfterCleanupHookTwo);
32 }
33
AsyncCleanupHook(napi_async_cleanup_hook_handle handle,void * arg)34 static void AsyncCleanupHook(napi_async_cleanup_hook_handle handle, void* arg) {
35 struct AsyncData* data = (struct AsyncData*) arg;
36 uv_loop_t* loop;
37 napi_status status = napi_get_uv_event_loop(data->env, &loop);
38 assert(status == napi_ok);
39 int err = uv_async_init(loop, &data->async, AfterCleanupHookOne);
40 assert(err == 0);
41
42 data->async.data = data;
43 data->handle = handle;
44 uv_async_send(&data->async);
45 }
46
Init(napi_env env,napi_value exports)47 static napi_value Init(napi_env env, napi_value exports) {
48 {
49 struct AsyncData* data = CreateAsyncData();
50 data->env = env;
51 napi_add_async_cleanup_hook(env, AsyncCleanupHook, data, &data->handle);
52 }
53
54 {
55 struct AsyncData* data = CreateAsyncData();
56 data->env = env;
57 napi_add_async_cleanup_hook(env, AsyncCleanupHook, data, NULL);
58 }
59
60 {
61 napi_async_cleanup_hook_handle must_not_call_handle;
62 napi_add_async_cleanup_hook(
63 env, MustNotCall, NULL, &must_not_call_handle);
64 napi_remove_async_cleanup_hook(must_not_call_handle);
65 }
66
67 return NULL;
68 }
69
70 NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
71