Stop IOCP when freeing the event_base.

This commit is contained in:
Christopher Davis 2010-08-28 02:08:27 -07:00
parent 03afa209de
commit d844242f9b
4 changed files with 31 additions and 6 deletions

18
event.c
View File

@ -638,6 +638,20 @@ event_base_start_iocp(struct event_base *base)
#endif #endif
} }
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 void
event_base_free(struct event_base *base) event_base_free(struct event_base *base)
{ {
@ -654,6 +668,10 @@ event_base_free(struct event_base *base)
/* XXX(niels) - check for internal events first */ /* XXX(niels) - check for internal events first */
EVUTIL_ASSERT(base); EVUTIL_ASSERT(base);
#ifdef WIN32
event_base_stop_iocp(base);
#endif
/* threading fds if we have them */ /* threading fds if we have them */
if (base->th_notify_fd[0] != -1) { if (base->th_notify_fd[0] != -1) {
event_del(&base->th_notify); event_del(&base->th_notify);

View File

@ -73,7 +73,8 @@ loop(void *_port)
EnterCriticalSection(&port->lock); EnterCriticalSection(&port->lock);
if (port->shutdown) { if (port->shutdown) {
if (--port->n_live_threads == 0) if (--port->n_live_threads == 0)
ReleaseSemaphore(port->shutdownSemaphore, 1, NULL); ReleaseSemaphore(port->shutdownSemaphore, 1,
NULL);
LeaveCriticalSection(&port->lock); LeaveCriticalSection(&port->lock);
return; return;
} }
@ -233,13 +234,18 @@ event_iocp_notify_all(struct event_iocp_port *port)
int int
event_iocp_shutdown(struct event_iocp_port *port, long waitMsec) event_iocp_shutdown(struct event_iocp_port *port, long waitMsec)
{ {
DWORD ms = INFINITE;
int n; int n;
EnterCriticalSection(&port->lock); EnterCriticalSection(&port->lock);
port->shutdown = 1; port->shutdown = 1;
LeaveCriticalSection(&port->lock); LeaveCriticalSection(&port->lock);
event_iocp_notify_all(port); event_iocp_notify_all(port);
WaitForSingleObject(port->shutdownSemaphore, waitMsec); if (waitMsec >= 0)
ms = waitMsec;
WaitForSingleObject(port->shutdownSemaphore, ms);
EnterCriticalSection(&port->lock); EnterCriticalSection(&port->lock);
n = port->n_live_threads; n = port->n_live_threads;
LeaveCriticalSection(&port->lock); LeaveCriticalSection(&port->lock);

View File

@ -164,9 +164,10 @@ int event_iocp_port_associate(struct event_iocp_port *port, evutil_socket_t fd,
ev_uintptr_t key); ev_uintptr_t key);
/** Tell all threads serving an iocp to stop. Wait for up to waitMsec for all /** 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 the threads to finish whatever they're doing. If waitMsec is -1, wait
done, free the port and return 0. Otherwise, return -1. If you get a -1 as long as required. If all the threads are done, free the port and return
return value, it is safe to call this function again. 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); 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. */ /* FIXME document. */
int event_base_start_iocp(struct event_base *base); int event_base_start_iocp(struct event_base *base);
void event_base_stop_iocp(struct event_base *base);
/* FIXME document. */ /* FIXME document. */
struct bufferevent *bufferevent_async_new(struct event_base *base, struct bufferevent *bufferevent_async_new(struct event_base *base,

View File

@ -255,7 +255,6 @@ test_iocp_bufferevent_async(void *ptr)
buf[n]='\0'; buf[n]='\0';
tt_str_op(buf, ==, "Hello world"); tt_str_op(buf, ==, "Hello world");
tt_want(!event_iocp_shutdown(port, 2000));
end: end:
/* FIXME: free stuff. */; /* FIXME: free stuff. */;
} }