From ed395e0619ab50d86c960e839525a0a5e8259b66 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Wed, 4 Apr 2012 05:03:15 -0700 Subject: [PATCH] unix: replace handle->next_watcher Remove the next_watcher and replace it with a linked list. Said list is named endgame_handles (because the uv-win calls it that) and contains all the handles that are in the UV_CLOSING state. The goal of this commit is two-fold: a) remove a dependency on libev, and b) share more code with uv-win in the future A nice side effect is that it shaves a few bytes off a uv_handle_t. --- include/uv-private/uv-unix.h | 3 +- src/unix/core.c | 50 ++++++++++++++-------------------- test/test-pipe-connect-error.c | 2 +- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/include/uv-private/uv-unix.h b/include/uv-private/uv-unix.h index 77b24067..58a67c14 100644 --- a/include/uv-private/uv-unix.h +++ b/include/uv-private/uv-unix.h @@ -82,6 +82,7 @@ typedef void* uv_lib_t; uv_async_t uv_eio_want_poll_notifier; \ uv_async_t uv_eio_done_poll_notifier; \ uv_idle_t uv_eio_poller; \ + uv_handle_t* endgame_handles; \ UV_LOOP_PRIVATE_PLATFORM_FIELDS #define UV_REQ_BUFSML_SIZE (4) @@ -118,7 +119,7 @@ typedef void* uv_lib_t; #define UV_HANDLE_PRIVATE_FIELDS \ int fd; \ int flags; \ - ev_idle next_watcher; + uv_handle_t* endgame_next; /* that's what uv-win calls it */ \ #define UV_STREAM_PRIVATE_FIELDS \ diff --git a/src/unix/core.c b/src/unix/core.c index 09987e99..5dafa32e 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -59,7 +59,6 @@ static uv_loop_t default_loop_struct; static uv_loop_t* default_loop_ptr; -void uv__next(EV_P_ ev_idle* watcher, int revents); static void uv__finish_close(uv_handle_t* handle); @@ -134,11 +133,9 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) { } handle->flags |= UV_CLOSING; - - /* This is used to call the on_close callback in the next loop. */ - ev_idle_start(handle->loop->ev, &handle->next_watcher); - ev_feed_event(handle->loop->ev, &handle->next_watcher, EV_IDLE); - assert(ev_is_pending(&handle->next_watcher)); + handle->endgame_next = handle->loop->endgame_handles; + handle->loop->endgame_handles = handle; + uv_unref(handle->loop); } @@ -151,6 +148,7 @@ static int uv__loop_init(uv_loop_t* loop, struct ev_loop *(ev_loop_new)(unsigned int flags)) { memset(loop, 0, sizeof(*loop)); RB_INIT(&loop->uv_ares_handles_); + loop->endgame_handles = NULL; #if HAVE_KQUEUE loop->ev = ev_loop_new(EVBACKEND_KQUEUE); #else @@ -209,14 +207,25 @@ uv_loop_t* uv_default_loop(void) { } +void uv__run(uv_loop_t* loop) { + ev_run(loop->ev, EVRUN_ONCE); + + while (loop->endgame_handles) + uv__finish_close(loop->endgame_handles); +} + + int uv_run(uv_loop_t* loop) { - ev_run(loop->ev, 0); + do + uv__run(loop); + while (uv_loop_refcount(loop) > 0); + return 0; } int uv_run_once(uv_loop_t* loop) { - ev_run(loop->ev, EVRUN_ONCE); + uv__run(loop); return 0; } @@ -228,11 +237,8 @@ void uv__handle_init(uv_loop_t* loop, uv_handle_t* handle, handle->loop = loop; handle->type = type; handle->flags = 0; - - ev_init(&handle->next_watcher, uv__next); - - /* Ref the loop until this handle is closed. See uv__finish_close. */ - ev_ref(loop->ev); + handle->endgame_next = NULL; + uv_ref(loop); /* unref'd in uv_close() */ } @@ -289,26 +295,12 @@ void uv__finish_close(uv_handle_t* handle) { break; } - ev_idle_stop(loop->ev, &handle->next_watcher); + + loop->endgame_handles = handle->endgame_next; if (handle->close_cb) { handle->close_cb(handle); } - - ev_unref(loop->ev); -} - - -void uv__next(EV_P_ ev_idle* w, int revents) { - uv_handle_t* handle = container_of(w, uv_handle_t, next_watcher); - - assert(revents == EV_IDLE); - - /* For now this function is only to handle the closing event, but we might - * put more stuff here later. - */ - assert(handle->flags & UV_CLOSING); - uv__finish_close(handle); } diff --git a/test/test-pipe-connect-error.c b/test/test-pipe-connect-error.c index 4a6c5110..cc06d429 100644 --- a/test/test-pipe-connect-error.c +++ b/test/test-pipe-connect-error.c @@ -93,4 +93,4 @@ TEST_IMPL(pipe_connect_to_file) { ASSERT(connect_cb_called == 1); return 0; -} \ No newline at end of file +}