4
4
#include <stdlib.h>
5
5
#include "../../js-native-api/common.h"
6
6
7
+ static int cleanup_hook_count = 0 ;
7
8
static void MustNotCall (napi_async_cleanup_hook_handle hook , void * arg ) {
8
9
assert (0 );
9
10
}
@@ -21,17 +22,20 @@ static struct AsyncData* CreateAsyncData() {
21
22
}
22
23
23
24
static void AfterCleanupHookTwo (uv_handle_t * handle ) {
25
+ cleanup_hook_count ++ ;
24
26
struct AsyncData * data = (struct AsyncData * ) handle -> data ;
25
27
napi_status status = napi_remove_async_cleanup_hook (data -> handle );
26
28
assert (status == napi_ok );
27
29
free (data );
28
30
}
29
31
30
32
static void AfterCleanupHookOne (uv_async_t * async ) {
33
+ cleanup_hook_count ++ ;
31
34
uv_close ((uv_handle_t * ) async , AfterCleanupHookTwo );
32
35
}
33
36
34
37
static void AsyncCleanupHook (napi_async_cleanup_hook_handle handle , void * arg ) {
38
+ cleanup_hook_count ++ ;
35
39
struct AsyncData * data = (struct AsyncData * ) arg ;
36
40
uv_loop_t * loop ;
37
41
napi_status status = napi_get_uv_event_loop (data -> env , & loop );
@@ -44,7 +48,31 @@ static void AsyncCleanupHook(napi_async_cleanup_hook_handle handle, void* arg) {
44
48
uv_async_send (& data -> async );
45
49
}
46
50
51
+ static void ObjectFinalizer (napi_env env , void * data , void * hint ) {
52
+ // AsyncCleanupHook and its subsequent callbacks are called twice.
53
+ assert (cleanup_hook_count == 6 );
54
+
55
+ napi_ref * ref = data ;
56
+ NODE_API_CALL_RETURN_VOID (env , napi_delete_reference (env , * ref ));
57
+ free (ref );
58
+ }
59
+
60
+ static void CreateObjectWrap (napi_env env ) {
61
+ napi_value js_obj ;
62
+ napi_ref * ref = malloc (sizeof (* ref ));
63
+ NODE_API_CALL_RETURN_VOID (env , napi_create_object (env , & js_obj ));
64
+ NODE_API_CALL_RETURN_VOID (
65
+ env , napi_wrap (env , js_obj , ref , ObjectFinalizer , NULL , ref ));
66
+ // create a strong reference so that the finalizer is called at shutdown.
67
+ NODE_API_CALL_RETURN_VOID (env , napi_reference_ref (env , * ref , NULL ));
68
+ }
69
+
47
70
static napi_value Init (napi_env env , napi_value exports ) {
71
+ // Reinitialize the static variable to be compatible with musl libc.
72
+ cleanup_hook_count = 0 ;
73
+ // Create object wrap before cleanup hooks.
74
+ CreateObjectWrap (env );
75
+
48
76
{
49
77
struct AsyncData * data = CreateAsyncData ();
50
78
data -> env = env ;
@@ -64,6 +92,9 @@ static napi_value Init(napi_env env, napi_value exports) {
64
92
napi_remove_async_cleanup_hook (must_not_call_handle );
65
93
}
66
94
95
+ // Create object wrap after cleanup hooks.
96
+ CreateObjectWrap (env );
97
+
67
98
return NULL ;
68
99
}
69
100
0 commit comments