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