code: plan9front

Download patch

ref: f6509078ed9d03b71c945b19cdda5c882cb1e78d
parent: 013b4983140cc2fbb7df9e3647e2e7c5d575a9dd
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat May 1 12:37:00 EDT 2021

lib9p: expose Srv.forker handler and srvforker(), threadsrvforker() and threadsrv() functions

To use srvrease()/srvaquire() we need to have a way to spawn
new processes to handle the service loop. This functionality
was provided by the internal _forker() function which was
eigther rfork or libthread based implementation depending on
if postmountsrv() or threadpostmountsrv() where called.

For servers who want to use srv() directly, _forker would not
be initialized so srvrelease() could not be used.

To untangle this, we get rid of the global _forker handler
and put the handler in the Srv structure. Which will get
initialized (when nil) to eigther srvforker() or threadsrvforker()
depending on if the thread or non-thread entry points where used.

For symmetry, we provde new threadsrv() and threadpostsrv()
functions which handle the default initialization of Srv.forker.

This also allows a user to provide his own forker function,
maybe to conserve stack space.

To avoid dead code, we put each of these function in their
own object file. Note, this also allows a user to define its
own srvforker() symbol.

--- a/sys/include/9p.h
+++ b/sys/include/9p.h
@@ -235,23 +235,29 @@
 
 	int	spid;	/* pid of srv() caller */
 
+	void	(*forker)(void (*)(void*), void*, int);
 	void	(*free)(Srv*);
 };
 
+void		srvforker(void (*)(void*), void*, int);
+void		threadsrvforker(void (*)(void*), void*, int);
+
 void		srv(Srv*);
+void		postsrv(Srv*, char*);
 void		postmountsrv(Srv*, char*, char*, int);
-void		_postmountsrv(Srv*, char*, char*, int);
 void		postsharesrv(Srv*, char*, char*, char*);
-void		_postsharesrv(Srv*, char*, char*, char*);
 void		listensrv(Srv*, char*);
-void		_listensrv(Srv*, char*);
-int		chatty9p;
-void		respond(Req*, char*);
-void		responderror(Req*);
+
+void		threadsrv(Srv*);
+void		threadpostsrv(Srv*, char*);
 void		threadpostmountsrv(Srv*, char*, char*, int);
 void		threadpostsharesrv(Srv*, char*, char*, char*);
 void		threadlistensrv(Srv *s, char *addr);
 
+int		chatty9p;
+void		respond(Req*, char*);
+void		responderror(Req*);
+
 /*
  * Helper.  Assumes user is same as group.
  */
@@ -275,8 +281,6 @@
 void		authwrite(Req*);
 void		authdestroy(Fid*);
 int		authattach(Req*);
-
-extern void (*_forker)(void (*)(void*), void*, int);
 
 void		srvacquire(Srv *);
 void		srvrelease(Srv *);
--- a/sys/man/2/9p
+++ b/sys/man/2/9p
@@ -9,16 +9,21 @@
 listensrv,
 postmountsrv,
 postsharesrv,
+postsrv,
 readbuf,
 readstr,
 respond,
 responderror,
+srv
 srvacquire,
+srvforker,
 srvrelease,
 threadlistensrv,
 threadpostmountsrv,
 threadpostsharesrv,
-srv \- 9P file service
+threadpostsrv,
+threadsrv,
+threadsrvforker - 9P file service
 .SH SYNOPSIS
 .ft L
 .nf
@@ -59,6 +64,8 @@
 	int		infd;
 	int		outfd;
 	int		srvfd;
+
+	void		(*forker)(void (*fn)(void*), void *arg, int flags);
 } Srv;
 .fi
 .PP
@@ -66,12 +73,17 @@
 .ft L
 .ta \w'\fLvoid* 'u
 void	srv(Srv *s)
+void	postsrv(Srv *s, char *name);
 void	postmountsrv(Srv *s, char *name, char *mtpt, int flag)
 void	postsharesrv(Srv *s, char *name, char *mtpt, char *desc)
+void	listensrv(Srv *s, char *addr)
+void	threadsrv(Srv *s)
+void	threadpostsrv(Srv *s, char *name);
 void	threadpostmountsrv(Srv *s, char *name, char *mtpt, int flag)
 void	threadpostsharesrv(Srv *s, char *name, char *mtpt, char *desc)
-void	listensrv(Srv *s, char *addr)
 void	threadlistensrv(Srv *s, char *addr)
+void	srvforker(void (*fn)(void*), void *arg, int flags)
+void	threadsrvforker(void (*fn)(void*), void *arg, int flags)
 void	respond(Req *r, char *error)
 void	responderror(Req*)
 void	readstr(Req *r, char *src)
@@ -106,7 +118,9 @@
 .SH DESCRIPTION
 The function
 .I srv
-serves a 9P session by reading requests from
+and
+.I threadsrv
+serve a 9P session by reading requests from
 .BR s->infd ,
 dispatching them to the function pointers kept in 
 .BR Srv ,
@@ -166,6 +180,19 @@
 If alternate behavior is desired, clients can link against
 alternate implementations of these functions.
 .PP
+The functions
+.I srvforker
+and
+.I threadsrvforker
+handle the creation of new processes on a connection which use
+.I rfork
+(see
+.IR fork (2))
+or
+.I procrfork
+(see
+.IR thread (2)).
+.PP
 .I Postmountsrv
 and
 .I threadpostmountsrv
@@ -174,6 +201,14 @@
 They do the following:
 .IP
 Initialize
+.IB s -> forker
+to eigther
+.I srvforker
+or
+.I threadsrvforker
+unless already initialized to a non-nil value.
+.IP
+Initialize
 .IB s -> infd
 and
 .IB s -> outfd
@@ -187,16 +222,12 @@
 is non-nil, post the file descriptor
 .IB s -> srvfd
 under the name
-.BI /srv/ name .
+.BI /srv/ name
+using a call to
+.IR postsrv .
 .IP
 Fork a child process via
-.I rfork
-(see
-.IR fork (2))
-or
-.I procrfork
-(see
-.IR thread (2)),
+.IB s -> forker
 using the
 .BR RFPROC ,
 .BR RFNOWAIT ,
--- a/sys/src/lib9p/listen.c
+++ b/sys/src/lib9p/listen.c
@@ -11,7 +11,7 @@
 static char *getremotesys(char*);
 
 void
-_listensrv(Srv *os, char *addr)
+listensrv(Srv *os, char *addr)
 {
 	Srv *s;
 
@@ -33,9 +33,9 @@
 	s->spid = 0;
 	s->free = nil;
 
-	if(_forker == nil)
-		sysfatal("no forker");
-	_forker(listenproc, s, 0);
+	if(s->forker == nil)
+		s->forker = srvforker;
+	(*s->forker)(listenproc, s, 0);
 }
 
 static void
@@ -72,7 +72,7 @@
 		s->addr = getremotesys(ndir);
 		s->infd = s->outfd = data;
 		s->free = srvfree;
-		_forker(srvproc, s, 0);
+		(*s->forker)(srvproc, s, 0);
 	}
 	free(os->addr);
 	free(os);
--- a/sys/src/lib9p/mkfile
+++ b/sys/src/lib9p/mkfile
@@ -7,17 +7,24 @@
 	fid.$O\
 	file.$O\
 	intmap.$O\
-	listen.$O\
 	mem.$O\
 	req.$O\
 	parse.$O\
-	post.$O\
 	queue.$O\
-	rfork.$O\
-	srv.$O\
-	thread.$O\
 	uid.$O\
 	util.$O\
+	srv.$O\
+	post.$O\
+	mount.$O\
+	share.$O\
+	listen.$O\
+	rfork.$O\
+	thread.$O\
+	threadsrv.$O\
+	threadpostsrv.$O\
+	threadpostmountsrv.$O\
+	threadpostsharesrv.$O\
+	threadlistensrv.$O\
 
 HFILES=/sys/include/9p.h
 
--- /dev/null
+++ b/sys/src/lib9p/mount.c
@@ -1,0 +1,19 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+#include <auth.h>
+
+void
+postmountsrv(Srv *s, char *name, char *mtpt, int flag)
+{
+	postsrv(s, name);
+
+	if(mtpt != nil){
+		if(amount(s->srvfd, mtpt, flag, "") == -1)
+			sysfatal("mount %s: %r", mtpt);
+		/* mount closed s->srvfd */
+	} else
+		close(s->srvfd);
+}
--- a/sys/src/lib9p/post.c
+++ b/sys/src/lib9p/post.c
@@ -8,15 +8,13 @@
 static void
 postproc(void *v)
 {
-	Srv *s;
-
-	s = v;
+	Srv *s = v;
 	rendezvous(0, 0);
 	close(s->srvfd);
 	srv(s);
 }
 
-static void
+void
 postsrv(Srv *s, char *name)
 {
 	char buf[80];
@@ -37,9 +35,9 @@
 	} else
 		cfd = -1;
 
-	if(_forker == nil)
-		sysfatal("no forker");
-	_forker(postproc, s, RFNAMEG|RFNOTEG);
+	if(s->forker == nil)
+		s->forker = srvforker;
+	(*s->forker)(postproc, s, RFNAMEG|RFNOTEG);
 
 	rfork(RFFDG);
 	rendezvous(0, 0);
@@ -50,44 +48,4 @@
 
 	if(cfd >= 0)
 		close(cfd);
-}
-
-void
-_postmountsrv(Srv *s, char *name, char *mtpt, int flag)
-{
-	postsrv(s, name);
-
-	if(mtpt != nil){
-		if(amount(s->srvfd, mtpt, flag, "") == -1)
-			sysfatal("mount %s: %r", mtpt);
-		/* mount closed s->srvfd */
-	} else
-		close(s->srvfd);
-}
-
-void
-_postsharesrv(Srv *s, char *name, char *mtpt, char *desc)
-{
-	char buf[80];
-	int cfd;
-
-	if(mtpt != nil && desc != nil){
-		snprint(buf, sizeof buf, "#σc/%s", mtpt);
-		if((cfd = create(buf, OREAD, DMDIR|0700)) >= 0)
-			close(cfd);
-
-		snprint(buf, sizeof buf, "#σc/%s/%s", mtpt, desc);
-		if((cfd = create(buf, OWRITE|ORCLOSE|OCEXEC, 0600)) < 0)
-			sysfatal("create %s: %r", buf);
-	} else
-		cfd = -1;
-
-	postsrv(s, name);
-
-	if(cfd >= 0){
-		if(fprint(cfd, "%d\n", s->srvfd) < 0)
-			sysfatal("write %s: %r", buf);
-		close(cfd);
-	}
-	close(s->srvfd);
 }
--- a/sys/src/lib9p/rfork.c
+++ b/sys/src/lib9p/rfork.c
@@ -4,8 +4,8 @@
 #include <thread.h>
 #include <9p.h>
 
-static void
-rforker(void (*fn)(void*), void *arg, int flag)
+void
+srvforker(void (*fn)(void*), void *arg, int flag)
 {
 	switch(rfork(RFPROC|RFMEM|RFNOWAIT|flag)){
 	case -1:
@@ -16,25 +16,4 @@
 		fn(arg);
 		_exits(0);
 	}
-}
-
-void
-listensrv(Srv *s, char *addr)
-{
-	_forker = rforker;
-	_listensrv(s, addr);
-}
-
-void
-postmountsrv(Srv *s, char *name, char *mtpt, int flag)
-{
-	_forker = rforker;
-	_postmountsrv(s, name, mtpt, flag);
-}
-
-void
-postsharesrv(Srv *s, char *name, char *mtpt, char *desc)
-{
-	_forker = rforker;
-	_postsharesrv(s, name, mtpt, desc);
 }
--- /dev/null
+++ b/sys/src/lib9p/share.c
@@ -1,0 +1,33 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+#include <auth.h>
+
+void
+postsharesrv(Srv *s, char *name, char *mtpt, char *desc)
+{
+	char buf[80];
+	int cfd;
+
+	if(mtpt != nil && desc != nil){
+		snprint(buf, sizeof buf, "#σc/%s", mtpt);
+		if((cfd = create(buf, OREAD, DMDIR|0700)) >= 0)
+			close(cfd);
+
+		snprint(buf, sizeof buf, "#σc/%s/%s", mtpt, desc);
+		if((cfd = create(buf, OWRITE|ORCLOSE|OCEXEC, 0600)) < 0)
+			sysfatal("create %s: %r", buf);
+	} else
+		cfd = -1;
+
+	postsrv(s, name);
+
+	if(cfd >= 0){
+		if(fprint(cfd, "%d\n", s->srvfd) < 0)
+			sysfatal("write %s: %r", buf);
+		close(cfd);
+	}
+	close(s->srvfd);
+}
--- a/sys/src/lib9p/srv.c
+++ b/sys/src/lib9p/srv.c
@@ -5,8 +5,6 @@
 #include <thread.h>
 #include <9p.h>
 
-void (*_forker)(void(*)(void*), void*, int);
-
 static char Ebadattach[] = "unknown specifier in attach";
 static char Ebadoffset[] = "bad offset";
 static char Ebadcount[] = "bad count";
@@ -813,7 +811,7 @@
 {
 	if(decref(&srv->sref) == 0){
 		incref(&srv->sref);
-		_forker(srvwork, srv, 0);
+		(*srv->forker)(srvwork, srv, 0);
 	}
 	qunlock(&srv->slock);
 }
@@ -842,6 +840,9 @@
 
 	if(srv->start)
 		srv->start(srv);
+
+	if(srv->forker == nil)
+		srv->forker = srvforker;
 
 	incref(&srv->sref);
 	srvwork(srv);
--- a/sys/src/lib9p/thread.c
+++ b/sys/src/lib9p/thread.c
@@ -4,29 +4,8 @@
 #include <thread.h>
 #include <9p.h>
 
-static void
-tforker(void (*fn)(void*), void *arg, int rflag)
-{
-	procrfork(fn, arg, 32*1024, rflag);
-}
-
 void
-threadlistensrv(Srv *s, char *addr)
+threadsrvforker(void (*fn)(void*), void *arg, int rflag)
 {
-	_forker = tforker;
-	_listensrv(s, addr);
-}
-
-void
-threadpostmountsrv(Srv *s, char *name, char *mtpt, int flag)
-{
-	_forker = tforker;
-	_postmountsrv(s, name, mtpt, flag);
-}
-
-void
-threadpostsharesrv(Srv *s, char *name, char *mtpt, char *desc)
-{
-	_forker = tforker;
-	_postsharesrv(s, name, mtpt, desc);
+	procrfork(fn, arg, 32*1024, rflag);
 }
--- /dev/null
+++ b/sys/src/lib9p/threadlistensrv.c
@@ -1,0 +1,13 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+
+void
+threadlistensrv(Srv *s, char *addr)
+{
+	if(s->forker == nil)
+		s->forker = threadsrvforker;
+	listensrv(s, addr);
+}
--- /dev/null
+++ b/sys/src/lib9p/threadpostmountsrv.c
@@ -1,0 +1,13 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+
+void
+threadpostmountsrv(Srv *s, char *name, char *mtpt, int flag)
+{
+	if(s->forker == nil)
+		s->forker = threadsrvforker;
+	postmountsrv(s, name, mtpt, flag);
+}
--- /dev/null
+++ b/sys/src/lib9p/threadpostsharesrv.c
@@ -1,0 +1,13 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+
+void
+threadpostsharesrv(Srv *s, char *name, char *mtpt, char *desc)
+{
+	if(s->forker == nil)
+		s->forker = threadsrvforker;
+	postsharesrv(s, name, mtpt, desc);
+}
--- /dev/null
+++ b/sys/src/lib9p/threadpostsrv.c
@@ -1,0 +1,13 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+
+void
+threadpostsrv(Srv *s, char *name)
+{
+	if(s->forker == nil)
+		s->forker = threadsrvforker;
+	postsrv(s, name);
+}
--- /dev/null
+++ b/sys/src/lib9p/threadsrv.c
@@ -1,0 +1,13 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+
+void
+threadsrv(Srv *s)
+{
+	if(s->forker == nil)
+		s->forker = threadsrvforker;
+	srv(s);
+}