windows: closing handles should always keep the loop alive

This makes the tcp-ref2 and udp-ref2 tests pass again.
Also adds another reference count test.
This commit is contained in:
Bert Belder 2012-10-25 15:10:16 +02:00
parent 6150feda56
commit 149b16f123
4 changed files with 54 additions and 22 deletions

View File

@ -135,34 +135,44 @@ UNUSED static int uv__is_active(const uv_handle_t* h) {
#define uv__is_active(h) 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;
assert(!(h->flags & UV__HANDLE_CLOSING));
if (h->flags & UV__HANDLE_ACTIVE)
return;
h->flags |= UV__HANDLE_ACTIVE;
if (h->flags & UV__HANDLE_CLOSING) return;
if (h->flags & UV__HANDLE_REF) uv__active_handle_add(h);
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;
assert(!(h->flags & UV__HANDLE_CLOSING));
if (!(h->flags & UV__HANDLE_ACTIVE))
return;
h->flags &= ~UV__HANDLE_ACTIVE;
if (h->flags & UV__HANDLE_CLOSING) return;
if (h->flags & UV__HANDLE_REF) uv__active_handle_rm(h);
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__HANDLE_CLOSING))
uv__active_handle_add(h);
if (h->flags & UV__HANDLE_REF)
return;
h->flags |= UV__HANDLE_REF;
if (h->flags & UV__HANDLE_CLOSING)
return;
if (h->flags & UV__HANDLE_ACTIVE)
uv__active_handle_add(h);
}
#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__HANDLE_CLOSING))
uv__active_handle_rm(h);
if (!(h->flags & UV__HANDLE_REF))
return;
h->flags &= ~UV__HANDLE_REF;
if (h->flags & UV__HANDLE_CLOSING)
return;
if (h->flags & UV__HANDLE_ACTIVE)
uv__active_handle_rm(h);
}
#define uv__handle_unref(h) uv__handle_unref((uv_handle_t*)(h))

View File

@ -62,25 +62,25 @@
#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) { \
\
if (!(((handle)->flags & UV__HANDLE_ACTIVE) && \
((handle)->flags & UV__HANDLE_REF))) \
uv__active_handle_add((uv_handle_t*) (handle)); \
} \
\
(handle)->flags |= UV__HANDLE_CLOSING; \
(handle)->flags &= ~UV__HANDLE_ACTIVE; \
} while (0)
#define uv__handle_close(handle) \
do { \
ngx_queue_remove(&(handle)->handle_queue); \
uv__active_handle_rm((uv_handle_t*) (handle)); \
\
(handle)->flags |= UV_HANDLE_CLOSED; \
if (handle->flags & UV__HANDLE_REF) { \
uv__active_handle_rm((uv_handle_t*) (handle)); \
} \
if ((handle)->close_cb) { \
\
if ((handle)->close_cb) \
(handle)->close_cb((uv_handle_t*) (handle)); \
} \
} while (0)

View File

@ -112,6 +112,7 @@ TEST_DECLARE (fs_event_ref)
TEST_DECLARE (fs_poll_ref)
TEST_DECLARE (tcp_ref)
TEST_DECLARE (tcp_ref2)
TEST_DECLARE (tcp_ref2b)
TEST_DECLARE (tcp_ref3)
TEST_DECLARE (tcp_ref4)
TEST_DECLARE (udp_ref)
@ -338,6 +339,7 @@ TASK_LIST_START
TEST_ENTRY (fs_event_ref)
TEST_ENTRY (tcp_ref)
TEST_ENTRY (tcp_ref2)
TEST_ENTRY (tcp_ref2b)
TEST_ENTRY (tcp_ref3)
TEST_HELPER (tcp_ref3, tcp4_echo_server)
TEST_ENTRY (tcp_ref4)

View File

@ -235,6 +235,26 @@ TEST_IMPL(tcp_ref2) {
}
static void tcp_ref2b_close_cb(uv_handle_t* handle) {
(*(int*) handle->data)++;
}
TEST_IMPL(tcp_ref2b) {
int close_cb_called = 0;
uv_tcp_t h;
h.data = &close_cb_called;
uv_tcp_init(uv_default_loop(), &h);
uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
uv_unref((uv_handle_t*)&h);
uv_close((uv_handle_t*)&h, tcp_ref2b_close_cb);
uv_run(uv_default_loop());
ASSERT(close_cb_called == 1);
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(tcp_ref3) {
struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
uv_tcp_t h;