Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Schedule AsyncQueueWorker to be called on the main thread #65

Open
wants to merge 11 commits into
base: feature/upgrade_to_NAN_2.8.0
Choose a base branch
from

Conversation

trxcllnt
Copy link
Collaborator

Hey @mikeseven if you don't mind looking this over, I think this is the fix for the failing uv_queue_done assertion I've been seeing. From what I gather, clSetEventCallback calls notifyCB off the main thread. If that's the case, we can't immediately call AsyncQueueWorker, because uv_queue_work isn't thread safe.

I followed the example of the CallbackBridge class in node-sass. C++ isn't my first language, so please feel free to clean this up.

It seems like there may still be an issue I haven't addressed: what's the behavior if someone calls clReleaseEvent() after setEventCallback, but before the callback has been invoked? Will we leak NoCLEventWorker instances?

@mikeseven
Copy link
Owner

mikeseven commented May 19, 2018 via email

@trxcllnt
Copy link
Collaborator Author

Thanks Mike! Here are links to a few of the discussions I found as I was digging in:

Nan::AsyncQueueWorker() is supposed to be called from the main thread.

If you want to wake up the main thread from another thread, you'll have to jury-rig something using uv_async_send(). Note that the uv_async_t handle should be initialized on the main thread first.

uv_queue_work is not thread-safe. You must call it from the loop thread. See docs.libuv.org/en/v1.x/design.html#the-i-o-loop

uv_queue_work should only be called from the main thread, it will queue a job to run in one of uv's worker threads, and the job's callback will run in the main thread. uv_async_send , however, can be called in any thread and will queue a job to wake and run in the main thread. This is described in much better detail in the libuv documentation.

As for a wrapper for worker creation from a foreign thread, all of the advice that I have read so far recommends to use AsyncProgressWorker for this, since it uses uv_async_send for its async worker functionality.

I looked into using AsyncProgressWorker, as it does handle waking the main event-loop thread via uv_async_send, but I couldn't figure out how to change NoCLEventWorker to extend it instead of AsyncWorker. Hope this helps!

@mikeseven
Copy link
Owner

mikeseven commented May 20, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants