diff --git a/sys/include/9p.h b/sys/include/9p.h index a3415d246..68e6e7aaa 100644 --- a/sys/include/9p.h +++ b/sys/include/9p.h @@ -231,6 +231,9 @@ struct Srv { QLock wlock; char* addr; + + QLock slock; + Ref sref; }; void srv(Srv*); @@ -275,6 +278,9 @@ int authattach(Req*); extern void (*_forker)(void (*)(void*), void*, int); +void srvacquire(Srv *); +void srvrelease(Srv *); + Reqqueue* reqqueuecreate(void); void reqqueuepush(Reqqueue*, Req*, void (*)(Req *)); void reqqueueflush(Reqqueue*, Req*); diff --git a/sys/src/lib9p/srv.c b/sys/src/lib9p/srv.c index 5d2fc6c57..8c4b95389 100644 --- a/sys/src/lib9p/srv.c +++ b/sys/src/lib9p/srv.c @@ -682,31 +682,19 @@ rwstat(Req*, char*) { } -void -srv(Srv *srv) +static void +srvwork(void *v) { + Srv *srv = v; Req *r; - fmtinstall('D', dirfmt); - fmtinstall('F', fcallfmt); - - if(srv->fpool == nil) - srv->fpool = allocfidpool(srv->destroyfid); - if(srv->rpool == nil) - srv->rpool = allocreqpool(srv->destroyreq); - if(srv->msize == 0) - srv->msize = 8192+IOHDRSZ; - - changemsize(srv, srv->msize); - - srv->fpool->srv = srv; - srv->rpool->srv = srv; - + incref(&srv->sref); while(r = getreq(srv)){ if(r->error){ respond(r, r->error); continue; } + qlock(&srv->slock); switch(r->ifcall.type){ default: respond(r, "unknown message"); @@ -725,7 +713,10 @@ srv(Srv *srv) case Tstat: sstat(srv, r); break; case Twstat: swstat(srv, r); break; } + qunlock(&srv->slock); } + if(decref(&srv->sref)) + return; free(srv->rbuf); srv->rbuf = nil; @@ -741,6 +732,42 @@ srv(Srv *srv) srv->end(srv); } +void +srvacquire(Srv *srv) +{ + incref(&srv->sref); + qlock(&srv->slock); +} + +void +srvrelease(Srv *srv) +{ + if(decref(&srv->sref) == 0) + _forker(srvwork, srv, 0); + qunlock(&srv->slock); +} + +void +srv(Srv *srv) +{ + fmtinstall('D', dirfmt); + fmtinstall('F', fcallfmt); + + if(srv->fpool == nil) + srv->fpool = allocfidpool(srv->destroyfid); + if(srv->rpool == nil) + srv->rpool = allocreqpool(srv->destroyreq); + if(srv->msize == 0) + srv->msize = 8192+IOHDRSZ; + + changemsize(srv, srv->msize); + + srv->fpool->srv = srv; + srv->rpool->srv = srv; + + srvwork(srv); +} + void respond(Req *r, char *error) {