File: test_uv_loop.cc

package info (click to toggle)
nodejs 22.14.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 246,928 kB
  • sloc: cpp: 1,582,349; javascript: 582,017; ansic: 82,400; python: 60,561; sh: 4,009; makefile: 2,263; asm: 1,732; pascal: 1,565; perl: 248; lisp: 222; xml: 42
file content (89 lines) | stat: -rw-r--r-- 2,647 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "../../js-native-api/common.h"

#include <node_api.h>
#include <uv.h>

#include <cassert>
#include <memory>
#include <utility>

template <typename T>
void* SetImmediate(napi_env env, T&& cb) {
  T* ptr = new T(std::move(cb));
  uv_loop_t* loop = nullptr;
  uv_check_t* check = new uv_check_t;
  check->data = ptr;
  NODE_API_ASSERT(env,
              napi_get_uv_event_loop(env, &loop) == napi_ok,
              "can get event loop");
  uv_check_init(loop, check);
  uv_check_start(check, [](uv_check_t* check) {
    std::unique_ptr<T> ptr {static_cast<T*>(check->data)};
    T cb = std::move(*ptr);
    uv_close(reinterpret_cast<uv_handle_t*>(check), [](uv_handle_t* handle) {
      delete reinterpret_cast<uv_check_t*>(handle);
    });

    assert(cb() != nullptr);
  });
  // Idle handle is needed only to stop the event loop from blocking in poll.
  uv_idle_t* idle = new uv_idle_t;
  uv_idle_init(loop, idle);
  uv_idle_start(idle, [](uv_idle_t* idle) {
    uv_close(reinterpret_cast<uv_handle_t*>(idle), [](uv_handle_t* handle) {
      delete reinterpret_cast<uv_check_t*>(handle);
    });
  });

  return nullptr;
}

static char dummy;

napi_value SetImmediateBinding(napi_env env, napi_callback_info info) {
  size_t argc = 1;
  napi_value argv[1];
  napi_value _this;
  void* data;
  NODE_API_CALL(env,
    napi_get_cb_info(env, info, &argc, argv, &_this, &data));
  NODE_API_ASSERT(env, argc >= 1, "Not enough arguments, expected 1.");

  napi_valuetype t;
  NODE_API_CALL(env, napi_typeof(env, argv[0], &t));
  NODE_API_ASSERT(env, t == napi_function,
      "Wrong first argument, function expected.");

  napi_ref cbref;
  NODE_API_CALL(env,
    napi_create_reference(env, argv[0], 1, &cbref));

  SetImmediate(env, [=]() -> char* {
    napi_value undefined;
    napi_value callback;
    napi_handle_scope scope;
    NODE_API_CALL(env, napi_open_handle_scope(env, &scope));
    NODE_API_CALL(env, napi_get_undefined(env, &undefined));
    NODE_API_CALL(env, napi_get_reference_value(env, cbref, &callback));
    NODE_API_CALL(env, napi_delete_reference(env, cbref));
    NODE_API_CALL(env,
        napi_call_function(env, undefined, callback, 0, nullptr, nullptr));
    NODE_API_CALL(env, napi_close_handle_scope(env, scope));
    return &dummy;
  });

  return nullptr;
}

napi_value Init(napi_env env, napi_value exports) {
  napi_property_descriptor properties[] = {
    DECLARE_NODE_API_PROPERTY("SetImmediate", SetImmediateBinding)
  };

  NODE_API_CALL(env, napi_define_properties(
      env, exports, sizeof(properties) / sizeof(*properties), properties));

  return exports;
}

NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)