ref: 8e1776881518c08f12960787f272c583f5517a9f
parent: 377fbce85909a097ccfca51b2b0002177c4af53c
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Wed Jan 30 01:26:03 EST 2013
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.
--- a/sys/include/9p.h
+++ b/sys/include/9p.h
@@ -234,6 +234,7 @@
QLock slock;
Ref sref;
+ Ref rref;
};
void srv(Srv*);
--- a/sys/src/lib9p/srv.c
+++ b/sys/src/lib9p/srv.c
@@ -163,23 +163,34 @@
}
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,6 +693,8 @@
{}
+static void srvclose(Srv *);
+
static void
srvwork(void *v)
{@@ -688,8 +701,10 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
closereq(r);
else
free(r);
+
+ srvclose(srv);
}
void
--
⑨