summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilly Tarreau <w@1wt.eu>2009-05-10 10:18:54 +0200
committerWilly Tarreau <w@1wt.eu>2009-05-10 18:19:22 +0200
commit53bbca0f14d536e1afe8231d1cd4f6ac84752c77 (patch)
tree2b99cc07d569f024490ca4149b690d88495e678b
parentf86b17c2a2969cfca5431dd7aa4d80f0757ebb74 (diff)
downloadhaproxy-53bbca0f14d536e1afe8231d1cd4f6ac84752c77.tar.gz
[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. (cherry-picked from commit d79e79b436144654d10124de7d5fd4c896ac0487) (cherry picked from commit 0d27ec2050a3208150af5dcaeda9dab7a53fdaf7)
-rw-r--r--src/ev_epoll.c13
-rw-r--r--src/ev_kqueue.c14
-rw-r--r--src/ev_sepoll.c13
3 files changed, 28 insertions, 12 deletions
diff --git a/src/ev_epoll.c b/src/ev_epoll.c
index 9ba7d8db7..726b0d7c1 100644
--- a/src/ev_epoll.c
+++ b/src/ev_epoll.c
@@ -308,7 +308,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)
if (epoll_events)
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 f34cdc3c1..46584b303 100644
--- a/src/ev_kqueue.c
+++ b/src/ev_kqueue.c
@@ -186,7 +186,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;
@@ -204,8 +204,11 @@ REGPRM1 static void _do_term(struct poller *p)
free(fd_evts[DIR_RD]);
if (kev)
free(kev);
- close(kqueue_fd);
- kqueue_fd = 0;
+
+ if (kqueue_fd >= 0) {
+ close(kqueue_fd);
+ kqueue_fd = -1;
+ }
p->private = NULL;
p->pref = 0;
@@ -233,7 +236,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;
@@ -252,6 +256,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 db3542357..417cbcfa8 100644
--- a/src/ev_sepoll.c
+++ b/src/ev_sepoll.c
@@ -526,7 +526,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;
@@ -545,8 +545,10 @@ REGPRM1 static void _do_term(struct poller *p)
if (epoll_events)
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;
@@ -579,7 +581,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;
@@ -598,6 +601,8 @@ static void _do_register(void)
if (nbpollers >= MAX_POLLERS)
return;
+
+ epoll_fd = -1;
p = &pollers[nbpollers++];
p->name = "sepoll";