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.
This commit is contained in:
parent
013b498314
commit
f6509078ed
15 changed files with 201 additions and 125 deletions
|
@ -235,23 +235,29 @@ struct Srv {
|
|||
|
||||
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.
|
||||
*/
|
||||
|
@ -276,8 +282,6 @@ void authwrite(Req*);
|
|||
void authdestroy(Fid*);
|
||||
int authattach(Req*);
|
||||
|
||||
extern void (*_forker)(void (*)(void*), void*, int);
|
||||
|
||||
void srvacquire(Srv *);
|
||||
void srvrelease(Srv *);
|
||||
|
||||
|
|
53
sys/man/2/9p
53
sys/man/2/9p
|
@ -9,16 +9,21 @@ estrdup9p,
|
|||
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 @@ typedef struct Srv {
|
|||
int infd;
|
||||
int outfd;
|
||||
int srvfd;
|
||||
|
||||
void (*forker)(void (*fn)(void*), void *arg, int flags);
|
||||
} Srv;
|
||||
.fi
|
||||
.PP
|
||||
|
@ -66,12 +73,17 @@ typedef struct Srv {
|
|||
.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 @@ extern int chatty9p;
|
|||
.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 @@ but abort the program if they run out of memory.
|
|||
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 @@ are wrappers that create a separate process in which to run
|
|||
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 @@ If
|
|||
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 ,
|
||||
|
|
|
@ -11,7 +11,7 @@ static void srvfree(Srv *);
|
|||
static char *getremotesys(char*);
|
||||
|
||||
void
|
||||
_listensrv(Srv *os, char *addr)
|
||||
listensrv(Srv *os, char *addr)
|
||||
{
|
||||
Srv *s;
|
||||
|
||||
|
@ -33,9 +33,9 @@ _listensrv(Srv *os, char *addr)
|
|||
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 @@ listenproc(void *v)
|
|||
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);
|
||||
|
|
|
@ -7,17 +7,24 @@ OFILES=\
|
|||
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
|
||||
|
||||
|
|
19
sys/src/lib9p/mount.c
Normal file
19
sys/src/lib9p/mount.c
Normal file
|
@ -0,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);
|
||||
}
|
|
@ -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 @@ postsrv(Srv *s, char *name)
|
|||
} 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);
|
||||
|
@ -51,43 +49,3 @@ postsrv(Srv *s, char *name)
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
@ -17,24 +17,3 @@ rforker(void (*fn)(void*), void *arg, int flag)
|
|||
_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);
|
||||
}
|
||||
|
|
33
sys/src/lib9p/share.c
Normal file
33
sys/src/lib9p/share.c
Normal file
|
@ -0,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);
|
||||
}
|
|
@ -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 @@ srvrelease(Srv *srv)
|
|||
{
|
||||
if(decref(&srv->sref) == 0){
|
||||
incref(&srv->sref);
|
||||
_forker(srvwork, srv, 0);
|
||||
(*srv->forker)(srvwork, srv, 0);
|
||||
}
|
||||
qunlock(&srv->slock);
|
||||
}
|
||||
|
@ -843,6 +841,9 @@ srv(Srv *srv)
|
|||
if(srv->start)
|
||||
srv->start(srv);
|
||||
|
||||
if(srv->forker == nil)
|
||||
srv->forker = srvforker;
|
||||
|
||||
incref(&srv->sref);
|
||||
srvwork(srv);
|
||||
}
|
||||
|
|
|
@ -4,29 +4,8 @@
|
|||
#include <thread.h>
|
||||
#include <9p.h>
|
||||
|
||||
static void
|
||||
tforker(void (*fn)(void*), void *arg, int rflag)
|
||||
void
|
||||
threadsrvforker(void (*fn)(void*), void *arg, int rflag)
|
||||
{
|
||||
procrfork(fn, arg, 32*1024, rflag);
|
||||
}
|
||||
|
||||
void
|
||||
threadlistensrv(Srv *s, char *addr)
|
||||
{
|
||||
_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);
|
||||
}
|
||||
|
|
13
sys/src/lib9p/threadlistensrv.c
Normal file
13
sys/src/lib9p/threadlistensrv.c
Normal file
|
@ -0,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);
|
||||
}
|
13
sys/src/lib9p/threadpostmountsrv.c
Normal file
13
sys/src/lib9p/threadpostmountsrv.c
Normal file
|
@ -0,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);
|
||||
}
|
13
sys/src/lib9p/threadpostsharesrv.c
Normal file
13
sys/src/lib9p/threadpostsharesrv.c
Normal file
|
@ -0,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);
|
||||
}
|
13
sys/src/lib9p/threadpostsrv.c
Normal file
13
sys/src/lib9p/threadpostsrv.c
Normal file
|
@ -0,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);
|
||||
}
|
13
sys/src/lib9p/threadsrv.c
Normal file
13
sys/src/lib9p/threadsrv.c
Normal file
|
@ -0,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);
|
||||
}
|
Loading…
Reference in a new issue