Module Name:    src
Committed By:   pooka
Date:           Mon Feb  7 15:25:41 UTC 2011

Modified Files:
        src/lib/librumpclient: rumpclient.c

Log Message:
malloc/free aren't async-signal-safe, so avoid calling them when
signals aren't blocked.

this bug made tests/rump/rumpkern/t_sp:sigsafe rarely deadlock


To generate a diff of this commit:
cvs rdiff -u -r1.25 -r1.26 src/lib/librumpclient/rumpclient.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/librumpclient/rumpclient.c
diff -u src/lib/librumpclient/rumpclient.c:1.25 src/lib/librumpclient/rumpclient.c:1.26
--- src/lib/librumpclient/rumpclient.c:1.25	Mon Feb  7 14:49:53 2011
+++ src/lib/librumpclient/rumpclient.c	Mon Feb  7 15:25:41 2011
@@ -1,4 +1,4 @@
-/*      $NetBSD: rumpclient.c,v 1.25 2011/02/07 14:49:53 pooka Exp $	*/
+/*      $NetBSD: rumpclient.c,v 1.26 2011/02/07 15:25:41 pooka Exp $	*/
 
 /*
  * Copyright (c) 2010, 2011 Antti Kantee.  All Rights Reserved.
@@ -267,12 +267,11 @@
 }
 
 static int
-syscall_req(struct spclient *spc, int sysnum,
+syscall_req(struct spclient *spc, sigset_t *omask, int sysnum,
 	const void *data, size_t dlen, void **resp)
 {
 	struct rsp_hdr rhdr;
 	struct respwait rw;
-	sigset_t omask;
 	int rv;
 
 	rhdr.rsp_len = sizeof(rhdr) + dlen;
@@ -280,7 +279,6 @@
 	rhdr.rsp_type = RUMPSP_SYSCALL;
 	rhdr.rsp_sysnum = sysnum;
 
-	pthread_sigmask(SIG_SETMASK, &fullset, &omask);
 	do {
 		putwait(spc, &rw, &rhdr);
 		if ((rv = send_with_recon(spc, &rhdr, sizeof(rhdr))) != 0) {
@@ -292,11 +290,10 @@
 			continue;
 		}
 
-		rv = cliwaitresp(spc, &rw, &omask, false);
+		rv = cliwaitresp(spc, &rw, omask, false);
 		if (rv == ENOTCONN)
 			rv = EAGAIN;
 	} while (rv == EAGAIN);
-	pthread_sigmask(SIG_SETMASK, &omask, NULL);
 
 	*resp = rw.rw_data;
 	return rv;
@@ -346,28 +343,27 @@
 		else
 			unputwait(spc, &rw);
 		if (cancel) {
-			pthread_sigmask(SIG_SETMASK, &omask, NULL);
-			return rv;
+			goto out;
 		}
 	} else {
 		rv = cliwaitresp(spc, &rw, &omask, haslock);
 	}
-	pthread_sigmask(SIG_SETMASK, &omask, NULL);
 	if (rv)
-		return rv;
+		goto out;
 
 	rv = *(int *)rw.rw_data;
 	free(rw.rw_data);
 
+ out:
+	pthread_sigmask(SIG_SETMASK, &omask, NULL);
 	return rv;
 }
 
 static int
-prefork_req(struct spclient *spc, void **resp)
+prefork_req(struct spclient *spc, sigset_t *omask, void **resp)
 {
 	struct rsp_hdr rhdr;
 	struct respwait rw;
-	sigset_t omask;
 	int rv;
 
 	rhdr.rsp_len = sizeof(rhdr);
@@ -375,7 +371,6 @@
 	rhdr.rsp_type = RUMPSP_PREFORK;
 	rhdr.rsp_error = 0;
 
-	pthread_sigmask(SIG_SETMASK, &fullset, &omask);
 	do {
 		putwait(spc, &rw, &rhdr);
 		rv = send_with_recon(spc, &rhdr, sizeof(rhdr));
@@ -384,11 +379,10 @@
 			continue;
 		}
 
-		rv = cliwaitresp(spc, &rw, &omask, false);
+		rv = cliwaitresp(spc, &rw, omask, false);
 		if (rv == ENOTCONN)
 			rv = EAGAIN;
 	} while (rv == EAGAIN);
-	pthread_sigmask(SIG_SETMASK, &omask, NULL);
 
 	*resp = rw.rw_data;
 	return rv;
@@ -463,15 +457,18 @@
 	register_t *retval)
 {
 	struct rsp_sysresp *resp;
+	sigset_t omask;
 	void *rdata;
 	int rv;
 
+	pthread_sigmask(SIG_SETMASK, &fullset, &omask);
+
 	DPRINTF(("rumpsp syscall_req: syscall %d with %p/%zu\n",
 	    sysnum, data, dlen));
 
-	rv = syscall_req(&clispc, sysnum, data, dlen, &rdata);
+	rv = syscall_req(&clispc, &omask, sysnum, data, dlen, &rdata);
 	if (rv)
-		return rv;
+		goto out;
 
 	resp = rdata;
 	DPRINTF(("rumpsp syscall_resp: syscall %d error %d, rv: %d/%d\n",
@@ -481,6 +478,8 @@
 	rv = resp->rsys_error;
 	free(rdata);
 
+ out:
+	pthread_sigmask(SIG_SETMASK, &omask, NULL);
 	return rv;
 }
 
@@ -757,22 +756,27 @@
 rumpclient_prefork(void)
 {
 	struct rumpclient_fork *rpf;
+	sigset_t omask;
 	void *resp;
 	int rv;
 
+	pthread_sigmask(SIG_SETMASK, &fullset, &omask);
 	rpf = malloc(sizeof(*rpf));
 	if (rpf == NULL)
 		return NULL;
 
-	if ((rv = prefork_req(&clispc, &resp)) != 0) {
+	if ((rv = prefork_req(&clispc, &omask, &resp)) != 0) {
 		free(rpf);
 		errno = rv;
-		return NULL;
+		rpf = NULL;
+		goto out;
 	}
 
 	memcpy(rpf->fork_auth, resp, sizeof(rpf->fork_auth));
 	free(resp);
 
+ out:
+	pthread_sigmask(SIG_SETMASK, &omask, NULL);
 	return rpf;
 }
 

Reply via email to