From: Willy Tarreau Date: Sun, 10 May 2009 08:18:54 +0000 (+0200) Subject: [BUG] O(1) pollers should check their FD before closing it X-Git-Tag: v1.3.18~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d79e79b436144654d10124de7d5fd4c896ac0487;p=thirdparty%2Fhaproxy.git [BUG] O(1) pollers should check their FD before closing it epoll, sepoll and kqueue pollers should check that their fd is not closed before attempting to close it, otherwise we can end up with multiple closes of fd #0 upon exit, which is harmless but dirty. --- diff --git a/src/ev_epoll.c b/src/ev_epoll.c index 345b0b2ac0..b976868ea7 100644 --- a/src/ev_epoll.c +++ b/src/ev_epoll.c @@ -312,7 +312,7 @@ REGPRM1 static int _do_init(struct poller *p) free(epoll_events); fail_ee: close(epoll_fd); - epoll_fd = 0; + epoll_fd = -1; fail_fd: p->pref = 0; return 0; @@ -331,8 +331,10 @@ REGPRM1 static void _do_term(struct poller *p) free(fd_evts); free(epoll_events); - close(epoll_fd); - epoll_fd = 0; + if (epoll_fd >= 0) { + close(epoll_fd); + epoll_fd = -1; + } chg_ptr = NULL; chg_list = NULL; @@ -366,7 +368,8 @@ REGPRM1 static int _do_test(struct poller *p) */ REGPRM1 static int _do_fork(struct poller *p) { - close(epoll_fd); + if (epoll_fd >= 0) + close(epoll_fd); epoll_fd = epoll_create(global.maxsock + 1); if (epoll_fd < 0) return 0; @@ -385,6 +388,8 @@ static void _do_register(void) if (nbpollers >= MAX_POLLERS) return; + + epoll_fd = -1; p = &pollers[nbpollers++]; p->name = "epoll"; diff --git a/src/ev_kqueue.c b/src/ev_kqueue.c index 7e626d112d..e167984241 100644 --- a/src/ev_kqueue.c +++ b/src/ev_kqueue.c @@ -188,7 +188,7 @@ REGPRM1 static int _do_init(struct poller *p) free(kev); fail_kev: close(kqueue_fd); - kqueue_fd = 0; + kqueue_fd = -1; fail_fd: p->pref = 0; return 0; @@ -203,8 +203,11 @@ REGPRM1 static void _do_term(struct poller *p) free(fd_evts[DIR_WR]); free(fd_evts[DIR_RD]); free(kev); - close(kqueue_fd); - kqueue_fd = 0; + + if (kqueue_fd >= 0) { + close(kqueue_fd); + kqueue_fd = -1; + } p->private = NULL; p->pref = 0; @@ -232,7 +235,8 @@ REGPRM1 static int _do_test(struct poller *p) */ REGPRM1 static int _do_fork(struct poller *p) { - close(kqueue_fd); + if (kqueue_fd >= 0) + close(kqueue_fd); kqueue_fd = kqueue(); if (kqueue_fd < 0) return 0; @@ -251,6 +255,8 @@ static void _do_register(void) if (nbpollers >= MAX_POLLERS) return; + + kqueue_fd = -1; p = &pollers[nbpollers++]; p->name = "kqueue"; diff --git a/src/ev_sepoll.c b/src/ev_sepoll.c index a093693f39..13e890b622 100644 --- a/src/ev_sepoll.c +++ b/src/ev_sepoll.c @@ -591,7 +591,7 @@ REGPRM1 static int _do_init(struct poller *p) free(epoll_events); fail_ee: close(epoll_fd); - epoll_fd = 0; + epoll_fd = -1; fail_fd: p->pref = 0; return 0; @@ -607,8 +607,10 @@ REGPRM1 static void _do_term(struct poller *p) free(spec_list); free(epoll_events); - close(epoll_fd); - epoll_fd = 0; + if (epoll_fd >= 0) { + close(epoll_fd); + epoll_fd = -1; + } fd_list = NULL; spec_list = NULL; @@ -641,7 +643,8 @@ REGPRM1 static int _do_test(struct poller *p) */ REGPRM1 static int _do_fork(struct poller *p) { - close(epoll_fd); + if (epoll_fd >= 0) + close(epoll_fd); epoll_fd = epoll_create(global.maxsock + 1); if (epoll_fd < 0) return 0; @@ -660,6 +663,8 @@ static void _do_register(void) if (nbpollers >= MAX_POLLERS) return; + + epoll_fd = -1; p = &pollers[nbpollers++]; p->name = "sepoll";