commit f60a569e51224a9b6bb4de0c95fe8503d6951168
parent f754fafcd60ec71f63d4adc3bcad530cf754fe25
Author: Christian Grothoff <christian@grothoff.org>
Date: Fri, 2 Mar 2018 22:56:41 +0100
fix 'race' between MHD_epoll and MHD_daemon_quiesce on epoll listen FD removal, resolve simply by allowing syscall to fail with ENOENT
Diffstat:
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
@@ -4079,10 +4079,12 @@ MHD_epoll (struct MHD_Daemon *daemon,
if ( (daemon->was_quiesced) &&
(daemon->listen_socket_in_epoll) )
{
- if (0 != epoll_ctl (daemon->epoll_fd,
- EPOLL_CTL_DEL,
- ls,
- NULL))
+ if ( (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_DEL,
+ ls,
+ NULL)) &&
+ (ENOENT != errno) ) /* ENOENT can happen due to race with
+ #MHD_quiesce_daemon() */
MHD_PANIC ("Failed to remove listen FD from epoll set\n");
daemon->listen_socket_in_epoll = false;
}
@@ -4586,10 +4588,12 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon)
(-1 != daemon->epoll_fd) &&
(daemon->listen_socket_in_epoll) )
{
- if (0 != epoll_ctl (daemon->epoll_fd,
- EPOLL_CTL_DEL,
- ret,
- NULL))
+ if ( (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_DEL,
+ ret,
+ NULL)) &&
+ (ENOENT != errno) ) /* ENOENT can happen due to race with
+ #MHD_epoll() */
MHD_PANIC ("Failed to remove listen FD from epoll set\n");
daemon->listen_socket_in_epoll = false;
}