On Tue, Jul 10, 2012 at 8:31 PM, Nathan Sobo <nat...@github.com> wrote: > I'm interested in embedding Node.js into the Chromium renderer process for > an internal tool I'm building for GitHub. This is a situation where running > Node as a subprocess won't suffice, so I'm curious what the barriers are do > doing this in process. > > Using Chromium's V8 Context > Node is current with the version of V8 used by Chromium, and does not seem > to have applied any patches. I'm imagining I can write an alternative to > Node::start that uses Chromium's existing V8 context instead of building a > new one. Is there anything I'm missing on that front?
We float patches on top of V8 from time to time. Most eventually land upstream but it means the V8 that ships with Chromium is not necessarily the V8 that ships with Node. > Embedding Node's Event Loop Without Blocking The Renderer Thread > The next challenge seems more daunting. The Chromium renderer thread has its > own run loop that can't really be modified and obviously can't be blocked by > just firing up a blocking libuv loop. Following the advice of the libev > documentation, I performed a small experiment with libev. I was able to run > the libev event loop inside the Chromium renderer process on an auxiliary > thread, but still retain the ability to add watches from the renderer thread > and–equally important–have my callback code execute on the renderer thread. > This ability to interact from the application thread (not the thread the > loop is blocking on) is essential in my case, because the V8 context I'd be > injecting Node into lives in the renderer thread. > > This mode of operation is officially supported / promoted by libev (and > libeio, via a different API). The technique requires the following > functions. Some have clear analogs in libuv; others I'm less sure about. > > ev_set_loop_release_cb > This function allows you to set two callbacks that acquire and release a > mutex while the loop thread is accessing the loop data. Release is called > just before the loop thread goes to sleep, and acquire is called when it > wakes up. > > ev_async_* > The async family of functions are present in libuv. They allow the main > thread to wake up the loop thread whenever the main thread makes a change to > the loop. Since the loop thread is sleeping, it has to be woken to recognize > these changes. > > ev_set_invoke_pending_cb > This function allows you to replace the code used by the loop to invoke > pending callbacks when processing events. You use this callback to tell the > main thread to invoke the loop's pending callbacks instead of doing it on > the loop thread. You then wait on a condition variable for the main thread > to finish invoking them. > > ev_invoke_pending > This is libev's default mechanism for invoking pending callbacks. The > important thing is that it's exposed so you can call it from the main thread > when it is signalled by the invoke pending callback. > > > How hard would it be to add similar functions in the libuv API? Are there > any additional complications (besides Windows) that would make this scenario > more difficult than it is in the libev example? I think allowing Node to be > embedded in applications that have their own event loops would be a > generally valuable feature. I know the standard line is just to embed it as > a child process, but in-process embedding obviously allows for much richer > bindings to the host application's API. In our case, we want to embed it > directly into a browser, so an external process isn't an option. I'd like to > gauge how feasible such a feature is, as well as the Node developers overall > attitude toward this use-case. > > Thanks very much for your time! First off, don't use libev - we're dropping it. Embedding libuv in another event loop is an oft-requested feature and it's something we're adding in the near future (possibly as a UNIX-only feature for now). The API is TBD but it will probably look something like this: int uv_loop_poll_fd(uv_loop_t*); int uv_loop_poll_timeout(uv_loop_t*); In other words, you get a file descriptor that you embed in your own event loop and a timeout to observe. When the file descriptor becomes active or the timeout expires, you call uv_run_once(). -- Job Board: http://jobs.nodejs.org/ Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines You received this message because you are subscribed to the Google Groups "nodejs" group. To post to this group, send email to nodejs@googlegroups.com To unsubscribe from this group, send email to nodejs+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/nodejs?hl=en?hl=en