diff --git a/test/threadsafe_function/threadsafe_function_unref.cc b/test/threadsafe_function/threadsafe_function_unref.cc index 6c278e7ad..5fcc5dd60 100644 --- a/test/threadsafe_function/threadsafe_function_unref.cc +++ b/test/threadsafe_function/threadsafe_function_unref.cc @@ -31,11 +31,24 @@ static Value TestUnref(const CallbackInfo& info) { return info.Env().Undefined(); } +static Value TestRef(const CallbackInfo& info) { + Function cb = info[1].As(); + + auto tsfn = ThreadSafeFunction::New(info.Env(), cb, "testRes", 1, 1); + + tsfn.BlockingCall(); + tsfn.Unref(info.Env()); + tsfn.Ref(info.Env()); + + return info.Env().Undefined(); +} + } // namespace Object InitThreadSafeFunctionUnref(Env env) { Object exports = Object::New(env); exports["testUnref"] = Function::New(env, TestUnref); + exports["testRef"] = Function::New(env, TestRef); return exports; } diff --git a/test/threadsafe_function/threadsafe_function_unref.js b/test/threadsafe_function/threadsafe_function_unref.js index e041e82d9..1f0e96b87 100644 --- a/test/threadsafe_function/threadsafe_function_unref.js +++ b/test/threadsafe_function/threadsafe_function_unref.js @@ -11,43 +11,88 @@ const isMainProcess = process.argv[1] !== __filename; * - Child process: creates TSFN. Native module Unref's via setTimeout after some time but does NOT call Release. * * Main process should expect child process to exit. + * + * We also added a new test case for `Ref`. The idea being, if a TSFN is active, the event loop that it belongs to should not exit + * Our setup is similar to the test for the `Unref` case, with the difference being now we are expecting the child process to hang */ if (isMainProcess) { module.exports = require('../common').runTestWithBindingPath(test); } else { - test(process.argv[2]); + const isTestingRef = (process.argv[3] === 'true'); + + if (isTestingRef) { + execTSFNRefTest(process.argv[2]); + } else { + execTSFNUnrefTest(process.argv[2]); + } +} + +function testUnRefCallback (resolve, reject, bindingFile) { + const child = require('../napi_child').spawn(process.argv[0], [ + '--expose-gc', __filename, bindingFile, false + ], { stdio: 'inherit' }); + + let timeout = setTimeout(function () { + child.kill(); + timeout = 0; + reject(new Error('Expected child to die')); + }, 5000); + + child.on('error', (err) => { + clearTimeout(timeout); + timeout = 0; + reject(new Error(err)); + }); + + child.on('close', (code) => { + if (timeout) clearTimeout(timeout); + assert.strictEqual(code, 0, 'Expected return value 0'); + resolve(); + }); +} + +function testRefCallback (resolve, reject, bindingFile) { + const child = require('../napi_child').spawn(process.argv[0], [ + '--expose-gc', __filename, bindingFile, true + ], { stdio: 'inherit' }); + + let timeout = setTimeout(function () { + child.kill(); + timeout = 0; + resolve(); + }, 1000); + + child.on('error', (err) => { + clearTimeout(timeout); + timeout = 0; + reject(new Error(err)); + }); + + child.on('close', (code) => { + if (timeout) clearTimeout(timeout); + + reject(new Error('We expected Child to hang')); + }); } function test (bindingFile) { - if (isMainProcess) { - // Main process + // Main process + return new Promise((resolve, reject) => { + testUnRefCallback(resolve, reject, bindingFile); + }).then(() => { return new Promise((resolve, reject) => { - const child = require('../napi_child').spawn(process.argv[0], [ - '--expose-gc', __filename, bindingFile - ], { stdio: 'inherit' }); - - let timeout = setTimeout(function () { - child.kill(); - timeout = 0; - reject(new Error('Expected child to die')); - }, 5000); - - child.on('error', (err) => { - clearTimeout(timeout); - timeout = 0; - reject(new Error(err)); - }); - - child.on('close', (code) => { - if (timeout) clearTimeout(timeout); - assert.strictEqual(code, 0, 'Expected return value 0'); - resolve(); - }); + testRefCallback(resolve, reject, bindingFile); }); - } else { - // Child process - const binding = require(bindingFile); - binding.threadsafe_function_unref.testUnref({}, () => { }); - } + }); +} + +function execTSFNUnrefTest (bindingFile) { + const binding = require(bindingFile); + binding.threadsafe_function_unref.testUnref({}, () => { }); +} + +function execTSFNRefTest (bindingFile) { + const binding = require(bindingFile); + binding.threadsafe_function_unref.testRef({}, () => { }); }