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

tridge at samba.org tridge at samba.org
Mon Jan 31 08:18:52 GMT 2005


Author: tridge
Date: 2005-01-31 08:18:52 +0000 (Mon, 31 Jan 2005)
New Revision: 5123

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

Log:
fixed a bug in the timed events handling. It was possible for a timed
event handler to trigger a free that could cause a timer to be
triggered twice. This changs fixes it properly by marking timer events
to be removed using a zero next_event time.

I also changed the default timeout for events.c to be infinite, so if
there are no events to handle then smbd will sit forever doing
nothing. That allows it to be swapped out completely when idle.

Modified:
   branches/SAMBA_4_0/source/lib/events.c
   branches/SAMBA_4_0/source/lib/time.c


Changeset:
Modified: branches/SAMBA_4_0/source/lib/events.c
===================================================================
--- branches/SAMBA_4_0/source/lib/events.c	2005-01-31 07:24:00 UTC (rev 5122)
+++ branches/SAMBA_4_0/source/lib/events.c	2005-01-31 08:18:52 UTC (rev 5123)
@@ -221,7 +221,7 @@
 	fd_set r_fds, w_fds;
 	struct fd_event *fe;
 	struct loop_event *le;
-	struct timed_event *te;
+	struct timed_event *te, *te_next;
 	int selrtn;
 	struct timeval tval, t;
 	uint32_t destruction_count = ev->destruction_count;
@@ -253,13 +253,24 @@
 	}
 
 	/* start with a reasonable max timeout */
-	tval.tv_sec = 600;
+	tval.tv_sec = 0;
 	tval.tv_usec = 0;
 		
 	/* work out the right timeout for all timed events */
-	for (te=ev->timed_events;te;te=te->next) {
-		struct timeval tv = timeval_diff(&te->next_event, &t);
-		tval = timeval_min(&tv, &tval);
+	for (te=ev->timed_events;te;te=te_next) {
+		struct timeval tv;
+		te_next = te->next;
+		if (timeval_is_zero(&te->next_event)) {
+			talloc_free(te);
+			continue;
+		}
+
+		tv = timeval_diff(&te->next_event, &t);
+		if (timeval_is_zero(&tval)) {
+			tval = tv;
+		} else {
+			tval = timeval_min(&tv, &tval);
+		}
 	}
 
 	/* only do a select() if there're fd_events
@@ -316,18 +327,14 @@
 	for (te=ev->timed_events;te;) {
 		struct timed_event *next = te->next;
 		if (timeval_compare(&te->next_event, &t) >= 0) {
+			te->next_event = timeval_zero();
 			te->handler(ev, te, t);
 			if (destruction_count != ev->destruction_count) {
 				break;
 			}
-			if (timeval_compare(&te->next_event, &t) >= 0) {
-				/* the handler didn't set a time for the 
-				   next event - remove the event */
-				talloc_free(te);
-			}
 		}
 		te = next;
-	}		
+	}
 	
 	return 0;
 }

Modified: branches/SAMBA_4_0/source/lib/time.c
===================================================================
--- branches/SAMBA_4_0/source/lib/time.c	2005-01-31 07:24:00 UTC (rev 5122)
+++ branches/SAMBA_4_0/source/lib/time.c	2005-01-31 08:18:52 UTC (rev 5123)
@@ -402,6 +402,14 @@
 }
 
 /*
+  return True if a timeval is zero
+*/
+BOOL timeval_is_zero(struct timeval *tv)
+{
+	return tv->tv_sec == 0 && tv->tv_usec == 0;
+}
+
+/*
   return a timeval for the current time
 */
 struct timeval timeval_current(void)



More information about the samba-cvs mailing list