diff --git a/src/fs-poll.c b/src/fs-poll.c index c952dfc9..f0fadd5d 100644 --- a/src/fs-poll.c +++ b/src/fs-poll.c @@ -238,7 +238,6 @@ static int statbuf_eq(const uv_statbuf_t* a, const uv_statbuf_t* b) { void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle) { assert(handle->flags & UV_HANDLE_CLOSING); assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_stop(handle); uv__handle_close(handle); } diff --git a/src/uv-common.h b/src/uv-common.h index 4608ee54..e9caed9a 100644 --- a/src/uv-common.h +++ b/src/uv-common.h @@ -53,12 +53,14 @@ enum { UV__HANDLE_INTERNAL = 0x8000, UV__HANDLE_ACTIVE = 0x4000, - UV__HANDLE_REF = 0x2000 + UV__HANDLE_REF = 0x2000, + UV__HANDLE_CLOSING = 0 /* no-op on unix */ }; #else # define UV__HANDLE_INTERNAL 0x80 # define UV__HANDLE_ACTIVE 0x40 # define UV__HANDLE_REF 0x20 +# define UV__HANDLE_CLOSING 0x01 #endif extern const uv_err_t uv_ok_; @@ -129,28 +131,32 @@ UNUSED static int uv__is_active(const uv_handle_t* h) { UNUSED static void uv__handle_start(uv_handle_t* h) { if (h->flags & UV__HANDLE_ACTIVE) return; - if (h->flags & UV__HANDLE_REF) uv__active_handle_add(h); h->flags |= UV__HANDLE_ACTIVE; + if (h->flags & UV__HANDLE_CLOSING) return; + if (h->flags & UV__HANDLE_REF) uv__active_handle_add(h); } #define uv__handle_start(h) uv__handle_start((uv_handle_t*)(h)) UNUSED static void uv__handle_stop(uv_handle_t* h) { if (!(h->flags & UV__HANDLE_ACTIVE)) return; - if (h->flags & UV__HANDLE_REF) uv__active_handle_rm(h); h->flags &= ~UV__HANDLE_ACTIVE; + if (h->flags & UV__HANDLE_CLOSING) return; + if (h->flags & UV__HANDLE_REF) uv__active_handle_rm(h); } #define uv__handle_stop(h) uv__handle_stop((uv_handle_t*)(h)) UNUSED static void uv__handle_ref(uv_handle_t* h) { if (h->flags & UV__HANDLE_REF) return; - if (h->flags & UV__HANDLE_ACTIVE) uv__active_handle_add(h); + if (h->flags & (UV__HANDLE_ACTIVE | UV__HANDLE_CLOSING)) + uv__active_handle_add(h); h->flags |= UV__HANDLE_REF; } #define uv__handle_ref(h) uv__handle_ref((uv_handle_t*)(h)) UNUSED static void uv__handle_unref(uv_handle_t* h) { if (!(h->flags & UV__HANDLE_REF)) return; - if (h->flags & UV__HANDLE_ACTIVE) uv__active_handle_rm(h); + if (h->flags & (UV__HANDLE_ACTIVE | UV__HANDLE_CLOSING)) + uv__active_handle_rm(h); h->flags &= ~UV__HANDLE_REF; } #define uv__handle_unref(h) uv__handle_unref((uv_handle_t*)(h)) diff --git a/src/win/async.c b/src/win/async.c index 40dee1fe..4247c75a 100644 --- a/src/win/async.c +++ b/src/win/async.c @@ -32,7 +32,6 @@ void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle) { if (handle->flags & UV_HANDLE_CLOSING && !handle->async_sent) { assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_stop(handle); uv__handle_close(handle); } } @@ -61,7 +60,7 @@ void uv_async_close(uv_loop_t* loop, uv_async_t* handle) { uv_want_endgame(loop, (uv_handle_t*) handle); } - uv__handle_start(handle); + uv__handle_closing(handle); } diff --git a/src/win/fs-event.c b/src/win/fs-event.c index 810be4f1..0874a768 100644 --- a/src/win/fs-event.c +++ b/src/win/fs-event.c @@ -470,7 +470,7 @@ void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle) { uv_want_endgame(loop, (uv_handle_t*)handle); } - uv__handle_start(handle); + uv__handle_closing(handle); } @@ -478,7 +478,6 @@ void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle) { if (handle->flags & UV_HANDLE_CLOSING && !handle->req_pending) { assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_stop(handle); if (handle->buffer) { _aligned_free(handle->buffer); diff --git a/src/win/handle-inl.h b/src/win/handle-inl.h index 18db5e69..3b02b7f0 100644 --- a/src/win/handle-inl.h +++ b/src/win/handle-inl.h @@ -59,12 +59,27 @@ } while (0) +#define uv__handle_closing(handle) \ + do { \ + assert(!((handle)->flags & UV__HANDLE_CLOSING)); \ + (handle)->flags |= UV__HANDLE_CLOSING; \ + if ((handle)->flags & UV__HANDLE_ACTIVE) { \ + (handle)->flags &= ~UV__HANDLE_ACTIVE; \ + } else if ((handle)->flags & UV__HANDLE_REF) { \ + uv__active_handle_add((uv_handle_t*) (handle)); \ + } \ + } while (0) + + #define uv__handle_close(handle) \ do { \ ngx_queue_remove(&(handle)->handle_queue); \ (handle)->flags |= UV_HANDLE_CLOSED; \ + if (handle->flags & UV__HANDLE_REF) { \ + uv__active_handle_rm((uv_handle_t*) (handle)); \ + } \ if ((handle)->close_cb) { \ - (handle)->close_cb((uv_handle_t*)(handle)); \ + (handle)->close_cb((uv_handle_t*) (handle)); \ } \ } while (0) diff --git a/src/win/handle.c b/src/win/handle.c index 74bd56c0..d300bd2b 100644 --- a/src/win/handle.c +++ b/src/win/handle.c @@ -71,7 +71,6 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) { return; } - handle->flags |= UV_HANDLE_CLOSING; handle->close_cb = cb; /* Handle-specific close actions */ @@ -98,25 +97,25 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) { case UV_TIMER: uv_timer_stop((uv_timer_t*)handle); - uv__handle_start(handle); + uv__handle_closing(handle); uv_want_endgame(loop, handle); return; case UV_PREPARE: uv_prepare_stop((uv_prepare_t*)handle); - uv__handle_start(handle); + uv__handle_closing(handle); uv_want_endgame(loop, handle); return; case UV_CHECK: uv_check_stop((uv_check_t*)handle); - uv__handle_start(handle); + uv__handle_closing(handle); uv_want_endgame(loop, handle); return; case UV_IDLE: uv_idle_stop((uv_idle_t*)handle); - uv__handle_start(handle); + uv__handle_closing(handle); uv_want_endgame(loop, handle); return; @@ -138,7 +137,7 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) { case UV_FS_POLL: uv__fs_poll_close((uv_fs_poll_t*) handle); - uv__handle_start(handle); + uv__handle_closing(handle); uv_want_endgame(loop, handle); return; diff --git a/src/win/loop-watcher.c b/src/win/loop-watcher.c index 1a028620..ee80feb9 100644 --- a/src/win/loop-watcher.c +++ b/src/win/loop-watcher.c @@ -30,7 +30,6 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) { if (handle->flags & UV_HANDLE_CLOSING) { assert(!(handle->flags & UV_HANDLE_CLOSED)); handle->flags |= UV_HANDLE_CLOSED; - uv__handle_stop(handle); uv__handle_close(handle); } } diff --git a/src/win/pipe.c b/src/win/pipe.c index a4bb7641..62cdef54 100644 --- a/src/win/pipe.c +++ b/src/win/pipe.c @@ -357,7 +357,6 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) { if (handle->flags & UV_HANDLE_CLOSING && handle->reqs_pending == 0) { assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_stop(handle); if (handle->flags & UV_HANDLE_CONNECTION) { if (handle->pending_ipc_info.socket_info) { @@ -660,7 +659,7 @@ void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle) { uv_want_endgame(loop, (uv_handle_t*) handle); } - uv__handle_start(handle); + uv__handle_closing(handle); } diff --git a/src/win/poll.c b/src/win/poll.c index 30819894..c6feaae5 100644 --- a/src/win/poll.c +++ b/src/win/poll.c @@ -230,7 +230,7 @@ static int uv__fast_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) { static void uv__fast_poll_close(uv_loop_t* loop, uv_poll_t* handle) { handle->events = 0; - uv__handle_start(handle); + uv__handle_closing(handle); if (handle->submitted_events_1 == 0 && handle->submitted_events_2 == 0) { @@ -477,7 +477,7 @@ static int uv__slow_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) { static void uv__slow_poll_close(uv_loop_t* loop, uv_poll_t* handle) { handle->events = 0; - uv__handle_start(handle); + uv__handle_closing(handle); if (handle->submitted_events_1 == 0 && handle->submitted_events_2 == 0) { @@ -611,6 +611,5 @@ void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle) { assert(handle->submitted_events_1 == 0); assert(handle->submitted_events_2 == 0); - uv__handle_stop(handle); uv__handle_close(handle); } diff --git a/src/win/process.c b/src/win/process.c index dac97690..88467587 100644 --- a/src/win/process.c +++ b/src/win/process.c @@ -700,7 +700,7 @@ void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) { void uv_process_close(uv_loop_t* loop, uv_process_t* handle) { - uv__handle_start(handle); + uv__handle_closing(handle); if (handle->wait_handle != INVALID_HANDLE_VALUE) { /* This blocks until either the wait was cancelled, or the callback has */ @@ -725,8 +725,6 @@ void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle) { assert(handle->flags & UV_HANDLE_CLOSING); assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_stop(handle); - /* Clean-up the process handle. */ CloseHandle(handle->process_handle); diff --git a/src/win/signal.c b/src/win/signal.c index f96e07ba..73aeff19 100644 --- a/src/win/signal.c +++ b/src/win/signal.c @@ -333,9 +333,9 @@ void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle, void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle) { uv_signal_stop(handle); + uv__handle_closing(handle); if (handle->pending_signum == 0) { - uv__handle_start(handle); uv_want_endgame(loop, (uv_handle_t*) handle); } } @@ -350,6 +350,5 @@ void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle) { handle->flags |= UV_HANDLE_CLOSED; - uv__handle_stop(handle); uv__handle_close(handle); } diff --git a/src/win/tcp.c b/src/win/tcp.c index fdca4529..4911cc62 100644 --- a/src/win/tcp.c +++ b/src/win/tcp.c @@ -187,7 +187,6 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) { if (handle->flags & UV_HANDLE_CLOSING && handle->reqs_pending == 0) { assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_stop(handle); if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) { closesocket(handle->socket); @@ -1386,7 +1385,7 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) { tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED; } - uv__handle_start(tcp); + uv__handle_closing(tcp); if (tcp->reqs_pending == 0) { uv_want_endgame(tcp->loop, (uv_handle_t*)tcp); diff --git a/src/win/timer.c b/src/win/timer.c index e9eab9ab..239f7884 100644 --- a/src/win/timer.c +++ b/src/win/timer.c @@ -78,7 +78,6 @@ int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) { void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle) { if (handle->flags & UV_HANDLE_CLOSING) { assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_stop(handle); uv__handle_close(handle); } } diff --git a/src/win/tty.c b/src/win/tty.c index f0a00e1f..19edf7d2 100644 --- a/src/win/tty.c +++ b/src/win/tty.c @@ -1816,7 +1816,7 @@ void uv_tty_close(uv_tty_t* handle) { handle->flags |= UV_HANDLE_SHUTTING; } - uv__handle_start(handle); + uv__handle_closing(handle); if (handle->reqs_pending == 0) { uv_want_endgame(handle->loop, (uv_handle_t*) handle); @@ -1859,7 +1859,6 @@ void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) { handle->read_raw_wait == NULL); assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_stop(handle); uv__handle_close(handle); } } diff --git a/src/win/udp.c b/src/win/udp.c index 9ad2f69f..5d3a5475 100644 --- a/src/win/udp.c +++ b/src/win/udp.c @@ -143,7 +143,7 @@ void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) { uv_udp_recv_stop(handle); closesocket(handle->socket); - uv__handle_start(handle); + uv__handle_closing(handle); if (handle->reqs_pending == 0) { uv_want_endgame(loop, (uv_handle_t*) handle); @@ -155,7 +155,6 @@ void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) { if (handle->flags & UV_HANDLE_CLOSING && handle->reqs_pending == 0) { assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_stop(handle); uv__handle_close(handle); } }