svn commit: samba r21171 - in branches/SAMBA_4_0/source/lib/events: .

tridge at samba.org tridge at samba.org
Tue Feb 6 04:43:48 GMT 2007


Author: tridge
Date: 2007-02-06 04:43:48 +0000 (Tue, 06 Feb 2007)
New Revision: 21171

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=21171

Log:

fixed a bug related to recursive event handling. 

If this happens:

  - two sockets are readable, and select/epoll/aio returns both of
    them
  - read event on socket1 is called
  - inside that read event an event_loop_once is called, this returns that
    socket2 is readable
  - read event on socket2 is called
  - event_loop_once returns
  - top level event handler then calls read event on socket2 (as it
    still has that listed as readable)
  - read handler for socket2 returns zero byte read, which is
    interpreted as end of file
  - socket is incorrectly closed

this happened with ctdb, but it could happen anywhere (just
rarely). The fix is trivial - ensure we break out of the event loop
when we have been called recursively.

Modified:
   branches/SAMBA_4_0/source/lib/events/events_aio.c
   branches/SAMBA_4_0/source/lib/events/events_epoll.c
   branches/SAMBA_4_0/source/lib/events/events_select.c
   branches/SAMBA_4_0/source/lib/events/events_standard.c


Changeset:
Modified: branches/SAMBA_4_0/source/lib/events/events_aio.c
===================================================================
--- branches/SAMBA_4_0/source/lib/events/events_aio.c	2007-02-06 04:42:52 UTC (rev 21170)
+++ branches/SAMBA_4_0/source/lib/events/events_aio.c	2007-02-06 04:43:48 UTC (rev 21171)
@@ -219,7 +219,7 @@
 static int aio_event_loop(struct aio_event_context *aio_ev, struct timeval *tvalp)
 {
 	int ret, i;
-	uint32_t destruction_count = aio_ev->destruction_count;
+	uint32_t destruction_count = ++aio_ev->destruction_count;
 	struct timespec timeout;
 	struct io_event events[8];
 

Modified: branches/SAMBA_4_0/source/lib/events/events_epoll.c
===================================================================
--- branches/SAMBA_4_0/source/lib/events/events_epoll.c	2007-02-06 04:42:52 UTC (rev 21170)
+++ branches/SAMBA_4_0/source/lib/events/events_epoll.c	2007-02-06 04:43:48 UTC (rev 21171)
@@ -204,7 +204,7 @@
 	int ret, i;
 #define MAXEVENTS 8
 	struct epoll_event events[MAXEVENTS];
-	uint32_t destruction_count = epoll_ev->destruction_count;
+	uint32_t destruction_count = ++epoll_ev->destruction_count;
 	int timeout = -1;
 
 	if (epoll_ev->epoll_fd == -1) return -1;

Modified: branches/SAMBA_4_0/source/lib/events/events_select.c
===================================================================
--- branches/SAMBA_4_0/source/lib/events/events_select.c	2007-02-06 04:42:52 UTC (rev 21170)
+++ branches/SAMBA_4_0/source/lib/events/events_select.c	2007-02-06 04:43:48 UTC (rev 21171)
@@ -47,12 +47,8 @@
 	/* information for exiting from the event loop */
 	int exit_code;
 
-	/* this is changed by the destructors for the fd event
-	   type. It is used to detect event destruction by event
-	   handlers, which means the code that is calling the event
-	   handler needs to assume that the linked list is no longer
-	   valid
-	*/
+	/* this is incremented when the loop over events causes something which
+	   could change the events yet to be processed */
 	uint32_t destruction_count;
 };
 
@@ -177,7 +173,7 @@
 	fd_set r_fds, w_fds;
 	struct fd_event *fde;
 	int selrtn;
-	uint32_t destruction_count = select_ev->destruction_count;
+	uint32_t destruction_count = ++select_ev->destruction_count;
 
 	/* we maybe need to recalculate the maxfd */
 	if (select_ev->maxfd == EVENT_INVALID_MAXFD) {

Modified: branches/SAMBA_4_0/source/lib/events/events_standard.c
===================================================================
--- branches/SAMBA_4_0/source/lib/events/events_standard.c	2007-02-06 04:42:52 UTC (rev 21170)
+++ branches/SAMBA_4_0/source/lib/events/events_standard.c	2007-02-06 04:43:48 UTC (rev 21171)
@@ -219,7 +219,7 @@
 	int ret, i;
 #define MAXEVENTS 8
 	struct epoll_event events[MAXEVENTS];
-	uint32_t destruction_count = std_ev->destruction_count;
+	uint32_t destruction_count = ++std_ev->destruction_count;
 	int timeout = -1;
 
 	if (std_ev->epoll_fd == -1) return -1;
@@ -425,7 +425,7 @@
 	fd_set r_fds, w_fds;
 	struct fd_event *fde;
 	int selrtn;
-	uint32_t destruction_count = std_ev->destruction_count;
+	uint32_t destruction_count = ++std_ev->destruction_count;
 
 	/* we maybe need to recalculate the maxfd */
 	if (std_ev->maxfd == EVENT_INVALID_MAXFD) {



More information about the samba-cvs mailing list