]> git.kaiwu.me - haproxy.git/commitdiff
[BUG] O(1) pollers should check their FD before closing it
authorWilly Tarreau <w@1wt.eu>
Sun, 10 May 2009 08:18:54 +0000 (10:18 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 10 May 2009 16:19:22 +0000 (18:19 +0200)
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)

src/ev_epoll.c
src/ev_kqueue.c
src/ev_sepoll.c

index 9ba7d8db720d0b1958b041936593a2bb451a3081..726b0d7c12cbaaecdf4becc0cfa7cf8aa56941db 100644 (file)
@@ -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";
index f34cdc3c1bcb33b53fafee5a12990adb0a08b9d0..46584b3037e7520d53481f9de9bbb3122aa666e7 100644 (file)
@@ -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";
index db35423574af592d5e2dc44c8ed050a54583ee32..417cbcfa89543876d0cba77f4154a5491b628a91 100644 (file)
@@ -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";