Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/librumpclient malloc/free aren't async-signal-safe, so a...



details:   https://anonhg.NetBSD.org/src/rev/ee3a3a32829d
branches:  trunk
changeset: 761782:ee3a3a32829d
user:      pooka <pooka%NetBSD.org@localhost>
date:      Mon Feb 07 15:25:41 2011 +0000

description:
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

diffstat:

 lib/librumpclient/rumpclient.c |  42 +++++++++++++++++++++++-------------------
 1 files changed, 23 insertions(+), 19 deletions(-)

diffs (159 lines):

diff -r 48a668ff241e -r ee3a3a32829d lib/librumpclient/rumpclient.c
--- a/lib/librumpclient/rumpclient.c    Mon Feb 07 14:49:53 2011 +0000
+++ b/lib/librumpclient/rumpclient.c    Mon Feb 07 15:25:41 2011 +0000
@@ -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;
 }
 



Home | Main Index | Thread Index | Old Index