• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdlib.h>
2 #include "node_api.h"
3 #include "uv.h"
4 #include "../../js-native-api/common.h"
5 
RunInCallbackScope(napi_env env,napi_callback_info info)6 static napi_value RunInCallbackScope(napi_env env, napi_callback_info info) {
7   size_t argc;
8   napi_value args[3];
9 
10   NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, NULL, NULL, NULL));
11   NODE_API_ASSERT(env, argc == 3 , "Wrong number of arguments");
12 
13   NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
14 
15   napi_valuetype valuetype;
16   NODE_API_CALL(env, napi_typeof(env, args[0], &valuetype));
17   NODE_API_ASSERT(env, valuetype == napi_object,
18       "Wrong type of arguments. Expects an object as first argument.");
19 
20   NODE_API_CALL(env, napi_typeof(env, args[1], &valuetype));
21   NODE_API_ASSERT(env, valuetype == napi_string,
22       "Wrong type of arguments. Expects a string as second argument.");
23 
24   NODE_API_CALL(env, napi_typeof(env, args[2], &valuetype));
25   NODE_API_ASSERT(env, valuetype == napi_function,
26       "Wrong type of arguments. Expects a function as third argument.");
27 
28   napi_async_context context;
29   NODE_API_CALL(env, napi_async_init(env, args[0], args[1], &context));
30 
31   napi_callback_scope scope = NULL;
32   NODE_API_CALL(env,
33       napi_open_callback_scope(env, args[0], context, &scope));
34 
35   // If the function has an exception pending after the call that is ok
36   // so we don't use NODE_API_CALL as we must close the callback scope
37   // regardless.
38   napi_value result = NULL;
39   napi_status function_call_result =
40       napi_call_function(env, args[0], args[2], 0, NULL, &result);
41   if (function_call_result != napi_ok) {
42     GET_AND_THROW_LAST_ERROR((env));
43   }
44 
45   NODE_API_CALL(env, napi_close_callback_scope(env, scope));
46   NODE_API_CALL(env, napi_async_destroy(env, context));
47 
48   return result;
49 }
50 
51 static napi_env shared_env = NULL;
52 static napi_deferred deferred = NULL;
53 
Callback(uv_work_t * req,int ignored)54 static void Callback(uv_work_t* req, int ignored) {
55   napi_env env = shared_env;
56 
57   napi_handle_scope handle_scope = NULL;
58   NODE_API_CALL_RETURN_VOID(env, napi_open_handle_scope(env, &handle_scope));
59 
60   napi_value resource_name;
61   NODE_API_CALL_RETURN_VOID(env, napi_create_string_utf8(
62       env, "test", NAPI_AUTO_LENGTH, &resource_name));
63   napi_async_context context;
64   NODE_API_CALL_RETURN_VOID(env,
65       napi_async_init(env, NULL, resource_name, &context));
66 
67   napi_value resource_object;
68   NODE_API_CALL_RETURN_VOID(env, napi_create_object(env, &resource_object));
69 
70   napi_value undefined_value;
71   NODE_API_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined_value));
72 
73   napi_callback_scope scope = NULL;
74   NODE_API_CALL_RETURN_VOID(env,
75       napi_open_callback_scope(env, resource_object, context, &scope));
76 
77   NODE_API_CALL_RETURN_VOID(env,
78       napi_resolve_deferred(env, deferred, undefined_value));
79 
80   NODE_API_CALL_RETURN_VOID(env, napi_close_callback_scope(env, scope));
81 
82   NODE_API_CALL_RETURN_VOID(env, napi_close_handle_scope(env, handle_scope));
83   NODE_API_CALL_RETURN_VOID(env, napi_async_destroy(env, context));
84   free(req);
85 }
86 
NoopWork(uv_work_t * work)87 static void NoopWork(uv_work_t* work) { (void) work; }
88 
TestResolveAsync(napi_env env,napi_callback_info info)89 static napi_value TestResolveAsync(napi_env env, napi_callback_info info) {
90   napi_value promise = NULL;
91   if (deferred == NULL) {
92     shared_env = env;
93     NODE_API_CALL(env, napi_create_promise(env, &deferred, &promise));
94 
95     uv_loop_t* loop = NULL;
96     NODE_API_CALL(env, napi_get_uv_event_loop(env, &loop));
97 
98     uv_work_t* req = malloc(sizeof(*req));
99     uv_queue_work(loop,
100                   req,
101                   NoopWork,
102                   Callback);
103   }
104   return promise;
105 }
106 
Init(napi_env env,napi_value exports)107 static napi_value Init(napi_env env, napi_value exports) {
108   napi_property_descriptor descriptors[] = {
109     DECLARE_NODE_API_PROPERTY("runInCallbackScope", RunInCallbackScope),
110     DECLARE_NODE_API_PROPERTY("testResolveAsync", TestResolveAsync)
111   };
112 
113   NODE_API_CALL(env, napi_define_properties(
114       env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors));
115 
116   return exports;
117 }
118 
119 NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
120