How do I pump window messages in a nodejs addon?
c++, libuv, node.js, v8, winapi
Solution
My mistake was trying to create the window on the V8 thread. Instead, `uv_thread_create` should be used to call a function that creates the window on a new thread and then proceeds to do its own message pump loop.
The wndproc function then needs to save received messages into a queue in a thread-safe manner and then use `uv_async_send` to notify the V8 thread that messages have arrived.
A function on the V8 thread (which was passed to `uv_async_init`) is then invoked after messages are enqueued. The function (thread-safely) pops each pending message off the queue and invokes the JS callback.
Problem
In a Windows nodejs addon, I've created a window for the purpose of receiving messages. ``` Handle<Value> MakeMessageWindow(const Arguments &args) { // exposed to JS ... CreateWindow(L"ClassName", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, 0); ... } ``` I have a wndproc function. ``` Local<Function> wndProc; LRESULT APIENTRY WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { // pack up the arguments into Local<Value> argv wndProc->Call(Context::GetCurrent()->Global(), 3, argv); } ``` Now I need to pump messages. Normally, you'd do something like ``` MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } ``` ...but that won't work since it would just block the v8 event loop. How do I pump Windows messages in a manner that won't block v8 and allows me to invoke a JS function when my window receives messages? I presume libuv will play a role, but I'm unsure exactly how to safely invoke a JS function from C running on a separate thread, especially since `uv_async_send` is not guaranteed to invoke a callback every time you call it, and I need to ensure that my JS callback is called every time a window message is received.