koffi 2.5.0-beta.1 → 2.5.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/2.5.0-beta.2/koffi_darwin_arm64/koffi.node +0 -0
- package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_darwin_x64/koffi.node +0 -0
- package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_freebsd_arm64/koffi.node +0 -0
- package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_freebsd_ia32/koffi.node +0 -0
- package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_freebsd_x64/koffi.node +0 -0
- package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_linux_arm32hf/koffi.node +0 -0
- package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_linux_arm64/koffi.node +0 -0
- package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_linux_ia32/koffi.node +0 -0
- package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_linux_x64/koffi.node +0 -0
- package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_openbsd_ia32/koffi.node +0 -0
- package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_openbsd_x64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_win32_arm64/koffi.node +0 -0
- package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_win32_ia32/koffi.node +0 -0
- package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_win32_x64/koffi.node +0 -0
- package/doc/index.rst +1 -0
- package/doc/parameters.md +1 -0
- package/doc/unions.md +187 -0
- package/package.json +1 -1
- package/src/koffi/src/call.cc +7 -2
- package/src/koffi/src/ffi.cc +8 -8
- package/src/koffi/src/util.hh +1 -0
- package/vendor/node-addon-api/CHANGELOG.md +31 -0
- package/vendor/node-addon-api/README.md +3 -2
- package/vendor/node-addon-api/doc/async_worker.md +1 -0
- package/vendor/node-addon-api/doc/creating_a_release.md +21 -0
- package/vendor/node-addon-api/doc/value.md +7 -0
- package/vendor/node-addon-api/napi-inl.h +23 -7
- package/vendor/node-addon-api/package.json +9 -1
- package/vendor/node-addon-api/test/async_progress_queue_worker.cc +155 -0
- package/vendor/node-addon-api/test/async_progress_queue_worker.js +134 -0
- package/vendor/node-addon-api/test/async_progress_worker.cc +155 -0
- package/vendor/node-addon-api/test/async_progress_worker.js +134 -0
- package/vendor/node-addon-api/test/common/index.js +45 -0
- package/vendor/node-addon-api/test/objectwrap.js +9 -0
- package/build/2.5.0-beta.1/koffi_darwin_arm64/koffi.node +0 -0
- package/build/2.5.0-beta.1/koffi_win32_arm64/koffi.node +0 -0
- /package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_win32_arm64/koffi.exp +0 -0
- /package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_win32_arm64/koffi.lib +0 -0
- /package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_win32_ia32/koffi.exp +0 -0
- /package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_win32_ia32/koffi.lib +0 -0
- /package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_win32_x64/koffi.exp +0 -0
- /package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_win32_x64/koffi.lib +0 -0
- /package/build/{2.5.0-beta.1 → 2.5.0-beta.2}/koffi_win32_x64/koffi.pdb +0 -0
|
@@ -15,6 +15,158 @@ struct ProgressData {
|
|
|
15
15
|
int32_t progress;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
class TestWorkerWithNoCb : public AsyncProgressQueueWorker<ProgressData> {
|
|
19
|
+
public:
|
|
20
|
+
static void DoWork(const CallbackInfo& info) {
|
|
21
|
+
switch (info.Length()) {
|
|
22
|
+
case 1: {
|
|
23
|
+
Function cb = info[0].As<Function>();
|
|
24
|
+
TestWorkerWithNoCb* worker = new TestWorkerWithNoCb(info.Env(), cb);
|
|
25
|
+
worker->Queue();
|
|
26
|
+
} break;
|
|
27
|
+
|
|
28
|
+
case 2: {
|
|
29
|
+
std::string resName = info[0].As<String>();
|
|
30
|
+
Function cb = info[1].As<Function>();
|
|
31
|
+
TestWorkerWithNoCb* worker =
|
|
32
|
+
new TestWorkerWithNoCb(info.Env(), resName.c_str(), cb);
|
|
33
|
+
worker->Queue();
|
|
34
|
+
} break;
|
|
35
|
+
|
|
36
|
+
case 3: {
|
|
37
|
+
std::string resName = info[0].As<String>();
|
|
38
|
+
Object resObject = info[1].As<Object>();
|
|
39
|
+
Function cb = info[2].As<Function>();
|
|
40
|
+
TestWorkerWithNoCb* worker =
|
|
41
|
+
new TestWorkerWithNoCb(info.Env(), resName.c_str(), resObject, cb);
|
|
42
|
+
worker->Queue();
|
|
43
|
+
} break;
|
|
44
|
+
|
|
45
|
+
default:
|
|
46
|
+
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
protected:
|
|
52
|
+
void Execute(const ExecutionProgress& progress) override {
|
|
53
|
+
ProgressData data{1};
|
|
54
|
+
progress.Send(&data, 1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
void OnProgress(const ProgressData*, size_t /* count */) override {
|
|
58
|
+
_cb.Call({});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private:
|
|
62
|
+
TestWorkerWithNoCb(Napi::Env env, Function cb)
|
|
63
|
+
: AsyncProgressQueueWorker(env) {
|
|
64
|
+
_cb.Reset(cb, 1);
|
|
65
|
+
}
|
|
66
|
+
TestWorkerWithNoCb(Napi::Env env, const char* resourceName, Function cb)
|
|
67
|
+
: AsyncProgressQueueWorker(env, resourceName) {
|
|
68
|
+
_cb.Reset(cb, 1);
|
|
69
|
+
}
|
|
70
|
+
TestWorkerWithNoCb(Napi::Env env,
|
|
71
|
+
const char* resourceName,
|
|
72
|
+
const Object& resourceObject,
|
|
73
|
+
Function cb)
|
|
74
|
+
: AsyncProgressQueueWorker(env, resourceName, resourceObject) {
|
|
75
|
+
_cb.Reset(cb, 1);
|
|
76
|
+
}
|
|
77
|
+
FunctionReference _cb;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
class TestWorkerWithRecv : public AsyncProgressQueueWorker<ProgressData> {
|
|
81
|
+
public:
|
|
82
|
+
static void DoWork(const CallbackInfo& info) {
|
|
83
|
+
switch (info.Length()) {
|
|
84
|
+
case 2: {
|
|
85
|
+
Object recv = info[0].As<Object>();
|
|
86
|
+
Function cb = info[1].As<Function>();
|
|
87
|
+
TestWorkerWithRecv* worker = new TestWorkerWithRecv(recv, cb);
|
|
88
|
+
worker->Queue();
|
|
89
|
+
} break;
|
|
90
|
+
|
|
91
|
+
case 3: {
|
|
92
|
+
Object recv = info[0].As<Object>();
|
|
93
|
+
Function cb = info[1].As<Function>();
|
|
94
|
+
std::string resName = info[2].As<String>();
|
|
95
|
+
TestWorkerWithRecv* worker =
|
|
96
|
+
new TestWorkerWithRecv(recv, cb, resName.c_str());
|
|
97
|
+
worker->Queue();
|
|
98
|
+
} break;
|
|
99
|
+
|
|
100
|
+
case 4: {
|
|
101
|
+
Object recv = info[0].As<Object>();
|
|
102
|
+
Function cb = info[1].As<Function>();
|
|
103
|
+
std::string resName = info[2].As<String>();
|
|
104
|
+
Object resObject = info[3].As<Object>();
|
|
105
|
+
TestWorkerWithRecv* worker =
|
|
106
|
+
new TestWorkerWithRecv(recv, cb, resName.c_str(), resObject);
|
|
107
|
+
worker->Queue();
|
|
108
|
+
} break;
|
|
109
|
+
|
|
110
|
+
default:
|
|
111
|
+
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
protected:
|
|
117
|
+
void Execute(const ExecutionProgress&) override {}
|
|
118
|
+
|
|
119
|
+
void OnProgress(const ProgressData*, size_t /* count */) override {}
|
|
120
|
+
|
|
121
|
+
private:
|
|
122
|
+
TestWorkerWithRecv(const Object& recv, const Function& cb)
|
|
123
|
+
: AsyncProgressQueueWorker(recv, cb) {}
|
|
124
|
+
TestWorkerWithRecv(const Object& recv,
|
|
125
|
+
const Function& cb,
|
|
126
|
+
const char* resourceName)
|
|
127
|
+
: AsyncProgressQueueWorker(recv, cb, resourceName) {}
|
|
128
|
+
TestWorkerWithRecv(const Object& recv,
|
|
129
|
+
const Function& cb,
|
|
130
|
+
const char* resourceName,
|
|
131
|
+
const Object& resourceObject)
|
|
132
|
+
: AsyncProgressQueueWorker(recv, cb, resourceName, resourceObject) {}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
class TestWorkerWithCb : public AsyncProgressQueueWorker<ProgressData> {
|
|
136
|
+
public:
|
|
137
|
+
static void DoWork(const CallbackInfo& info) {
|
|
138
|
+
switch (info.Length()) {
|
|
139
|
+
case 1: {
|
|
140
|
+
Function cb = info[0].As<Function>();
|
|
141
|
+
TestWorkerWithCb* worker = new TestWorkerWithCb(cb);
|
|
142
|
+
worker->Queue();
|
|
143
|
+
} break;
|
|
144
|
+
|
|
145
|
+
case 2: {
|
|
146
|
+
Function cb = info[0].As<Function>();
|
|
147
|
+
std::string asyncResName = info[1].As<String>();
|
|
148
|
+
TestWorkerWithCb* worker =
|
|
149
|
+
new TestWorkerWithCb(cb, asyncResName.c_str());
|
|
150
|
+
worker->Queue();
|
|
151
|
+
} break;
|
|
152
|
+
|
|
153
|
+
default:
|
|
154
|
+
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
protected:
|
|
160
|
+
void Execute(const ExecutionProgress&) override {}
|
|
161
|
+
|
|
162
|
+
void OnProgress(const ProgressData*, size_t /* count */) override {}
|
|
163
|
+
|
|
164
|
+
private:
|
|
165
|
+
TestWorkerWithCb(Function cb) : AsyncProgressQueueWorker(cb) {}
|
|
166
|
+
TestWorkerWithCb(Function cb, const char* res_name)
|
|
167
|
+
: AsyncProgressQueueWorker(cb, res_name) {}
|
|
168
|
+
};
|
|
169
|
+
|
|
18
170
|
class TestWorker : public AsyncProgressQueueWorker<ProgressData> {
|
|
19
171
|
public:
|
|
20
172
|
static Napi::Value CreateWork(const CallbackInfo& info) {
|
|
@@ -87,6 +239,9 @@ Object InitAsyncProgressQueueWorker(Env env) {
|
|
|
87
239
|
Object exports = Object::New(env);
|
|
88
240
|
exports["createWork"] = Function::New(env, TestWorker::CreateWork);
|
|
89
241
|
exports["queueWork"] = Function::New(env, TestWorker::QueueWork);
|
|
242
|
+
exports["runWorkerNoCb"] = Function::New(env, TestWorkerWithNoCb::DoWork);
|
|
243
|
+
exports["runWorkerWithRecv"] = Function::New(env, TestWorkerWithRecv::DoWork);
|
|
244
|
+
exports["runWorkerWithCb"] = Function::New(env, TestWorkerWithCb::DoWork);
|
|
90
245
|
return exports;
|
|
91
246
|
}
|
|
92
247
|
|
|
@@ -4,10 +4,144 @@ const common = require('./common');
|
|
|
4
4
|
const assert = require('assert');
|
|
5
5
|
|
|
6
6
|
module.exports = common.runTest(test);
|
|
7
|
+
const nodeVersion = process.versions.node.split('.')[0];
|
|
8
|
+
|
|
9
|
+
let asyncHooks;
|
|
10
|
+
function checkAsyncHooks () {
|
|
11
|
+
if (nodeVersion >= 8) {
|
|
12
|
+
if (asyncHooks === undefined) {
|
|
13
|
+
asyncHooks = require('async_hooks');
|
|
14
|
+
}
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
7
19
|
|
|
8
20
|
async function test ({ asyncprogressqueueworker }) {
|
|
9
21
|
await success(asyncprogressqueueworker);
|
|
10
22
|
await fail(asyncprogressqueueworker);
|
|
23
|
+
|
|
24
|
+
await asyncProgressWorkerCallbackOverloads(asyncprogressqueueworker.runWorkerWithCb);
|
|
25
|
+
await asyncProgressWorkerRecvOverloads(asyncprogressqueueworker.runWorkerWithRecv);
|
|
26
|
+
await asyncProgressWorkerNoCbOverloads(asyncprogressqueueworker.runWorkerNoCb);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function asyncProgressWorkerCallbackOverloads (bindingFunction) {
|
|
30
|
+
bindingFunction(common.mustCall());
|
|
31
|
+
if (!checkAsyncHooks()) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const hooks = common.installAysncHooks('cbResources');
|
|
36
|
+
|
|
37
|
+
const triggerAsyncId = asyncHooks.executionAsyncId();
|
|
38
|
+
await new Promise((resolve, reject) => {
|
|
39
|
+
bindingFunction(common.mustCall(), 'cbResources');
|
|
40
|
+
hooks.then(actual => {
|
|
41
|
+
assert.deepStrictEqual(actual, [
|
|
42
|
+
{
|
|
43
|
+
eventName: 'init',
|
|
44
|
+
type: 'cbResources',
|
|
45
|
+
triggerAsyncId: triggerAsyncId,
|
|
46
|
+
resource: {}
|
|
47
|
+
},
|
|
48
|
+
{ eventName: 'before' },
|
|
49
|
+
{ eventName: 'after' },
|
|
50
|
+
{ eventName: 'destroy' }
|
|
51
|
+
]);
|
|
52
|
+
resolve();
|
|
53
|
+
}).catch((err) => reject(err));
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function asyncProgressWorkerRecvOverloads (bindingFunction) {
|
|
58
|
+
const recvObject = {
|
|
59
|
+
a: 4
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
function cb () {
|
|
63
|
+
assert.strictEqual(this.a, recvObject.a);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
bindingFunction(recvObject, common.mustCall(cb));
|
|
67
|
+
if (!checkAsyncHooks()) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const asyncResources = [
|
|
71
|
+
{ resName: 'cbRecvResources', resObject: {} },
|
|
72
|
+
{ resName: 'cbRecvResourcesObject', resObject: { foo: 'bar' } }
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
for (const asyncResource of asyncResources) {
|
|
76
|
+
const asyncResName = asyncResource.resName;
|
|
77
|
+
const asyncResObject = asyncResource.resObject;
|
|
78
|
+
|
|
79
|
+
const hooks = common.installAysncHooks(asyncResource.resName);
|
|
80
|
+
const triggerAsyncId = asyncHooks.executionAsyncId();
|
|
81
|
+
await new Promise((resolve, reject) => {
|
|
82
|
+
if (Object.keys(asyncResObject).length === 0) {
|
|
83
|
+
bindingFunction(recvObject, common.mustCall(cb), asyncResName);
|
|
84
|
+
} else {
|
|
85
|
+
bindingFunction(recvObject, common.mustCall(cb), asyncResName, asyncResObject);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
hooks.then(actual => {
|
|
89
|
+
assert.deepStrictEqual(actual, [
|
|
90
|
+
{
|
|
91
|
+
eventName: 'init',
|
|
92
|
+
type: asyncResName,
|
|
93
|
+
triggerAsyncId: triggerAsyncId,
|
|
94
|
+
resource: asyncResObject
|
|
95
|
+
},
|
|
96
|
+
{ eventName: 'before' },
|
|
97
|
+
{ eventName: 'after' },
|
|
98
|
+
{ eventName: 'destroy' }
|
|
99
|
+
]);
|
|
100
|
+
resolve();
|
|
101
|
+
}).catch((err) => reject(err));
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function asyncProgressWorkerNoCbOverloads (bindingFunction) {
|
|
107
|
+
bindingFunction(common.mustCall());
|
|
108
|
+
if (!checkAsyncHooks()) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const asyncResources = [
|
|
112
|
+
{ resName: 'noCbResources', resObject: {} },
|
|
113
|
+
{ resName: 'noCbResourcesObject', resObject: { foo: 'bar' } }
|
|
114
|
+
];
|
|
115
|
+
|
|
116
|
+
for (const asyncResource of asyncResources) {
|
|
117
|
+
const asyncResName = asyncResource.resName;
|
|
118
|
+
const asyncResObject = asyncResource.resObject;
|
|
119
|
+
|
|
120
|
+
const hooks = common.installAysncHooks(asyncResource.resName);
|
|
121
|
+
const triggerAsyncId = asyncHooks.executionAsyncId();
|
|
122
|
+
await new Promise((resolve, reject) => {
|
|
123
|
+
if (Object.keys(asyncResObject).length === 0) {
|
|
124
|
+
bindingFunction(asyncResName, common.mustCall(() => {}));
|
|
125
|
+
} else {
|
|
126
|
+
bindingFunction(asyncResName, asyncResObject, common.mustCall(() => {}));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
hooks.then(actual => {
|
|
130
|
+
assert.deepStrictEqual(actual, [
|
|
131
|
+
{
|
|
132
|
+
eventName: 'init',
|
|
133
|
+
type: asyncResName,
|
|
134
|
+
triggerAsyncId: triggerAsyncId,
|
|
135
|
+
resource: asyncResObject
|
|
136
|
+
},
|
|
137
|
+
{ eventName: 'before' },
|
|
138
|
+
{ eventName: 'after' },
|
|
139
|
+
{ eventName: 'destroy' }
|
|
140
|
+
]);
|
|
141
|
+
resolve();
|
|
142
|
+
}).catch((err) => reject(err));
|
|
143
|
+
});
|
|
144
|
+
}
|
|
11
145
|
}
|
|
12
146
|
|
|
13
147
|
function success (binding) {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
#include <chrono>
|
|
4
4
|
#include <condition_variable>
|
|
5
|
+
#include <iostream>
|
|
5
6
|
#include <mutex>
|
|
6
7
|
#include <thread>
|
|
7
8
|
|
|
@@ -15,6 +16,157 @@ struct ProgressData {
|
|
|
15
16
|
size_t progress;
|
|
16
17
|
};
|
|
17
18
|
|
|
19
|
+
class TestWorkerWithNoCb : public AsyncProgressWorker<ProgressData> {
|
|
20
|
+
public:
|
|
21
|
+
static void DoWork(const CallbackInfo& info) {
|
|
22
|
+
switch (info.Length()) {
|
|
23
|
+
case 1: {
|
|
24
|
+
Function cb = info[0].As<Function>();
|
|
25
|
+
TestWorkerWithNoCb* worker = new TestWorkerWithNoCb(info.Env(), cb);
|
|
26
|
+
worker->Queue();
|
|
27
|
+
} break;
|
|
28
|
+
|
|
29
|
+
case 2: {
|
|
30
|
+
std::string resName = info[0].As<String>();
|
|
31
|
+
Function cb = info[1].As<Function>();
|
|
32
|
+
TestWorkerWithNoCb* worker =
|
|
33
|
+
new TestWorkerWithNoCb(info.Env(), resName.c_str(), cb);
|
|
34
|
+
worker->Queue();
|
|
35
|
+
} break;
|
|
36
|
+
|
|
37
|
+
case 3: {
|
|
38
|
+
std::string resName = info[0].As<String>();
|
|
39
|
+
Object resObject = info[1].As<Object>();
|
|
40
|
+
Function cb = info[2].As<Function>();
|
|
41
|
+
TestWorkerWithNoCb* worker =
|
|
42
|
+
new TestWorkerWithNoCb(info.Env(), resName.c_str(), resObject, cb);
|
|
43
|
+
worker->Queue();
|
|
44
|
+
} break;
|
|
45
|
+
|
|
46
|
+
default:
|
|
47
|
+
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
protected:
|
|
53
|
+
void Execute(const ExecutionProgress& progress) override {
|
|
54
|
+
ProgressData data{1};
|
|
55
|
+
progress.Send(&data, 1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
void OnProgress(const ProgressData*, size_t /* count */) override {
|
|
59
|
+
_cb.Call({});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private:
|
|
63
|
+
TestWorkerWithNoCb(Napi::Env env, Function cb) : AsyncProgressWorker(env) {
|
|
64
|
+
_cb.Reset(cb, 1);
|
|
65
|
+
}
|
|
66
|
+
TestWorkerWithNoCb(Napi::Env env, const char* resourceName, Function cb)
|
|
67
|
+
: AsyncProgressWorker(env, resourceName) {
|
|
68
|
+
_cb.Reset(cb, 1);
|
|
69
|
+
}
|
|
70
|
+
TestWorkerWithNoCb(Napi::Env env,
|
|
71
|
+
const char* resourceName,
|
|
72
|
+
const Object& resourceObject,
|
|
73
|
+
Function cb)
|
|
74
|
+
: AsyncProgressWorker(env, resourceName, resourceObject) {
|
|
75
|
+
_cb.Reset(cb, 1);
|
|
76
|
+
}
|
|
77
|
+
FunctionReference _cb;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
class TestWorkerWithRecv : public AsyncProgressWorker<ProgressData> {
|
|
81
|
+
public:
|
|
82
|
+
static void DoWork(const CallbackInfo& info) {
|
|
83
|
+
switch (info.Length()) {
|
|
84
|
+
case 2: {
|
|
85
|
+
Object recv = info[0].As<Object>();
|
|
86
|
+
Function cb = info[1].As<Function>();
|
|
87
|
+
TestWorkerWithRecv* worker = new TestWorkerWithRecv(recv, cb);
|
|
88
|
+
worker->Queue();
|
|
89
|
+
} break;
|
|
90
|
+
|
|
91
|
+
case 3: {
|
|
92
|
+
Object recv = info[0].As<Object>();
|
|
93
|
+
Function cb = info[1].As<Function>();
|
|
94
|
+
std::string resName = info[2].As<String>();
|
|
95
|
+
TestWorkerWithRecv* worker =
|
|
96
|
+
new TestWorkerWithRecv(recv, cb, resName.c_str());
|
|
97
|
+
worker->Queue();
|
|
98
|
+
} break;
|
|
99
|
+
|
|
100
|
+
case 4: {
|
|
101
|
+
Object recv = info[0].As<Object>();
|
|
102
|
+
Function cb = info[1].As<Function>();
|
|
103
|
+
std::string resName = info[2].As<String>();
|
|
104
|
+
Object resObject = info[3].As<Object>();
|
|
105
|
+
TestWorkerWithRecv* worker =
|
|
106
|
+
new TestWorkerWithRecv(recv, cb, resName.c_str(), resObject);
|
|
107
|
+
worker->Queue();
|
|
108
|
+
} break;
|
|
109
|
+
|
|
110
|
+
default:
|
|
111
|
+
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
protected:
|
|
117
|
+
void Execute(const ExecutionProgress&) override {}
|
|
118
|
+
|
|
119
|
+
void OnProgress(const ProgressData*, size_t /* count */) override {}
|
|
120
|
+
|
|
121
|
+
private:
|
|
122
|
+
TestWorkerWithRecv(const Object& recv, const Function& cb)
|
|
123
|
+
: AsyncProgressWorker(recv, cb) {}
|
|
124
|
+
TestWorkerWithRecv(const Object& recv,
|
|
125
|
+
const Function& cb,
|
|
126
|
+
const char* resourceName)
|
|
127
|
+
: AsyncProgressWorker(recv, cb, resourceName) {}
|
|
128
|
+
TestWorkerWithRecv(const Object& recv,
|
|
129
|
+
const Function& cb,
|
|
130
|
+
const char* resourceName,
|
|
131
|
+
const Object& resourceObject)
|
|
132
|
+
: AsyncProgressWorker(recv, cb, resourceName, resourceObject) {}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
class TestWorkerWithCb : public AsyncProgressWorker<ProgressData> {
|
|
136
|
+
public:
|
|
137
|
+
static void DoWork(const CallbackInfo& info) {
|
|
138
|
+
switch (info.Length()) {
|
|
139
|
+
case 1: {
|
|
140
|
+
Function cb = info[0].As<Function>();
|
|
141
|
+
TestWorkerWithCb* worker = new TestWorkerWithCb(cb);
|
|
142
|
+
worker->Queue();
|
|
143
|
+
} break;
|
|
144
|
+
|
|
145
|
+
case 2: {
|
|
146
|
+
Function cb = info[0].As<Function>();
|
|
147
|
+
std::string asyncResName = info[1].As<String>();
|
|
148
|
+
TestWorkerWithCb* worker =
|
|
149
|
+
new TestWorkerWithCb(cb, asyncResName.c_str());
|
|
150
|
+
worker->Queue();
|
|
151
|
+
} break;
|
|
152
|
+
|
|
153
|
+
default:
|
|
154
|
+
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
protected:
|
|
160
|
+
void Execute(const ExecutionProgress&) override {}
|
|
161
|
+
|
|
162
|
+
void OnProgress(const ProgressData*, size_t /* count */) override {}
|
|
163
|
+
|
|
164
|
+
private:
|
|
165
|
+
TestWorkerWithCb(Function cb) : AsyncProgressWorker(cb) {}
|
|
166
|
+
TestWorkerWithCb(Function cb, const char* res_name)
|
|
167
|
+
: AsyncProgressWorker(cb, res_name) {}
|
|
168
|
+
};
|
|
169
|
+
|
|
18
170
|
class TestWorker : public AsyncProgressWorker<ProgressData> {
|
|
19
171
|
public:
|
|
20
172
|
static void DoWork(const CallbackInfo& info) {
|
|
@@ -196,6 +348,9 @@ Object InitAsyncProgressWorker(Env env) {
|
|
|
196
348
|
exports["doMalignTest"] = Function::New(env, MalignWorker::DoWork);
|
|
197
349
|
exports["doSignalAfterProgressTest"] =
|
|
198
350
|
Function::New(env, SignalAfterProgressTestWorker::DoWork);
|
|
351
|
+
exports["runWorkerNoCb"] = Function::New(env, TestWorkerWithNoCb::DoWork);
|
|
352
|
+
exports["runWorkerWithRecv"] = Function::New(env, TestWorkerWithRecv::DoWork);
|
|
353
|
+
exports["runWorkerWithCb"] = Function::New(env, TestWorkerWithCb::DoWork);
|
|
199
354
|
return exports;
|
|
200
355
|
}
|
|
201
356
|
|
|
@@ -4,12 +4,146 @@ const common = require('./common');
|
|
|
4
4
|
const assert = require('assert');
|
|
5
5
|
|
|
6
6
|
module.exports = common.runTest(test);
|
|
7
|
+
const nodeVersion = process.versions.node.split('.')[0];
|
|
8
|
+
|
|
9
|
+
let asyncHooks;
|
|
10
|
+
function checkAsyncHooks () {
|
|
11
|
+
if (nodeVersion >= 8) {
|
|
12
|
+
if (asyncHooks === undefined) {
|
|
13
|
+
asyncHooks = require('async_hooks');
|
|
14
|
+
}
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
7
19
|
|
|
8
20
|
async function test ({ asyncprogressworker }) {
|
|
9
21
|
await success(asyncprogressworker);
|
|
10
22
|
await fail(asyncprogressworker);
|
|
11
23
|
await signalTest(asyncprogressworker.doMalignTest);
|
|
12
24
|
await signalTest(asyncprogressworker.doSignalAfterProgressTest);
|
|
25
|
+
|
|
26
|
+
await asyncProgressWorkerCallbackOverloads(asyncprogressworker.runWorkerWithCb);
|
|
27
|
+
await asyncProgressWorkerRecvOverloads(asyncprogressworker.runWorkerWithRecv);
|
|
28
|
+
await asyncProgressWorkerNoCbOverloads(asyncprogressworker.runWorkerNoCb);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function asyncProgressWorkerCallbackOverloads (bindingFunction) {
|
|
32
|
+
bindingFunction(common.mustCall());
|
|
33
|
+
if (!checkAsyncHooks()) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const hooks = common.installAysncHooks('cbResources');
|
|
38
|
+
|
|
39
|
+
const triggerAsyncId = asyncHooks.executionAsyncId();
|
|
40
|
+
await new Promise((resolve, reject) => {
|
|
41
|
+
bindingFunction(common.mustCall(), 'cbResources');
|
|
42
|
+
hooks.then(actual => {
|
|
43
|
+
assert.deepStrictEqual(actual, [
|
|
44
|
+
{
|
|
45
|
+
eventName: 'init',
|
|
46
|
+
type: 'cbResources',
|
|
47
|
+
triggerAsyncId: triggerAsyncId,
|
|
48
|
+
resource: {}
|
|
49
|
+
},
|
|
50
|
+
{ eventName: 'before' },
|
|
51
|
+
{ eventName: 'after' },
|
|
52
|
+
{ eventName: 'destroy' }
|
|
53
|
+
]);
|
|
54
|
+
}).catch(common.mustNotCall());
|
|
55
|
+
resolve();
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function asyncProgressWorkerRecvOverloads (bindingFunction) {
|
|
60
|
+
const recvObject = {
|
|
61
|
+
a: 4
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
function cb () {
|
|
65
|
+
assert.strictEqual(this.a, recvObject.a);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
bindingFunction(recvObject, common.mustCall(cb));
|
|
69
|
+
if (!checkAsyncHooks()) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const asyncResources = [
|
|
73
|
+
{ resName: 'cbRecvResources', resObject: {} },
|
|
74
|
+
{ resName: 'cbRecvResourcesObject', resObject: { foo: 'bar' } }
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
for (const asyncResource of asyncResources) {
|
|
78
|
+
const asyncResName = asyncResource.resName;
|
|
79
|
+
const asyncResObject = asyncResource.resObject;
|
|
80
|
+
|
|
81
|
+
const hooks = common.installAysncHooks(asyncResource.resName);
|
|
82
|
+
const triggerAsyncId = asyncHooks.executionAsyncId();
|
|
83
|
+
await new Promise((resolve, reject) => {
|
|
84
|
+
if (Object.keys(asyncResObject).length === 0) {
|
|
85
|
+
bindingFunction(recvObject, common.mustCall(cb), asyncResName);
|
|
86
|
+
} else {
|
|
87
|
+
bindingFunction(recvObject, common.mustCall(cb), asyncResName, asyncResObject);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
hooks.then(actual => {
|
|
91
|
+
assert.deepStrictEqual(actual, [
|
|
92
|
+
{
|
|
93
|
+
eventName: 'init',
|
|
94
|
+
type: asyncResName,
|
|
95
|
+
triggerAsyncId: triggerAsyncId,
|
|
96
|
+
resource: asyncResObject
|
|
97
|
+
},
|
|
98
|
+
{ eventName: 'before' },
|
|
99
|
+
{ eventName: 'after' },
|
|
100
|
+
{ eventName: 'destroy' }
|
|
101
|
+
]);
|
|
102
|
+
}).catch(common.mustNotCall());
|
|
103
|
+
resolve();
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function asyncProgressWorkerNoCbOverloads (bindingFunction) {
|
|
109
|
+
bindingFunction(common.mustCall(() => {}));
|
|
110
|
+
if (!checkAsyncHooks()) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const asyncResources = [
|
|
114
|
+
{ resName: 'noCbResources', resObject: {} },
|
|
115
|
+
{ resName: 'noCbResourcesObject', resObject: { foo: 'bar' } }
|
|
116
|
+
];
|
|
117
|
+
|
|
118
|
+
for (const asyncResource of asyncResources) {
|
|
119
|
+
const asyncResName = asyncResource.resName;
|
|
120
|
+
const asyncResObject = asyncResource.resObject;
|
|
121
|
+
|
|
122
|
+
const hooks = common.installAysncHooks(asyncResource.resName);
|
|
123
|
+
const triggerAsyncId = asyncHooks.executionAsyncId();
|
|
124
|
+
await new Promise((resolve, reject) => {
|
|
125
|
+
if (Object.keys(asyncResObject).length === 0) {
|
|
126
|
+
bindingFunction(asyncResName, common.mustCall(() => {}));
|
|
127
|
+
} else {
|
|
128
|
+
bindingFunction(asyncResName, asyncResObject, common.mustCall(() => {}));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
hooks.then(actual => {
|
|
132
|
+
assert.deepStrictEqual(actual, [
|
|
133
|
+
{
|
|
134
|
+
eventName: 'init',
|
|
135
|
+
type: asyncResName,
|
|
136
|
+
triggerAsyncId: triggerAsyncId,
|
|
137
|
+
resource: asyncResObject
|
|
138
|
+
},
|
|
139
|
+
{ eventName: 'before' },
|
|
140
|
+
{ eventName: 'after' },
|
|
141
|
+
{ eventName: 'destroy' }
|
|
142
|
+
]);
|
|
143
|
+
}).catch(common.mustNotCall());
|
|
144
|
+
resolve();
|
|
145
|
+
});
|
|
146
|
+
}
|
|
13
147
|
}
|
|
14
148
|
|
|
15
149
|
function success (binding) {
|
|
@@ -32,6 +32,51 @@ function runCallChecks (exitCode) {
|
|
|
32
32
|
if (failed.length) process.exit(1);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
exports.installAysncHooks = function (asyncResName) {
|
|
36
|
+
const asyncHooks = require('async_hooks');
|
|
37
|
+
return new Promise((resolve, reject) => {
|
|
38
|
+
let id;
|
|
39
|
+
const events = [];
|
|
40
|
+
/**
|
|
41
|
+
* TODO(legendecas): investigate why resolving & disabling hooks in
|
|
42
|
+
* destroy callback causing crash with case 'callbackscope.js'.
|
|
43
|
+
*/
|
|
44
|
+
let destroyed = false;
|
|
45
|
+
const hook = asyncHooks.createHook({
|
|
46
|
+
init (asyncId, type, triggerAsyncId, resource) {
|
|
47
|
+
if (id === undefined && type === asyncResName) {
|
|
48
|
+
id = asyncId;
|
|
49
|
+
events.push({ eventName: 'init', type, triggerAsyncId, resource });
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
before (asyncId) {
|
|
53
|
+
if (asyncId === id) {
|
|
54
|
+
events.push({ eventName: 'before' });
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
after (asyncId) {
|
|
58
|
+
if (asyncId === id) {
|
|
59
|
+
events.push({ eventName: 'after' });
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
destroy (asyncId) {
|
|
63
|
+
if (asyncId === id) {
|
|
64
|
+
events.push({ eventName: 'destroy' });
|
|
65
|
+
destroyed = true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}).enable();
|
|
69
|
+
|
|
70
|
+
const interval = setInterval(() => {
|
|
71
|
+
if (destroyed) {
|
|
72
|
+
hook.disable();
|
|
73
|
+
clearInterval(interval);
|
|
74
|
+
resolve(events);
|
|
75
|
+
}
|
|
76
|
+
}, 10);
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
|
|
35
80
|
exports.mustCall = function (fn, exact) {
|
|
36
81
|
return _mustCallInner(fn, exact, 'exact');
|
|
37
82
|
};
|