summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--event.c18
-rw-r--r--event_iocp.c10
-rw-r--r--iocp-internal.h8
-rw-r--r--test/regress_iocp.c1
4 files changed, 31 insertions, 6 deletions
diff --git a/event.c b/event.c
index dbf1c2f3..5f4656fb 100644
--- a/event.c
+++ b/event.c
@@ -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. */;
}