r22968: andrew bartlett pointed out that the parent process could add a fd to
authorAndrew Tridgell <tridge@samba.org>
Thu, 17 May 2007 07:52:33 +0000 (07:52 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:52:33 +0000 (14:52 -0500)
the epoll context which would then appear in the children. To fix this
we need to check for pid changes in more places. Luckily on platforms
where we have epoll(), getpid() is very very cheap.

source/lib/events/events_aio.c
source/lib/events/events_epoll.c
source/lib/events/events_standard.c

index e78487547f02b2c0d311dd9609d48b8428e8d960..ae5f597c185fd85ca71e65b41669d735df0ec4bf 100644 (file)
@@ -103,10 +103,14 @@ static void epoll_add_event(struct aio_event_context *aio_ev, struct fd_event *f
   see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an 
   demonstration of why this is needed
  */
-static void epoll_reopen(struct aio_event_context *aio_ev)
+static void epoll_check_reopen(struct aio_event_context *aio_ev)
 {
        struct fd_event *fde;
 
+       if (aio_ev->pid == getpid()) {
+               return;
+       }
+
        close(aio_ev->epoll_fd);
        aio_ev->epoll_fd = epoll_create(MAX_AIO_QUEUE_DEPTH);
        if (aio_ev->epoll_fd == -1) {
@@ -131,16 +135,6 @@ static void epoll_add_event(struct aio_event_context *aio_ev, struct fd_event *f
        struct epoll_event event;
        if (aio_ev->epoll_fd == -1) return;
 
-       /* during an add event we need to check if our pid has changed
-          and re-open the epoll socket. Note that we don't need to do this 
-          for other epoll changes */
-       if (aio_ev->pid != getpid()) {
-               epoll_reopen(aio_ev);
-               /* the current event gets added in epoll_reopen(), so
-                  we can return here */
-               return;
-       }
-
        fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
 
        /* if we don't want events yet, don't add an aio_event */
@@ -424,6 +418,8 @@ static struct fd_event *aio_event_add_fd(struct event_context *ev, TALLOC_CTX *m
                                                           struct aio_event_context);
        struct fd_event *fde;
 
+       epoll_check_reopen(aio_ev);
+
        fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
        if (!fde) return NULL;
 
@@ -468,6 +464,8 @@ static void aio_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
 
        fde->flags = flags;
 
+       epoll_check_reopen(aio_ev);
+
        epoll_change_event(aio_ev, fde);
 }
 
@@ -485,6 +483,8 @@ static int aio_event_loop_once(struct event_context *ev)
                return 0;
        }
 
+       epoll_check_reopen(aio_ev);
+
        return aio_event_loop(aio_ev, &tval);
 }
 
index 5b6266fb490217a49f223750f00bb6817e7f76ec..413925357e5d228bede7eb09eab2a917d46b4316 100644 (file)
@@ -102,10 +102,14 @@ static void epoll_add_event(struct epoll_event_context *epoll_ev, struct fd_even
   see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an 
   demonstration of why this is needed
  */
-static void epoll_reopen(struct epoll_event_context *epoll_ev)
+static void epoll_check_reopen(struct epoll_event_context *epoll_ev)
 {
        struct fd_event *fde;
 
+       if (epoll_ev->pid == getpid()) {
+               return;
+       }
+
        close(epoll_ev->epoll_fd);
        epoll_ev->epoll_fd = epoll_create(64);
        if (epoll_ev->epoll_fd == -1) {
@@ -131,16 +135,6 @@ static void epoll_add_event(struct epoll_event_context *epoll_ev, struct fd_even
 
        if (epoll_ev->epoll_fd == -1) return;
 
-       /* during an add event we need to check if our pid has changed
-          and re-open the epoll socket. Note that we don't need to do this 
-          for other epoll changes */
-       if (epoll_ev->pid != getpid()) {
-               epoll_reopen(epoll_ev);
-               /* the current event gets added in epoll_reopen(), so
-                  we can return here */
-               return;
-       }
-
        fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
 
        /* if we don't want events yet, don't add an epoll_event */
@@ -373,6 +367,8 @@ static struct fd_event *epoll_event_add_fd(struct event_context *ev, TALLOC_CTX
                                                           struct epoll_event_context);
        struct fd_event *fde;
 
+       epoll_check_reopen(epoll_ev);
+
        fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
        if (!fde) return NULL;
 
@@ -417,6 +413,8 @@ static void epoll_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
 
        fde->flags = flags;
 
+       epoll_check_reopen(epoll_ev);
+
        epoll_change_event(epoll_ev, fde);
 }
 
@@ -434,6 +432,8 @@ static int epoll_event_loop_once(struct event_context *ev)
                return 0;
        }
 
+       epoll_check_reopen(epoll_ev);
+
        return epoll_event_loop(epoll_ev, &tval);
 }
 
index 50ba4ed79f018236967626a6020ceda79f9d067d..ee3ca4e535b9411b87c89c8935d22ed4fd98b324 100644 (file)
@@ -119,10 +119,14 @@ static void epoll_add_event(struct std_event_context *std_ev, struct fd_event *f
   see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an 
   demonstration of why this is needed
  */
-static void epoll_reopen(struct std_event_context *std_ev)
+static void epoll_check_reopen(struct std_event_context *std_ev)
 {
        struct fd_event *fde;
 
+       if (std_ev->pid == getpid()) {
+               return;
+       }
+
        close(std_ev->epoll_fd);
        std_ev->epoll_fd = epoll_create(64);
        if (std_ev->epoll_fd == -1) {
@@ -147,16 +151,6 @@ static void epoll_add_event(struct std_event_context *std_ev, struct fd_event *f
        struct epoll_event event;
        if (std_ev->epoll_fd == -1) return;
 
-       /* during an add event we need to check if our pid has changed
-          and re-open the epoll socket. Note that we don't need to do this 
-          for other epoll changes */
-       if (std_ev->pid != getpid()) {
-               epoll_reopen(std_ev);
-               /* the current event gets added in epoll_reopen(), so
-                  we can return here */
-               return;
-       }
-
        fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
 
        /* if we don't want events yet, don't add an epoll_event */
@@ -415,6 +409,8 @@ static struct fd_event *std_event_add_fd(struct event_context *ev, TALLOC_CTX *m
                                                           struct std_event_context);
        struct fd_event *fde;
 
+       epoll_check_reopen(std_ev);
+
        fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
        if (!fde) return NULL;
 
@@ -462,6 +458,8 @@ static void std_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
 
        fde->flags = flags;
 
+       epoll_check_reopen(std_ev);
+
        epoll_change_event(std_ev, fde);
 }
 
@@ -558,6 +556,8 @@ static int std_event_loop_once(struct event_context *ev)
                return 0;
        }
 
+       epoll_check_reopen(std_ev);
+
        if (epoll_event_loop(std_ev, &tval) == 0) {
                return 0;
        }