refactor(napi): use get_uv_event_loop instead of uv_default_loop
Using the uv_loop_s from napi_env is safer as it's possible that there are multiple Workers, and therefore multiple uv_loop_s.
This commit is contained in:
parent
0bfacc536a
commit
00454eb577
3 changed files with 55 additions and 2 deletions
|
@ -533,6 +533,17 @@ impl Env {
|
|||
.map_err(|e| Error::new(Status::InvalidArg, format!("{}", e)))
|
||||
}
|
||||
|
||||
#[cfg(napi2)]
|
||||
#[inline]
|
||||
pub fn get_uv_event_loop(&self) -> Result<*mut sys::uv_loop_s> {
|
||||
let mut uv_loop: *mut sys::uv_loop_s = ptr::null_mut();
|
||||
Ok(unsafe {
|
||||
let status = sys::napi_get_uv_event_loop(self.0, &mut uv_loop);
|
||||
check_status(status)?;
|
||||
uv_loop
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "libuv", napi4))]
|
||||
#[inline]
|
||||
pub fn execute<
|
||||
|
@ -553,7 +564,7 @@ impl Env {
|
|||
check_status(status)?;
|
||||
}
|
||||
|
||||
let event_loop = unsafe { sys::uv_default_loop() };
|
||||
let event_loop = self.get_uv_event_loop()?;
|
||||
let future_promise = promise::FuturePromise::create(self.0, raw_deferred, Box::from(resolver))?;
|
||||
let future_to_execute = promise::resolve_from_future(future_promise.start()?, deferred);
|
||||
uv::execute(event_loop, Box::pin(future_to_execute))?;
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
const test = require('ava')
|
||||
const { join } = require('path')
|
||||
const { join, resolve } = require('path')
|
||||
const { readFileSync } = require('fs')
|
||||
|
||||
const bindings = require('../../index.node')
|
||||
const napiVersion = require('../napi-version')
|
||||
|
||||
let threadMod
|
||||
|
||||
try {
|
||||
threadMod = require('worker_threads')
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
|
||||
const filepath = join(__dirname, './example.txt')
|
||||
|
||||
test('should execute future on libuv thread pool', async (t) => {
|
||||
|
@ -16,3 +24,21 @@ test('should execute future on libuv thread pool', async (t) => {
|
|||
t.true(Buffer.isBuffer(fileContent))
|
||||
t.deepEqual(readFileSync(filepath), fileContent)
|
||||
})
|
||||
|
||||
test('should execute future on libuv thread pool of "Worker"', async (t) => {
|
||||
// Test in threads if current Node.js supports "worker_threads".`
|
||||
if (!threadMod || napiVersion < 4) {
|
||||
return
|
||||
}
|
||||
|
||||
const { Worker } = threadMod
|
||||
const script = resolve(__dirname, './uv_worker.js')
|
||||
const worker = new Worker(script)
|
||||
const success = await new Promise((resolve) => {
|
||||
worker.on('message', (success) => {
|
||||
resolve(success)
|
||||
})
|
||||
})
|
||||
|
||||
t.is(success, true)
|
||||
})
|
||||
|
|
16
test_module/__test__/napi4/uv_worker.js
Normal file
16
test_module/__test__/napi4/uv_worker.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
const { isMainThread, parentPort } = require('worker_threads')
|
||||
const { join } = require('path')
|
||||
const { readFileSync } = require('fs')
|
||||
const bindings = require('../../index.node')
|
||||
|
||||
const filepath = join(__dirname, './example.txt')
|
||||
|
||||
if (!isMainThread) {
|
||||
;(async () => {
|
||||
const fileContent = await bindings.uvReadFile(filepath)
|
||||
const success =
|
||||
Buffer.isBuffer(fileContent) &&
|
||||
readFileSync(filepath).toString('utf8') === fileContent.toString('utf8')
|
||||
parentPort.postMessage(success)
|
||||
})()
|
||||
}
|
Loading…
Reference in a new issue