Module Name: src Committed By: pooka Date: Wed Nov 24 15:17:47 UTC 2010
Modified Files: src/lib/librumpuser: rumpuser_sp.c Log Message: improve threadsafety To generate a diff of this commit: cvs rdiff -u -r1.11 -r1.12 src/lib/librumpuser/rumpuser_sp.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/librumpuser/rumpuser_sp.c diff -u src/lib/librumpuser/rumpuser_sp.c:1.11 src/lib/librumpuser/rumpuser_sp.c:1.12 --- src/lib/librumpuser/rumpuser_sp.c:1.11 Wed Nov 24 11:40:24 2010 +++ src/lib/librumpuser/rumpuser_sp.c Wed Nov 24 15:17:46 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: rumpuser_sp.c,v 1.11 2010/11/24 11:40:24 pooka Exp $ */ +/* $NetBSD: rumpuser_sp.c,v 1.12 2010/11/24 15:17:46 pooka Exp $ */ /* * Copyright (c) 2010 Antti Kantee. All Rights Reserved. @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: rumpuser_sp.c,v 1.11 2010/11/24 11:40:24 pooka Exp $"); +__RCSID("$NetBSD: rumpuser_sp.c,v 1.12 2010/11/24 15:17:46 pooka Exp $"); #include <sys/types.h> #include <sys/atomic.h> @@ -308,7 +308,9 @@ if (ref > 0) return; - _DIAGASSERT(TAILQ_EMPTY(&spclist[i].spc_respwait)); + DPRINTF(("spcrelease: spc %p fd %d\n", spc, spc->spc_fd)); + + _DIAGASSERT(TAILQ_EMPTY(spc->spc_respwait)); _DIAGASSERT(spc->spc_buf == NULL); lwproc_switch(spc->spc_mainlwp); @@ -317,9 +319,8 @@ close(spc->spc_fd); spc->spc_fd = -1; + spc->spc_dying = 0; - spc->spc_pfd->fd = -1; - membar_producer(); atomic_inc_uint(&disco); } @@ -331,6 +332,12 @@ DPRINTF(("rump_sp: disconnecting [%u]\n", idx)); + pfdlist[idx].fd = -1; + pfdlist[idx].revents = 0; + pthread_mutex_lock(&spc->spc_mtx); + spc->spc_dying = 1; + kickall(spc); + pthread_mutex_unlock(&spc->spc_mtx); spcrelease(spc); } @@ -367,7 +374,7 @@ /* find empty slot the simple way */ for (i = 0; i < MAXCLI; i++) { - if (pfdlist[i].fd == -1) + if (pfdlist[i].fd == -1 && spclist[i].spc_dying == 0) break; } @@ -427,6 +434,7 @@ struct sysbouncearg *barg = arg; serv_handlesyscall(barg->sba_spc, &barg->sba_hdr, barg->sba_data); + spcrelease(barg->sba_spc); free(arg); return NULL; } @@ -436,8 +444,11 @@ { struct spclient *spc = arg; void *rdata = NULL; /* XXXuninit */ + int rv; - copyin_req(spc, uaddr, len, &rdata); + rv = copyin_req(spc, uaddr, len, &rdata); + if (rv) + return EFAULT; memcpy(kaddr, rdata, len); free(rdata); @@ -536,8 +547,6 @@ pfdlist[idx].events = POLLIN; spc = &spclist[idx]; - - spc->spc_pfd = &pfdlist[idx]; pthread_mutex_init(&spc->spc_mtx, NULL); pthread_cond_init(&spc->spc_cv, NULL); } @@ -553,20 +562,20 @@ if (disco) { int discoed; - membar_consumer(); discoed = atomic_swap_uint(&disco, 0); while (discoed--) { nfds--; idx = maxidx; - while (idx--) { + while (idx) { if (pfdlist[idx].fd != -1) { maxidx = idx; break; } - assert(idx != 0); + idx--; } DPRINTF(("rump_sp: set maxidx to [%u]\n", maxidx)); + assert(maxidx+1 >= nfds); } } @@ -583,9 +592,7 @@ break; } - for (idx = 0; seen < rv; idx++) { - assert(idx < MAXCLI); - + for (idx = 0; seen < rv && idx < MAXCLI; idx++) { if ((pfdlist[idx].revents & POLLIN) == 0) continue; @@ -594,7 +601,6 @@ idx, seen, rv)); if (idx > 0) { spc = &spclist[idx]; - DPRINTF(("rump_sp: mainloop read [%u]\n", idx)); switch (readframe(spc)) { case 0: @@ -627,6 +633,7 @@ nfds++; if (idx > maxidx) maxidx = idx; + DPRINTF(("rump_sp: maxid now %d\n", maxidx)); } } }