[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha8-1241-g76d9115

Andrew Tridgell tridge at samba.org
Thu Aug 27 22:28:37 MDT 2009


The branch, master has been updated
       via  76d91156c82e20bbd68c752376cb814d71759033 (commit)
       via  be4ac227842530d484659f2db683453366326d8b (commit)
       via  6abb637e3e0d23635fdbbb91c163731b325d696d (commit)
       via  398d0c2929026fccb3409316720a4dcad225ab05 (commit)
       via  4279879c9847ca069527e11ca934b8906009cad8 (commit)
      from  cc248f7dfccf015586627ecef5fc5a475cc7f842 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 76d91156c82e20bbd68c752376cb814d71759033
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Aug 28 12:11:23 2009 +0930

    lib/tevent: close pipe_fds on event_context destruction
    
    The "hack_fds" were never closed before; now they're inside event_context
    they should be closed when that is destroyed.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit be4ac227842530d484659f2db683453366326d8b
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Aug 28 12:08:47 2009 +0930

    lib/tevent: handle tevent_common_add_signal on different event contexts.
    
    I don't know if this is a problem in real life.
    
    The code assumes there's only one tevent_context; all signals will notify
    the first event context.  That's counter-intuitive if you ever use more
    than one, and there's nothing else in this code which prevents it AFAICT.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 6abb637e3e0d23635fdbbb91c163731b325d696d
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Aug 28 12:04:22 2009 +0930

    lib/tevent: fix race with signals and tevent_common_add_signal
    
    We carefully preserve the old signal handler, but we replace it before
    we've set up everything; in particular, if we fail setting up the
    pipe_hack we could write a NUL char to stdout (fd 0), instead of
    calling the old signal handler.
    
    Replace the signal handler as the very last thing we do.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 398d0c2929026fccb3409316720a4dcad225ab05
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Aug 28 11:56:34 2009 +0930

    lib/tdb: don't overwrite TDBs with different version numbers.
    
    In future, this may happen, and we don't want to clobber them.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 4279879c9847ca069527e11ca934b8906009cad8
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Wed Aug 26 17:30:32 2009 +0930

    lib/tevent: remove spectacularly complicated manual subtraction
    
    To be completely honest, I don't quite know whether to laugh or cry at
    this one:
    
    	1 + (0xFFFFFFFF & ~(s.seen - s.count))
    	== 1 + (~(s.seen - s.count))		# s.seen, s.count are uint32_t
    	== s.count - s.seen			# -A == ~A + 1
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

-----------------------------------------------------------------------

Summary of changes:
 lib/tdb/common/open.c        |   12 ++++---
 lib/tevent/tevent.c          |    2 +
 lib/tevent/tevent_internal.h |    1 +
 lib/tevent/tevent_signal.c   |   69 +++++++++++++++++++++++++-----------------
 4 files changed, 51 insertions(+), 33 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/tdb/common/open.c b/lib/tdb/common/open.c
index 2e6a707..141e6fe 100644
--- a/lib/tdb/common/open.c
+++ b/lib/tdb/common/open.c
@@ -240,17 +240,19 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
 
 	errno = 0;
 	if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header)
-	    || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0
-	    || (tdb->header.version != TDB_VERSION
-		&& !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) {
-		/* its not a valid database - possibly initialise it */
+	    || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0) {
 		if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) {
 			if (errno == 0) {
-			errno = EIO; /* ie bad format or something */
+				errno = EIO; /* ie bad format or something */
 			}
 			goto fail;
 		}
 		rev = (tdb->flags & TDB_CONVERT);
+	} else if (tdb->header.version != TDB_VERSION
+		   && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION)))) {
+		/* wrong version */
+		errno = EIO;
+		goto fail;
 	}
 	vp = (unsigned char *)&tdb->header.version;
 	vertest = (((uint32_t)vp[0]) << 24) | (((uint32_t)vp[1]) << 16) |
diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c
index 0c02e46..56d0da3 100644
--- a/lib/tevent/tevent.c
+++ b/lib/tevent/tevent.c
@@ -148,6 +148,8 @@ int tevent_common_context_destructor(struct tevent_context *ev)
 
 	if (ev->pipe_fde) {
 		talloc_free(ev->pipe_fde);
+		close(ev->pipe_fds[0]);
+		close(ev->pipe_fds[1]);
 		ev->pipe_fde = NULL;
 	}
 
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index 513ca1c..4e3b7b5 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -240,6 +240,7 @@ struct tevent_context {
 
 	/* pipe hack used with signal handlers */
 	struct tevent_fd *pipe_fde;
+	int pipe_fds[2];
 
 	/* debugging operations */
 	struct tevent_debug_ops debug_ops;
diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c
index f07de83..0333325 100644
--- a/lib/tevent/tevent_signal.c
+++ b/lib/tevent/tevent_signal.c
@@ -57,7 +57,6 @@ static struct sig_state {
 	struct sigaction *oldact[NUM_SIGNALS+1];
 	struct sigcounter signal_count[NUM_SIGNALS+1];
 	struct sigcounter got_signal;
-	int pipe_hack[2];
 #ifdef SA_SIGINFO
 	/* with SA_SIGINFO we get quite a lot of info per signal */
 	siginfo_t *sig_info[NUM_SIGNALS+1];
@@ -70,10 +69,7 @@ static struct sig_state {
 */
 static uint32_t sig_count(struct sigcounter s)
 {
-	if (s.count >= s.seen) {
-		return s.count - s.seen;
-	}
-	return 1 + (0xFFFFFFFF & ~(s.seen - s.count));
+	return s.count - s.seen;
 }
 
 /*
@@ -83,10 +79,20 @@ static void tevent_common_signal_handler(int signum)
 {
 	char c = 0;
 	ssize_t res;
+	struct tevent_common_signal_list *sl;
+	struct tevent_context *ev = NULL;
+
 	SIG_INCREMENT(sig_state->signal_count[signum]);
 	SIG_INCREMENT(sig_state->got_signal);
-	/* doesn't matter if this pipe overflows */
-	res = write(sig_state->pipe_hack[1], &c, 1);
+
+	/* Write to each unique event context. */
+	for (sl = sig_state->sig_handlers[signum]; sl; sl = sl->next) {
+		if (sl->se->event_ctx != ev) {
+			/* doesn't matter if this pipe overflows */
+			res = write(ev->pipe_fds[1], &c, 1);
+			ev = sl->se->event_ctx;
+		}
+	}
 }
 
 #ifdef SA_SIGINFO
@@ -163,7 +169,7 @@ static void signal_pipe_handler(struct tevent_context *ev, struct tevent_fd *fde
 	char c[16];
 	ssize_t res;
 	/* its non-blocking, doesn't matter if we read too much */
-	res = read(sig_state->pipe_hack[0], c, sizeof(c));
+	res = read(fde->fd, c, sizeof(c));
 }
 
 /*
@@ -181,6 +187,7 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
 {
 	struct tevent_signal *se;
 	struct tevent_common_signal_list *sl;
+	sigset_t set, oldset;
 
 	if (signum >= NUM_SIGNALS) {
 		errno = EINVAL;
@@ -222,6 +229,26 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
 		return NULL;
 	}
 
+	/* we need to setup the pipe hack handler if not already
+	   setup */
+	if (ev->pipe_fde == NULL) {
+		if (pipe(ev->pipe_fds) == -1) {
+			talloc_free(se);
+			return NULL;
+		}
+		ev_set_blocking(ev->pipe_fds[0], false);
+		ev_set_blocking(ev->pipe_fds[1], false);
+		ev->pipe_fde = tevent_add_fd(ev, ev, ev->pipe_fds[0],
+					     TEVENT_FD_READ,
+					     signal_pipe_handler, NULL);
+		if (!ev->pipe_fde) {
+			close(ev->pipe_fds[0]);
+			close(ev->pipe_fds[1]);
+			talloc_free(se);
+			return NULL;
+		}
+	}
+
 	/* only install a signal handler if not already installed */
 	if (sig_state->sig_handlers[signum] == NULL) {
 		struct sigaction act;
@@ -253,31 +280,17 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
 	}
 
 	DLIST_ADD(se->event_ctx->signal_events, se);
+
+	/* Make sure the signal doesn't come in while we're mangling list. */
+	sigemptyset(&set);
+	sigaddset(&set, signum);
+	sigprocmask(SIG_BLOCK, &set, &oldset);
 	DLIST_ADD(sig_state->sig_handlers[signum], sl);
+	sigprocmask(SIG_SETMASK, &oldset, NULL);
 
 	talloc_set_destructor(se, tevent_signal_destructor);
 	talloc_set_destructor(sl, tevent_common_signal_list_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) {
-			if (pipe(sig_state->pipe_hack) == -1) {
-				talloc_free(se);
-				return NULL;
-			}
-			ev_set_blocking(sig_state->pipe_hack[0], false);
-			ev_set_blocking(sig_state->pipe_hack[1], false);
-		}
-		ev->pipe_fde = tevent_add_fd(ev, ev, sig_state->pipe_hack[0],
-					     TEVENT_FD_READ, signal_pipe_handler, NULL);
-		if (!ev->pipe_fde) {
-			talloc_free(se);
-			return NULL;
-		}
-	}
-
 	return se;
 }
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list