diff options
author | Christopher Davis <chrisd@torproject.org> | 2010-08-28 02:08:27 -0700 |
---|---|---|
committer | Christopher Davis <chrisd@torproject.org> | 2010-09-08 01:22:21 -0700 |
commit | d844242f9b138be4896942ded25d74a91bf29901 (patch) | |
tree | 5edb40d6cb73b0638802e961c0265ba3be1532e1 | |
parent | 03afa209de96d67f1a4b935460aeabe63f5ef24f (diff) | |
download | libevent-d844242f9b138be4896942ded25d74a91bf29901.tar.gz |
Stop IOCP when freeing the event_base.
-rw-r--r-- | event.c | 18 | ||||
-rw-r--r-- | event_iocp.c | 10 | ||||
-rw-r--r-- | iocp-internal.h | 8 | ||||
-rw-r--r-- | test/regress_iocp.c | 1 |
4 files changed, 31 insertions, 6 deletions
@@ -639,6 +639,20 @@ event_base_start_iocp(struct event_base *base) } void +event_base_stop_iocp(struct event_base *base) +{ +#ifdef WIN32 + int rv; + + if (!base->iocp) + return; + rv = event_iocp_shutdown(base->iocp, -1); + EVUTIL_ASSERT(rv >= 0); + base->iocp = NULL; +#endif +} + +void event_base_free(struct event_base *base) { int i, n_deleted=0; @@ -654,6 +668,10 @@ event_base_free(struct event_base *base) /* XXX(niels) - check for internal events first */ EVUTIL_ASSERT(base); +#ifdef WIN32 + event_base_stop_iocp(base); +#endif + /* threading fds if we have them */ if (base->th_notify_fd[0] != -1) { event_del(&base->th_notify); diff --git a/event_iocp.c b/event_iocp.c index fe9ea571..82fa9aee 100644 --- a/event_iocp.c +++ b/event_iocp.c @@ -73,7 +73,8 @@ loop(void *_port) EnterCriticalSection(&port->lock); if (port->shutdown) { if (--port->n_live_threads == 0) - ReleaseSemaphore(port->shutdownSemaphore, 1, NULL); + ReleaseSemaphore(port->shutdownSemaphore, 1, + NULL); LeaveCriticalSection(&port->lock); return; } @@ -233,13 +234,18 @@ event_iocp_notify_all(struct event_iocp_port *port) int event_iocp_shutdown(struct event_iocp_port *port, long waitMsec) { + DWORD ms = INFINITE; int n; + EnterCriticalSection(&port->lock); port->shutdown = 1; LeaveCriticalSection(&port->lock); event_iocp_notify_all(port); - WaitForSingleObject(port->shutdownSemaphore, waitMsec); + if (waitMsec >= 0) + ms = waitMsec; + + WaitForSingleObject(port->shutdownSemaphore, ms); EnterCriticalSection(&port->lock); n = port->n_live_threads; LeaveCriticalSection(&port->lock); diff --git a/iocp-internal.h b/iocp-internal.h index c444cc39..2b740bcc 100644 --- a/iocp-internal.h +++ b/iocp-internal.h @@ -164,9 +164,10 @@ int event_iocp_port_associate(struct event_iocp_port *port, evutil_socket_t fd, ev_uintptr_t key); /** Tell all threads serving an iocp to stop. Wait for up to waitMsec for all - the threads to finish whatever they're doing. If all the threads are - done, free the port and return 0. Otherwise, return -1. If you get a -1 - return value, it is safe to call this function again. + the threads to finish whatever they're doing. If waitMsec is -1, wait + as long as required. If all the threads are done, free the port and return + 0. Otherwise, return -1. If you get a -1 return value, it is safe to call + this function again. */ int event_iocp_shutdown(struct event_iocp_port *port, long waitMsec); @@ -181,6 +182,7 @@ struct event_iocp_port *event_base_get_iocp(struct event_base *base); /* FIXME document. */ int event_base_start_iocp(struct event_base *base); +void event_base_stop_iocp(struct event_base *base); /* FIXME document. */ struct bufferevent *bufferevent_async_new(struct event_base *base, diff --git a/test/regress_iocp.c b/test/regress_iocp.c index 64e86320..59aeab0b 100644 --- a/test/regress_iocp.c +++ b/test/regress_iocp.c @@ -255,7 +255,6 @@ test_iocp_bufferevent_async(void *ptr) buf[n]='\0'; tt_str_op(buf, ==, "Hello world"); - tt_want(!event_iocp_shutdown(port, 2000)); end: /* FIXME: free stuff. */; } |