shithub: riscv

Download patch

ref: dbbbff89151794c838319e831254bcff6b3dbbcf
parent: bc0e5ffa2293526ed3cf65a025263d2599c1f331
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
--