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

tridge at samba.org tridge at samba.org
Tue Jan 23 00:06:34 GMT 2007


Author: tridge
Date: 2007-01-23 00:06:33 +0000 (Tue, 23 Jan 2007)
New Revision: 20960

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

Log:

attempt to fix a valgrind error in the signals backend.

This also reduces the static data in the signal backend when not using
signals to 4 bytes.

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


Changeset:
Modified: branches/SAMBA_4_0/source/lib/events/events_signal.c
===================================================================
--- branches/SAMBA_4_0/source/lib/events/events_signal.c	2007-01-22 23:38:55 UTC (rev 20959)
+++ branches/SAMBA_4_0/source/lib/events/events_signal.c	2007-01-23 00:06:33 UTC (rev 20960)
@@ -45,7 +45,7 @@
 /*
   the poor design of signals means that this table must be static global
 */
-static struct {
+static struct sig_state {
 	struct signal_event *sig_handlers[NUM_SIGNALS];
 	struct sigaction *oldact[NUM_SIGNALS];
 	struct sigcounter signal_count[NUM_SIGNALS];
@@ -56,7 +56,7 @@
 	siginfo_t *sig_info[NUM_SIGNALS];
 	struct sigcounter sig_blocked[NUM_SIGNALS];
 #endif
-} sig_state;
+} *sig_state;
 
 /*
   return number of sigcounter events not processed yet
@@ -75,10 +75,10 @@
 static void signal_handler(int signum)
 {
 	char c = 0;
-	SIG_INCREMENT(sig_state.signal_count[signum]);
-	SIG_INCREMENT(sig_state.got_signal);
+	SIG_INCREMENT(sig_state->signal_count[signum]);
+	SIG_INCREMENT(sig_state->got_signal);
 	/* doesn't matter if this pipe overflows */
-	write(sig_state.pipe_hack[1], &c, 1);
+	write(sig_state->pipe_hack[1], &c, 1);
 }
 
 #ifdef SA_SIGINFO
@@ -87,8 +87,8 @@
 */
 static void signal_handler_info(int signum, siginfo_t *info, void *uctx)
 {
-	uint32_t count = sig_count(sig_state.signal_count[signum]);
-	sig_state.sig_info[signum][count] = *info;
+	uint32_t count = sig_count(sig_state->signal_count[signum]);
+	sig_state->sig_info[signum][count] = *info;
 
 	signal_handler(signum);
 
@@ -100,7 +100,7 @@
 		sigemptyset(&set);
 		sigaddset(&set, signum);
 		sigprocmask(SIG_BLOCK, &set, NULL);
-		SIG_INCREMENT(sig_state.sig_blocked[signum]);
+		SIG_INCREMENT(sig_state->sig_blocked[signum]);
 	}
 }
 #endif
@@ -111,15 +111,15 @@
 static int signal_event_destructor(struct signal_event *se)
 {
 	se->event_ctx->num_signal_handlers--;
-	DLIST_REMOVE(sig_state.sig_handlers[se->signum], se);
-	if (sig_state.sig_handlers[se->signum] == NULL) {
+	DLIST_REMOVE(sig_state->sig_handlers[se->signum], se);
+	if (sig_state->sig_handlers[se->signum] == NULL) {
 		/* restore old handler, if any */
-		sigaction(se->signum, sig_state.oldact[se->signum], NULL);
-		sig_state.oldact[se->signum] = NULL;
+		sigaction(se->signum, sig_state->oldact[se->signum], NULL);
+		sig_state->oldact[se->signum] = NULL;
 #ifdef SA_SIGINFO
 		if (se->sa_flags & SA_SIGINFO) {
-			talloc_free(sig_state.sig_info[se->signum]);
-			sig_state.sig_info[se->signum] = NULL;
+			talloc_free(sig_state->sig_info[se->signum]);
+			sig_state->sig_info[se->signum] = NULL;
 		}
 #endif
 	}
@@ -134,7 +134,7 @@
 {
 	char c[16];
 	/* its non-blocking, doesn't matter if we read too much */
-	read(sig_state.pipe_hack[0], c, sizeof(c));
+	read(sig_state->pipe_hack[0], c, sizeof(c));
 }
 
 /*
@@ -154,6 +154,15 @@
 		return NULL;
 	}
 
+	/* the sig_state needs to be on a global context as it can last across
+	   multiple event contexts */
+	if (sig_state == NULL) {
+		sig_state = talloc_zero(talloc_autofree_context(), struct sig_state);
+		if (sig_state == NULL) {
+			return NULL;
+		}
+	}
+
 	se = talloc(mem_ctx?mem_ctx:ev, struct signal_event);
 	if (se == NULL) return NULL;
 
@@ -164,7 +173,7 @@
 	se->sa_flags            = sa_flags;
 
 	/* only install a signal handler if not already installed */
-	if (sig_state.sig_handlers[signum] == NULL) {
+	if (sig_state->sig_handlers[signum] == NULL) {
 		struct sigaction act;
 		ZERO_STRUCT(act);
 		act.sa_handler   = signal_handler;
@@ -173,40 +182,40 @@
 		if (sa_flags & SA_SIGINFO) {
 			act.sa_handler   = NULL;
 			act.sa_sigaction = signal_handler_info;
-			if (sig_state.sig_info[signum] == NULL) {
-				sig_state.sig_info[signum] = talloc_array(ev, siginfo_t, SA_INFO_QUEUE_COUNT);
-				if (sig_state.sig_info[signum] == NULL) {
+			if (sig_state->sig_info[signum] == NULL) {
+				sig_state->sig_info[signum] = talloc_array(sig_state, siginfo_t, SA_INFO_QUEUE_COUNT);
+				if (sig_state->sig_info[signum] == NULL) {
 					talloc_free(se);
 					return NULL;
 				}
 			}
 		}
 #endif
-		sig_state.oldact[signum] = talloc(ev, struct sigaction);
-		if (sig_state.oldact[signum] == NULL) {
+		sig_state->oldact[signum] = talloc(sig_state, struct sigaction);
+		if (sig_state->oldact[signum] == NULL) {
 			talloc_free(se);
 			return NULL;			
 		}
-		if (sigaction(signum, &act, sig_state.oldact[signum]) == -1) {
+		if (sigaction(signum, &act, sig_state->oldact[signum]) == -1) {
 			talloc_free(se);
 			return NULL;
 		}
 	}
 
-	DLIST_ADD(sig_state.sig_handlers[signum], se);
+	DLIST_ADD(sig_state->sig_handlers[signum], se);
 
 	talloc_set_destructor(se, signal_event_destructor);
 
 	/* we need to setup the pipe hack handler if not already
 	   setup */
 	if (ev->pipe_fde == NULL) {
-		if (sig_state.pipe_hack[0] == 0 && 
-		    sig_state.pipe_hack[1] == 0) {
-			pipe(sig_state.pipe_hack);
-			set_blocking(sig_state.pipe_hack[0], False);
-			set_blocking(sig_state.pipe_hack[1], False);
+		if (sig_state->pipe_hack[0] == 0 && 
+		    sig_state->pipe_hack[1] == 0) {
+			pipe(sig_state->pipe_hack);
+			set_blocking(sig_state->pipe_hack[0], False);
+			set_blocking(sig_state->pipe_hack[1], False);
 		}
-		ev->pipe_fde = event_add_fd(ev, ev, sig_state.pipe_hack[0],
+		ev->pipe_fde = event_add_fd(ev, ev, sig_state->pipe_hack[0],
 					    EVENT_FD_READ, signal_pipe_handler, NULL);
 	}
 	ev->num_signal_handlers++;
@@ -222,19 +231,20 @@
 int common_event_check_signal(struct event_context *ev)
 {
 	int i;
-	if (!SIG_PENDING(sig_state.got_signal)) {
+
+	if (!sig_state || !SIG_PENDING(sig_state->got_signal)) {
 		return 0;
 	}
 	
 	for (i=0;i<NUM_SIGNALS+1;i++) {
 		struct signal_event *se, *next;
-		struct sigcounter counter = sig_state.signal_count[i];
+		struct sigcounter counter = sig_state->signal_count[i];
 		uint32_t count = sig_count(counter);
 
 		if (count == 0) {
 			continue;
 		}
-		for (se=sig_state.sig_handlers[i];se;se=next) {
+		for (se=sig_state->sig_handlers[i];se;se=next) {
 			next = se->next;
 #ifdef SA_SIGINFO
 			if (se->sa_flags & SA_SIGINFO) {
@@ -244,17 +254,17 @@
 					   ring buffer */
 					int ofs = (counter.count + j) % SA_INFO_QUEUE_COUNT;
 					se->handler(ev, se, i, 1, 
-						    (void*)&sig_state.sig_info[i][ofs], 
+						    (void*)&sig_state->sig_info[i][ofs], 
 						    se->private_data);
 				}
-				if (SIG_PENDING(sig_state.sig_blocked[i])) {
+				if (SIG_PENDING(sig_state->sig_blocked[i])) {
 					/* we'd filled the queue, unblock the
 					   signal now */
 					sigset_t set;
 					sigemptyset(&set);
 					sigaddset(&set, i);
-					SIG_SEEN(sig_state.sig_blocked[i], 
-						 sig_count(sig_state.sig_blocked[i]));
+					SIG_SEEN(sig_state->sig_blocked[i], 
+						 sig_count(sig_state->sig_blocked[i]));
 					sigprocmask(SIG_UNBLOCK, &set, NULL);
 				}
 				if (se->sa_flags & SA_RESETHAND) {
@@ -268,8 +278,8 @@
 				talloc_free(se);
 			}
 		}
-		SIG_SEEN(sig_state.signal_count[i], count);
-		SIG_SEEN(sig_state.got_signal, count);
+		SIG_SEEN(sig_state->signal_count[i], count);
+		SIG_SEEN(sig_state->got_signal, count);
 	}
 
 	return 1;



More information about the samba-cvs mailing list