File: env_cleanup.cc

package info (click to toggle)
node-addon-api 8.3.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,248 kB
  • sloc: cpp: 15,431; javascript: 5,631; ansic: 157; makefile: 7
file content (100 lines) | stat: -rw-r--r-- 2,437 bytes parent folder | download
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
90
91
92
93
94
95
96
97
98
99
100
#include <stdio.h>
#include "napi.h"

using namespace Napi;

#if (NAPI_VERSION > 2)
namespace {

static void cleanup(void* arg) {
  printf("static cleanup(%d)\n", *(int*)(arg));
}
static void cleanupInt(int* arg) {
  printf("static cleanup(%d)\n", *(arg));
}

static void cleanupVoid() {
  printf("static cleanup()\n");
}

static int secret1 = 42;
static int secret2 = 43;

class TestClass {
 public:
  Env::CleanupHook<void (*)(void* arg), int> hook;

  void removeHook(Env env) { hook.Remove(env); }
};

Value AddHooks(const CallbackInfo& info) {
  auto env = info.Env();

  bool shouldRemove = info[0].As<Boolean>().Value();

  // hook: void (*)(void *arg), hint: int
  auto hook1 = env.AddCleanupHook(cleanup, &secret1);
  // test using same hook+arg pair
  auto hook1b = env.AddCleanupHook(cleanup, &secret1);

  // hook: void (*)(int *arg), hint: int
  auto hook2 = env.AddCleanupHook(cleanupInt, &secret2);

  // hook: void (*)(int *arg), hint: void (default)
  auto hook3 = env.AddCleanupHook(cleanupVoid);
  // test using the same hook
  auto hook3b = env.AddCleanupHook(cleanupVoid);

  // hook: lambda []void (int *arg)->void, hint: int
  auto hook4 = env.AddCleanupHook(
      [&](int* arg) { printf("lambda cleanup(%d)\n", *arg); }, &secret1);

  // hook: lambda []void (void *)->void, hint: void
  auto hook5 =
      env.AddCleanupHook([&](void*) { printf("lambda cleanup(void)\n"); },
                         static_cast<void*>(nullptr));

  // hook: lambda []void ()->void, hint: void (default)
  auto hook6 = env.AddCleanupHook([&]() { printf("lambda cleanup()\n"); });

  if (shouldRemove) {
    hook1.Remove(env);
    hook1b.Remove(env);
    hook2.Remove(env);
    hook3.Remove(env);
    hook3b.Remove(env);
    hook4.Remove(env);
    hook5.Remove(env);
    hook6.Remove(env);
  }

  int added = 0;

  added += !hook1.IsEmpty();
  added += !hook1b.IsEmpty();
  added += !hook2.IsEmpty();
  added += !hook3.IsEmpty();
  added += !hook3b.IsEmpty();
  added += !hook4.IsEmpty();
  added += !hook5.IsEmpty();
  added += !hook6.IsEmpty();

  // Test store a hook in a member class variable
  auto myclass = TestClass();
  myclass.hook = env.AddCleanupHook(cleanup, &secret1);
  myclass.removeHook(env);

  return Number::New(env, added);
}

}  // anonymous namespace

Object InitEnvCleanup(Env env) {
  Object exports = Object::New(env);

  exports["addHooks"] = Function::New(env, AddHooks);

  return exports;
}

#endif