Fix a few locking problems with multithreaded clients.
TODO: make server deal graciously with out-of-resources conditions
This commit is contained in:
parent
f8063a37d7
commit
f0d58f7830
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: rumpuser_sp.c,v 1.17 2010/11/26 14:37:08 pooka Exp $ */
|
||||
/* $NetBSD: rumpuser_sp.c,v 1.18 2010/11/26 18:51:03 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.17 2010/11/26 14:37:08 pooka Exp $");
|
||||
__RCSID("$NetBSD: rumpuser_sp.c,v 1.18 2010/11/26 18:51:03 pooka Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/atomic.h>
|
||||
|
@ -65,7 +65,7 @@ __RCSID("$NetBSD: rumpuser_sp.c,v 1.17 2010/11/26 14:37:08 pooka Exp $");
|
|||
|
||||
#include "sp_common.c"
|
||||
|
||||
#define MAXCLI 4
|
||||
#define MAXCLI 256
|
||||
|
||||
static struct pollfd pfdlist[MAXCLI];
|
||||
static struct spclient spclist[MAXCLI];
|
||||
|
@ -329,7 +329,6 @@ spcrelease(struct spclient *spc)
|
|||
spc->spc_dying = 0;
|
||||
|
||||
atomic_inc_uint(&disco);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -622,25 +621,22 @@ spserver(void *arg)
|
|||
DPRINTF(("rump_sp: server mainloop\n"));
|
||||
|
||||
for (;;) {
|
||||
/* g/c hangarounds (eventually) */
|
||||
if (disco) {
|
||||
int discoed;
|
||||
int discoed;
|
||||
|
||||
discoed = atomic_swap_uint(&disco, 0);
|
||||
while (discoed--) {
|
||||
nfds--;
|
||||
idx = maxidx;
|
||||
while (idx) {
|
||||
if (pfdlist[idx].fd != -1) {
|
||||
maxidx = idx;
|
||||
break;
|
||||
}
|
||||
idx--;
|
||||
/* g/c hangarounds (eventually) */
|
||||
discoed = atomic_swap_uint(&disco, 0);
|
||||
while (discoed--) {
|
||||
nfds--;
|
||||
idx = maxidx;
|
||||
while (idx) {
|
||||
if (pfdlist[idx].fd != -1) {
|
||||
maxidx = idx;
|
||||
break;
|
||||
}
|
||||
DPRINTF(("rump_sp: set maxidx to [%u]\n",
|
||||
maxidx));
|
||||
assert(maxidx+1 >= nfds);
|
||||
idx--;
|
||||
}
|
||||
DPRINTF(("rump_sp: set maxidx to [%u]\n",
|
||||
maxidx));
|
||||
}
|
||||
|
||||
DPRINTF(("rump_sp: loop nfd %d\n", maxidx+1));
|
||||
|
@ -744,7 +740,7 @@ rumpuser_sp_init(const struct rumpuser_sp_ops *spopsp, const char *url)
|
|||
fprintf(stderr, "rump_sp: server bind failed\n");
|
||||
return errno;
|
||||
}
|
||||
if (listen(s, 20) == -1) {
|
||||
if (listen(s, MAXCLI) == -1) {
|
||||
fprintf(stderr, "rump_sp: server listen failed\n");
|
||||
return errno;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sp_common.c,v 1.11 2010/11/26 14:37:08 pooka Exp $ */
|
||||
/* $NetBSD: sp_common.c,v 1.12 2010/11/26 18:51:03 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010 Antti Kantee. All Rights Reserved.
|
||||
|
@ -133,7 +133,7 @@ struct spclient {
|
|||
TAILQ_HEAD(, respwait) spc_respwait;
|
||||
|
||||
/* rest of the fields are zeroed upon disconnect */
|
||||
#define SPC_ZEROFF offsetof(struct spclient, spc_pid)
|
||||
#define SPC_ZEROFF offsetof(struct spclient, spc_pfd)
|
||||
struct pollfd *spc_pfd;
|
||||
|
||||
struct rsp_hdr spc_hdr;
|
||||
|
@ -154,26 +154,42 @@ static int readframe(struct spclient *);
|
|||
static void handlereq(struct spclient *);
|
||||
|
||||
static void
|
||||
sendlock(struct spclient *spc)
|
||||
sendlockl(struct spclient *spc)
|
||||
{
|
||||
|
||||
pthread_mutex_lock(&spc->spc_mtx);
|
||||
/* assert(pthread_mutex_owned) */
|
||||
while (spc->spc_ostatus != SPCSTATUS_FREE) {
|
||||
spc->spc_ostatus = SPCSTATUS_WANTED;
|
||||
pthread_cond_wait(&spc->spc_cv, &spc->spc_mtx);
|
||||
}
|
||||
spc->spc_ostatus = SPCSTATUS_BUSY;
|
||||
}
|
||||
|
||||
static void
|
||||
sendlock(struct spclient *spc)
|
||||
{
|
||||
|
||||
pthread_mutex_lock(&spc->spc_mtx);
|
||||
sendlockl(spc);
|
||||
pthread_mutex_unlock(&spc->spc_mtx);
|
||||
}
|
||||
|
||||
static void
|
||||
sendunlockl(struct spclient *spc)
|
||||
{
|
||||
|
||||
/* assert(pthread_mutex_owned) */
|
||||
if (spc->spc_ostatus == SPCSTATUS_WANTED)
|
||||
pthread_cond_broadcast(&spc->spc_cv);
|
||||
spc->spc_ostatus = SPCSTATUS_FREE;
|
||||
}
|
||||
|
||||
static void
|
||||
sendunlock(struct spclient *spc)
|
||||
{
|
||||
|
||||
pthread_mutex_lock(&spc->spc_mtx);
|
||||
if (spc->spc_ostatus == SPCSTATUS_WANTED)
|
||||
pthread_cond_broadcast(&spc->spc_cv);
|
||||
spc->spc_ostatus = SPCSTATUS_FREE;
|
||||
sendunlockl(spc);
|
||||
pthread_mutex_unlock(&spc->spc_mtx);
|
||||
}
|
||||
|
||||
|
@ -224,12 +240,16 @@ putwait(struct spclient *spc, struct respwait *rw, struct rsp_hdr *rhdr)
|
|||
pthread_mutex_lock(&spc->spc_mtx);
|
||||
rw->rw_reqno = rhdr->rsp_reqno = spc->spc_nextreq++;
|
||||
TAILQ_INSERT_TAIL(&spc->spc_respwait, rw, rw_entries);
|
||||
|
||||
sendlockl(spc);
|
||||
}
|
||||
|
||||
static void
|
||||
unputwait(struct spclient *spc, struct respwait *rw)
|
||||
{
|
||||
|
||||
sendunlockl(spc);
|
||||
|
||||
TAILQ_REMOVE(&spc->spc_respwait, rw, rw_entries);
|
||||
pthread_mutex_unlock(&spc->spc_mtx);
|
||||
pthread_cond_destroy(&rw->rw_cv);
|
||||
|
@ -267,7 +287,7 @@ kickall(struct spclient *spc)
|
|||
|
||||
/* DIAGASSERT(mutex_owned(spc_lock)) */
|
||||
TAILQ_FOREACH(rw, &spc->spc_respwait, rw_entries)
|
||||
pthread_cond_signal(&rw->rw_cv);
|
||||
pthread_cond_broadcast(&rw->rw_cv);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -276,6 +296,8 @@ waitresp(struct spclient *spc, struct respwait *rw)
|
|||
struct pollfd pfd;
|
||||
int rv = 0;
|
||||
|
||||
sendunlockl(spc);
|
||||
|
||||
while (rw->rw_data == NULL && spc->spc_dying == 0) {
|
||||
/* are we free to receive? */
|
||||
if (spc->spc_istatus == SPCSTATUS_FREE) {
|
||||
|
|
Loading…
Reference in New Issue