Merge pull request #137 from oyyd/default-loop

refactor(napi): use get_uv_event_loop instead of uv_default_loop
This commit is contained in:
LongYinan 2020-08-18 14:34:09 +08:00 committed by GitHub
commit cf34fba4e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 2 deletions

View file

@ -533,6 +533,17 @@ impl Env {
.map_err(|e| Error::new(Status::InvalidArg, format!("{}", e))) .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))] #[cfg(all(feature = "libuv", napi4))]
#[inline] #[inline]
pub fn execute< pub fn execute<
@ -553,7 +564,7 @@ impl Env {
check_status(status)?; 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_promise = promise::FuturePromise::create(self.0, raw_deferred, Box::from(resolver))?;
let future_to_execute = promise::resolve_from_future(future_promise.start()?, deferred); let future_to_execute = promise::resolve_from_future(future_promise.start()?, deferred);
uv::execute(event_loop, Box::pin(future_to_execute))?; uv::execute(event_loop, Box::pin(future_to_execute))?;

View file

@ -1,10 +1,18 @@
const test = require('ava') const test = require('ava')
const { join } = require('path') const { join, resolve } = require('path')
const { readFileSync } = require('fs') const { readFileSync } = require('fs')
const bindings = require('../../index.node') const bindings = require('../../index.node')
const napiVersion = require('../napi-version') const napiVersion = require('../napi-version')
let threadMod
try {
threadMod = require('worker_threads')
} catch (err) {
//
}
const filepath = join(__dirname, './example.txt') const filepath = join(__dirname, './example.txt')
test('should execute future on libuv thread pool', async (t) => { test('should execute future on libuv thread pool', async (t) => {
@ -16,3 +24,20 @@ test('should execute future on libuv thread pool', async (t) => {
t.true(Buffer.isBuffer(fileContent)) t.true(Buffer.isBuffer(fileContent))
t.deepEqual(readFileSync(filepath), fileContent) t.deepEqual(readFileSync(filepath), fileContent)
}) })
if (threadMod && napiVersion >= 4) {
test('should execute future on libuv thread pool of "Worker"', async (t) => {
// Test in threads if current Node.js supports "worker_threads".`
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)
})
}

View 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)
})()
}