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));
}
}
}