git: 9front

Download patch

ref: 15fc57d86c27c87281a115833c607b7d5afaa90f
parent: b0229d4f6917d23a1e75dc66d6c41e26b2723f0c
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Oct 15 09:21:30 EDT 2015

lib9p: do not override Srv.end in listensrv(), simplify srvclose() and recounting

listensrv() used to override Srv.end() with its own handler
to free the malloc'd Srv structure and close the fd. this
makes it impossible to register your own cleanup handler.
instead, we introduce the private Srv.free() handler that
is used by listensrv to register its cleanup code. Srv.free()
is called once all the srv procs have been exited and all
requests on that srv have been responded to while Srv.end()
is called once all the procs exited the srv loop regardless
of the requests still being in flight.

--- a/sys/include/9p.h
+++ b/sys/include/9p.h
@@ -233,8 +233,10 @@
 	char*	addr;
 
 	QLock	slock;
-	Ref	sref;
-	Ref	rref;
+	Ref	sref;	/* srvwork procs */
+	Ref	rref;	/* requests in flight */
+
+	void	(*free)(Srv*);
 };
 
 void		srv(Srv*);
--- a/sys/src/lib9p/listen.c
+++ b/sys/src/lib9p/listen.c
@@ -7,7 +7,7 @@
 
 static void listenproc(void*);
 static void srvproc(void*);
-static void srvend(Srv *);
+static void srvfree(Srv *);
 static char *getremotesys(char*);
 
 void
@@ -58,7 +58,7 @@
 		s->rpool = nil;
 		s->rbuf = nil;
 		s->wbuf = nil;
-		s->end = srvend;
+		s->free = srvfree;
 		_forker(srvproc, s, 0);
 	}
 	free(os->addr);
@@ -72,7 +72,7 @@
 }
 
 static void
-srvend(Srv *s)
+srvfree(Srv *s)
 {
 	close(s->infd);
 	free(s->addr);
--- a/sys/src/lib9p/srv.c
+++ b/sys/src/lib9p/srv.c
@@ -167,7 +167,7 @@
 static void
 sversion(Srv *srv, Req *r)
 {
-	if(srv->rref.ref != 2){
+	if(srv->rref.ref != 1){
 		respond(r, Ebotch);
 		return;
 	}
@@ -724,8 +724,6 @@
 	Srv *srv = v;
 	Req *r;
 
-	incref(&srv->rref);
-	incref(&srv->sref);
 	while(r = getreq(srv)){
 		incref(&srv->rref);
 		if(r->error){
@@ -753,14 +751,17 @@
 		}
 		qunlock(&srv->slock);
 	}
-	decref(&srv->sref);
-	srvclose(srv);
+
+	if(srv->end && srv->sref.ref == 1)
+		srv->end(srv);
+	if(decref(&srv->sref) == 0)
+		srvclose(srv);
 }
 
 static void
 srvclose(Srv *srv)
 {
-	if(decref(&srv->rref))
+	if(srv->rref.ref || srv->sref.ref)
 		return;
 
 	if(chatty9p)
@@ -776,8 +777,8 @@
 	freereqpool(srv->rpool);
 	srv->rpool = nil;
 
-	if(srv->end)
-		srv->end(srv);
+	if(srv->free)
+		srv->free(srv);
 }
 
 void
@@ -790,8 +791,10 @@
 void
 srvrelease(Srv *srv)
 {
-	if(decref(&srv->sref) == 0)
+	if(decref(&srv->sref) == 0){
+		incref(&srv->sref);
 		_forker(srvwork, srv, 0);
+	}
 	qunlock(&srv->slock);
 }
 
@@ -819,6 +822,7 @@
 	if(srv->start)
 		srv->start(srv);
 
+	incref(&srv->sref);
 	srvwork(srv);
 }
 
@@ -896,7 +900,8 @@
 	else
 		free(r);
 
-	srvclose(srv);
+	if(decref(&srv->rref) == 0)
+		srvclose(srv);
 }
 
 void
--