static int dash_dash_index = 0;
static bool use_debug_agent = false;
+
+static ev_async eio_want_poll_notifier;
+static ev_async eio_done_poll_notifier;
+static ev_idle eio_poller;
+
+
+static void DoPoll(EV_P_ ev_idle *watcher, int revents) {
+ assert(watcher == &eio_poller);
+ assert(revents == EV_IDLE);
+
+ if (eio_poll() != -1) ev_idle_stop(EV_DEFAULT_UC_ watcher);
+}
+
+
+// Called from the main thread.
+static void WantPollNotifier(EV_P_ ev_async *watcher, int revents) {
+ assert(watcher == &eio_want_poll_notifier);
+ assert(revents == EV_ASYNC);
+
+ if (eio_poll() == -1) ev_idle_start(EV_DEFAULT_UC_ &eio_poller);
+}
+
+
+static void DonePollNotifier(EV_P_ ev_async *watcher, int revents) {
+ assert(watcher == &eio_done_poll_notifier);
+ assert(revents == EV_ASYNC);
+
+ ev_idle_stop(EV_DEFAULT_UC_ &eio_poller);
+}
+
+
+// EIOWantPoll() is called from the EIO thread pool each time an EIO
+// request (that is, one of the node.fs.* functions) has completed.
+static void EIOWantPoll(void) {
+ // Signal the main thread that eio_poll need to be processed.
+ ev_async_send(EV_DEFAULT_UC_ &eio_want_poll_notifier);
+}
+
+
+static void EIODonePoll(void) {
+ // Signal the main thread that we should stop calling eio_poll().
+ // from the idle watcher.
+ ev_async_send(EV_DEFAULT_UC_ &eio_done_poll_notifier);
+}
+
+
enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
HandleScope scope;
static Handle<Value> Loop(const Arguments& args) {
HandleScope scope;
+
+ if (eio_poll() == -1) ev_idle_start(EV_DEFAULT_UC_ &eio_poller);
+
ev_loop(EV_DEFAULT_UC_ 0);
return Undefined();
}
uncaught_exception_counter--;
}
-static ev_async eio_watcher;
-
-// Called from the main thread.
-static void EIOCallback(EV_P_ ev_async *watcher, int revents) {
- assert(watcher == &eio_watcher);
- assert(revents == EV_ASYNC);
- // Give control to EIO to process responses. In nearly every case
- // EIOPromise::After() (file.cc) is called once EIO receives the response.
- if (-1 == eio_poll() && !ev_async_pending(&eio_watcher)) {
- ev_async_send(EV_DEFAULT_UC_ &eio_watcher);
- }
-}
-
-// EIOWantPoll() is called from the EIO thread pool each time an EIO
-// request (that is, one of the node.fs.* functions) has completed.
-static void EIOWantPoll(void) {
- // Signal the main thread that EIO callbacks need to be processed.
- ev_async_send(EV_DEFAULT_UC_ &eio_watcher);
- // EIOCallback() will be called from the main thread in the next event
- // loop.
-}
static ev_async debug_watcher;
// Initialize the default ev loop.
ev_default_loop(EVFLAG_AUTO);
- // Start the EIO thread pool:
- // 1. Initialize the ev_async watcher which allows for notification from
- // the thread pool (in node::EIOWantPoll) to poll for updates (in
- // node::EIOCallback).
- ev_async_init(&node::eio_watcher, node::EIOCallback);
- // 2. Actaully start the thread pool.
- eio_init(node::EIOWantPoll, NULL);
- // Don't handle more than 10 reqs on each eio_poll(). This is to avoid
- // race conditions. See test/mjsunit/test-eio-race.js
- eio_set_max_poll_reqs(10);
- // 3. Start watcher.
- ev_async_start(EV_DEFAULT_UC_ &node::eio_watcher);
- // 4. Remove a reference to the async watcher. This means we'll drop out
- // of the ev_loop even though eio_watcher is active.
- ev_unref(EV_DEFAULT_UC);
+ // Setup the EIO thread pool
+ { // It requires 3, yes 3, watchers.
+ ev_idle_init(&node::eio_poller, node::DoPoll);
+
+ ev_async_init(&node::eio_want_poll_notifier, node::WantPollNotifier);
+ ev_async_start(EV_DEFAULT_UC_ &node::eio_want_poll_notifier);
+ ev_unref(EV_DEFAULT_UC);
+
+ ev_async_init(&node::eio_done_poll_notifier, node::DonePollNotifier);
+ ev_async_start(EV_DEFAULT_UC_ &node::eio_done_poll_notifier);
+ ev_unref(EV_DEFAULT_UC);
+
+ eio_init(node::EIOWantPoll, node::EIODonePoll);
+ // Don't handle more than 10 reqs on each eio_poll(). This is to avoid
+ // race conditions. See test/mjsunit/test-eio-race.js
+ eio_set_max_poll_reqs(10);
+ }
V8::Initialize();
HandleScope handle_scope;