diff options
Diffstat (limited to 'listener.c')
-rw-r--r-- | listener.c | 28 |
1 files changed, 18 insertions, 10 deletions
@@ -245,6 +245,11 @@ evconnlistener_new_bind(struct event_base *base, evconnlistener_cb cb, goto err; } + if (flags & LEV_OPT_BIND_IPV6ONLY) { + if (evutil_make_listen_socket_ipv6only(fd) < 0) + goto err; + } + if (sa) { if (bind(fd, sa, socklen)<0) goto err; @@ -421,11 +426,14 @@ listener_read_cb(evutil_socket_t fd, short what, void *p) if (lev->refcnt == 1) { int freed = listener_decref_and_unlock(lev); EVUTIL_ASSERT(freed); - - evutil_closesocket(new_fd); return; } --lev->refcnt; + if (!lev->enabled) { + /* the callback could have disabled the listener */ + UNLOCK(lev); + return; + } } err = evutil_socket_geterror(fd); if (EVUTIL_ERR_ACCEPT_RETRIABLE(err)) { @@ -504,7 +512,7 @@ new_accepting_socket(struct evconnlistener_iocp *lev, int family) return NULL; event_overlapped_init_(&res->overlapped, accepted_socket_cb); - res->s = INVALID_SOCKET; + res->s = EVUTIL_INVALID_SOCKET; res->lev = lev; res->buflen = buflen; res->family = family; @@ -522,7 +530,7 @@ static void free_and_unlock_accepting_socket(struct accepting_socket *as) { /* requires lock. */ - if (as->s != INVALID_SOCKET) + if (as->s != EVUTIL_INVALID_SOCKET) closesocket(as->s); LeaveCriticalSection(&as->lock); @@ -542,7 +550,7 @@ start_accepting(struct accepting_socket *as) if (!as->lev->base.enabled) return 0; - if (s == INVALID_SOCKET) { + if (s == EVUTIL_INVALID_SOCKET) { error = WSAGetLastError(); goto report_err; } @@ -589,7 +597,7 @@ stop_accepting(struct accepting_socket *as) { /* requires lock. */ SOCKET s = as->s; - as->s = INVALID_SOCKET; + as->s = EVUTIL_INVALID_SOCKET; closesocket(s); } @@ -631,7 +639,7 @@ accepted_socket_invoke_user_cb(struct event_callback *dcb, void *arg) &socklen_remote); sock = as->s; cb = lev->cb; - as->s = INVALID_SOCKET; + as->s = EVUTIL_INVALID_SOCKET; /* We need to call this so getsockname, getpeername, and * shutdown work correctly on the accepted socket. */ @@ -679,7 +687,7 @@ accepted_socket_cb(struct event_overlapped *o, ev_uintptr_t key, ev_ssize_t n, i free_and_unlock_accepting_socket(as); listener_decref_and_unlock(lev); return; - } else if (as->s == INVALID_SOCKET) { + } else if (as->s == EVUTIL_INVALID_SOCKET) { /* This is okay; we were disabled by iocp_listener_disable. */ LeaveCriticalSection(&as->lock); } else { @@ -717,7 +725,7 @@ iocp_listener_enable(struct evconnlistener *lev) if (!as) continue; EnterCriticalSection(&as->lock); - if (!as->free_on_cb && as->s == INVALID_SOCKET) + if (!as->free_on_cb && as->s == EVUTIL_INVALID_SOCKET) start_accepting(as); LeaveCriticalSection(&as->lock); } @@ -739,7 +747,7 @@ iocp_listener_disable_impl(struct evconnlistener *lev, int shutdown) if (!as) continue; EnterCriticalSection(&as->lock); - if (!as->free_on_cb && as->s != INVALID_SOCKET) { + if (!as->free_on_cb && as->s != EVUTIL_INVALID_SOCKET) { if (shutdown) as->free_on_cb = 1; stop_accepting(as); |