Open sdroege opened 3 years ago
Can reproduce, I'll investigate more.
@wotzlaff if you have any hints here I'd be happy to have your input.
One thing I've noted, uv's doc says:
Note
1. Callers should be prepared to deal with spurious wakeups on uv_cond_wait() and uv_cond_timedwait().
It's surely not the cause of this but our uv_cond_wait()
isn't in a loop, we probably need to wrap it.
The case can be simplified to the following code. Any synchronous out-of-thread callback fails. Async callbacks are fine.
const task = new Gio.Task(null)
task.runInThreadSync(() => {
console.log('callback called')
})
Edit: I think I see what's happening. libuv/nodejs main loop is stopped because it has called g_task_run_in_thread_sync
(which has itself called g_cond_wait
), and the thread spawn by g_task_run_in_thread_sync
is itself trying to get an answer from libuv's main thread, which is waiting :/
I have trouble seeing how we're gonna get out of this one. One thing is sure, if we want to run JS from other threads, the main loop cannot be blocked by *_sync
functions. They need to be moved off-thread somehow.
Asynchronous callbacks (I assume you mean things like GIO async operations with GAsyncResult
etc) are called from the thread that runs the main loop, not from some random other thread.
E.g. the following change to
examples/gst.js
:When running it prints the log output from the sync handler but not any longer from the normal
addWatch()
callback that would happen from the main thread, and it also doesn't show the video window as before.Backtrace is as follows. It waits for something in
GNodeJS::AsyncCallWrapper::Wait()
in one of the threads that would call the new callback.