From dbbbff89151794c838319e831254bcff6b3dbbcf Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Wed, 30 Jan 2013 06:26:03 +0100 Subject: lib9p: defer closing down srv until the last request has been responded, Tversion message size in multithreaded programs, we have to wait until all outstanding requests have been responded before closing down the srv. dont make write errors sysfatal(), only print them. in case if listensrv() is used we dont want to exit the process in respond() called by some worker thread. make sure Tversion is only handled when there are no outstanding requests and make sure message size is sane. --- sys/src/lib9p/srv.c | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) (limited to 'sys/src') diff --git a/sys/src/lib9p/srv.c b/sys/src/lib9p/srv.c index 33791cb18..12b1d7fe5 100644 --- a/sys/src/lib9p/srv.c +++ b/sys/src/lib9p/srv.c @@ -163,23 +163,34 @@ walkandclone(Req *r, char *(*walk1)(Fid*, char*, void*), char *(*clone)(Fid*, Fi } static void -sversion(Srv*, Req *r) +sversion(Srv *srv, Req *r) { + if(srv->rref.ref != 2){ + respond(r, Ebotch); + return; + } if(strncmp(r->ifcall.version, "9P", 2) != 0){ r->ofcall.version = "unknown"; respond(r, nil); return; } - r->ofcall.version = "9P2000"; - r->ofcall.msize = r->ifcall.msize; + if(r->ifcall.msize < 256){ + respond(r, "version: message size too small"); + return; + } + if(r->ifcall.msize < 1024*1024) + r->ofcall.msize = r->ifcall.msize; + else + r->ofcall.msize = 1024*1024; respond(r, nil); } + static void rversion(Req *r, char *error) { - assert(error == nil); - changemsize(r->srv, r->ofcall.msize); + if(error == nil) + changemsize(r->srv, r->ofcall.msize); } static void @@ -682,14 +693,18 @@ rwstat(Req*, char*) { } +static void srvclose(Srv *); + static void srvwork(void *v) { Srv *srv = v; Req *r; + incref(&srv->rref); incref(&srv->sref); while(r = getreq(srv)){ + incref(&srv->rref); if(r->error){ respond(r, r->error); continue; @@ -715,9 +730,19 @@ srvwork(void *v) } qunlock(&srv->slock); } - if(decref(&srv->sref)) + decref(&srv->sref); + srvclose(srv); +} + +static void +srvclose(Srv *srv) +{ + if(decref(&srv->rref)) return; + if(chatty9p) + fprint(2, "srvclose\n"); + free(srv->rbuf); srv->rbuf = nil; free(srv->wbuf); @@ -753,6 +778,9 @@ srv(Srv *srv) fmtinstall('D', dirfmt); fmtinstall('F', fcallfmt); + srv->sref.ref = 0; + srv->rref.ref = 0; + if(srv->fpool == nil) srv->fpool = allocfidpool(srv->destroyfid); if(srv->rpool == nil) @@ -819,7 +847,7 @@ if(chatty9p) qlock(&srv->wlock); n = convS2M(&r->ofcall, srv->wbuf, srv->msize); if(n <= 0){ - fprint(2, "n = %d %F\n", n, &r->ofcall); + fprint(2, "msize = %d n = %d %F\n", srv->msize, n, &r->ofcall); abort(); } assert(n > 2); @@ -827,7 +855,7 @@ if(chatty9p) closereq(removereq(r->pool, r->ifcall.tag)); m = write(srv->outfd, srv->wbuf, n); if(m != n) - sysfatal("lib9p srv: write %d returned %d on fd %d: %r", n, m, srv->outfd); + fprint(2, "lib9p srv: write %d returned %d on fd %d: %r", n, m, srv->outfd); qunlock(&srv->wlock); qlock(&r->lk); /* no one will add flushes now */ @@ -844,6 +872,8 @@ if(chatty9p) closereq(r); else free(r); + + srvclose(srv); } void -- cgit v1.2.3