Tweaks to various bits.

Until I hear otherwise, Refs aren't used enough to
merit their own assembly.  They are now implemented with locks.
This commit is contained in:
rsc 2003-12-17 04:34:52 +00:00
parent 7f11104a57
commit 49588d5d90
11 changed files with 166 additions and 90 deletions

View file

@ -352,8 +352,8 @@ connthread(void *arg)
m->afid->ref++; m->afid->ref++;
break; break;
case Topenfd: case Topenfd:
if(m->tx.mode != OREAD && (m->tx.mode&~OTRUNC) != OWRITE){ if(m->tx.mode&~(OTRUNC|3)){
err(m, "openfd mode must be OREAD or OWRITE"); err(m, "bad openfd mode");
continue; continue;
} }
m->isopenfd = 1; m->isopenfd = 1;
@ -489,13 +489,17 @@ openfdthread(void *v)
m->ref++; m->ref++;
sendomsg(m); sendomsg(m);
recvp(c->internal); recvp(c->internal);
if(m->rx.type == Rerror) if(m->rx.type == Rerror){
// fprint(2, "read error: %s\n", m->rx.ename);
break; break;
}
if(m->rx.count == 0) if(m->rx.count == 0)
break; break;
tot += m->rx.count; tot += m->rx.count;
if(iowrite(io, c->fd, m->rx.data, m->rx.count) != m->rx.count) if(iowrite(io, c->fd, m->rx.data, m->rx.count) != m->rx.count){
fprint(2, "pipe write error: %r\n");
break; break;
}
msgput(m); msgput(m);
msgput(m); msgput(m);
} }
@ -503,6 +507,8 @@ openfdthread(void *v)
for(;;){ for(;;){
if(verbose) fprint(2, "twrite..."); if(verbose) fprint(2, "twrite...");
if((n=ioread(io, c->fd, buf, sizeof buf)) <= 0){ if((n=ioread(io, c->fd, buf, sizeof buf)) <= 0){
if(n < 0)
fprint(2, "pipe read error: %r\n");
m = nil; m = nil;
break; break;
} }
@ -520,8 +526,10 @@ openfdthread(void *v)
m->ref++; m->ref++;
sendomsg(m); sendomsg(m);
recvp(c->internal); recvp(c->internal);
if(m->rx.type == Rerror) if(m->rx.type == Rerror){
break; // fprint(2, "write error: %s\n", m->rx.ename);
continue;
}
tot = n; tot = n;
msgput(m); msgput(m);
msgput(m); msgput(m);
@ -534,18 +542,20 @@ openfdthread(void *v)
msgput(m); msgput(m);
msgput(m); msgput(m);
} }
m = msgnew(); if(fid->ref == 1){
m->internal = 1; m = msgnew();
m->c = c; m->internal = 1;
m->tx.type = Tclunk; m->c = c;
m->tx.fid = fid->fid; m->tx.type = Tclunk;
m->fid = fid; m->tx.fid = fid->fid;
fid->ref++; m->fid = fid;
m->ref++; fid->ref++;
sendomsg(m); m->ref++;
recvp(c->internal); sendomsg(m);
msgput(m); recvp(c->internal);
msgput(m); msgput(m);
msgput(m);
}
fidput(fid); fidput(fid);
c->fdfid = nil; c->fdfid = nil;
chanfree(c->internal); chanfree(c->internal);
@ -578,13 +588,24 @@ xopenfd(Msg *m)
nc->fdmode = m->tx.mode; nc->fdmode = m->tx.mode;
nc->fd = p[0]; nc->fd = p[0];
/* clunk fid from other connection */
if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
fidput(m->fid);
/* a thread to tend the pipe */ /* a thread to tend the pipe */
threadcreate(openfdthread, nc, STACK); threadcreate(openfdthread, nc, STACK);
/* if mode is ORDWR, that openfdthread will write; start a reader */
if((m->tx.mode&3) == ORDWR){
nc = emalloc(sizeof(Conn));
nc->internal = chancreate(sizeof(void*), 0);
nc->fdfid = m->fid;
m->fid->ref++;
nc->fdmode = OREAD;
nc->fd = dup(p[0], -1);
threadcreate(openfdthread, nc, STACK);
}
/* steal fid from other connection */
if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
fidput(m->fid);
/* rewrite as Ropenfd */ /* rewrite as Ropenfd */
m->rx.type = Ropenfd; m->rx.type = Ropenfd;
n = GBIT32(m->rpkt); n = GBIT32(m->rpkt);
@ -1265,7 +1286,7 @@ iowrite(Ioproc *io, int fd, void *v, long n)
u = v; u = v;
for(tot=0; tot<n; tot+=m){ for(tot=0; tot<n; tot+=m){
m = _iowrite(io, fd, u+tot, n-tot); m = _iowrite(io, fd, u+tot, n-tot);
if(m <= 0){ if(m < 0){
if(tot) if(tot)
break; break;
return m; return m;

View file

@ -306,6 +306,7 @@ fsysattach(Xfid *x, Fid *f)
Fcall t; Fcall t;
int id; int id;
Mntdir *m; Mntdir *m;
char buf[128];
if(strcmp(x->fcall.uname, user) != 0) if(strcmp(x->fcall.uname, user) != 0)
return respond(x, &t, Eperm); return respond(x, &t, Eperm);
@ -327,8 +328,10 @@ fsysattach(Xfid *x, Fid *f)
m->ref++; m->ref++;
break; break;
} }
if(m == nil) if(m == nil){
sendp(cerr, estrdup("unknown id in attach")); snprint(buf, sizeof buf, "unknown id '%s' in attach", x->fcall.aname);
sendp(cerr, estrdup(buf));
}
qunlock(&mnt.lk); qunlock(&mnt.lk);
return respond(x, &t, nil); return respond(x, &t, nil);
} }

View file

@ -36,6 +36,6 @@ UPDATE=\
<$PLAN9/src/mkone <$PLAN9/src/mkone
LDFLAGS=$LDFLAGS -lfs -lmux -lplumb -lthread -lframe -ldraw -lbio -l9 -lfmt -lutf -L$X11/lib -lX11 LDFLAGS=$LDFLAGS -lplumb -lfs -lmux -lthread -lframe -ldraw -lbio -l9 -lfmt -lutf -L$X11/lib -lX11
edit.$O ecmd.$O elog.$O: edit.h edit.$O ecmd.$O elog.$O: edit.h

View file

@ -194,6 +194,7 @@ xfidclose(Xfid *x)
w = x->f->w; w = x->f->w;
x->f->busy = FALSE; x->f->busy = FALSE;
x->f->w = nil;
if(x->f->open == FALSE){ if(x->f->open == FALSE){
if(w != nil) if(w != nil)
winclose(w); winclose(w);

View file

@ -6,7 +6,7 @@ LDFLAGS=$LDFLAGS -lthread -lsec -lfs -lmux -lregexp9 -lbio -l9 -lfmt -lutf
<$PLAN9/src/mkmany <$PLAN9/src/mkmany
BUGGERED='CVS|oplumb|plumb2|mk|vac|9term|venti|htmlfmt' BUGGERED='CVS|faces|factotum|oplumb|plumb2|mk|vac|9term|upas|venti|htmlfmt'
DIRS=`ls -l |sed -n 's/^d.* //p' |egrep -v "$BUGGERED"` DIRS=`ls -l |sed -n 's/^d.* //p' |egrep -v "$BUGGERED"`
<$PLAN9/src/mkdirs <$PLAN9/src/mkdirs

View file

@ -7,33 +7,37 @@
extern char *_p9sigstr(int, char*); extern char *_p9sigstr(int, char*);
static int sigs[] = { static struct {
SIGHUP, int sig;
SIGINT, int restart;
SIGQUIT, } sigs[] = {
SIGILL, SIGHUP, 0,
SIGTRAP, SIGINT, 0,
SIGQUIT, 0,
SIGILL, 0,
SIGTRAP, 0,
/* SIGABRT, */ /* SIGABRT, */
#ifdef SIGEMT #ifdef SIGEMT
SIGEMT, SIGEMT, 0,
#endif #endif
SIGFPE, SIGFPE, 0,
SIGBUS, SIGBUS, 0,
/* SIGSEGV, */ /* SIGSEGV, */
SIGSYS, SIGCHLD, 1,
SIGPIPE, SIGSYS, 0,
SIGALRM, SIGPIPE, 0,
SIGTERM, SIGALRM, 0,
SIGTSTP, SIGTERM, 0,
SIGTTIN, SIGTSTP, 1,
SIGTTOU, SIGTTIN, 1,
SIGXCPU, SIGTTOU, 1,
SIGXFSZ, SIGXCPU, 0,
SIGVTALRM, SIGXFSZ, 0,
SIGUSR1, SIGVTALRM, 0,
SIGUSR2, SIGUSR1, 0,
SIGUSR2, 0,
#ifdef SIGINFO #ifdef SIGINFO
SIGINFO, SIGINFO, 0,
#endif #endif
}; };
@ -72,8 +76,13 @@ notify(void (*f)(void*, char*))
notifyf = f; notifyf = f;
sa.sa_handler = notifysigf; sa.sa_handler = notifysigf;
} }
for(i=0; i<nelem(sigs); i++) for(i=0; i<nelem(sigs); i++){
sigaction(sigs[i], &sa, 0); if(sigs[i].restart)
sa.sa_flags |= SA_RESTART;
else
sa.sa_flags &= ~SA_RESTART;
sigaction(sigs[i].sig, &sa, 0);
}
return 0; return 0;
} }

View file

@ -25,6 +25,7 @@ nsmount(char *name, char *aname)
werrstr("dial %s: %r", addr); werrstr("dial %s: %r", addr);
return nil; return nil;
} }
fcntl(fd, F_SETFL, FD_CLOEXEC);
fs = fsmount(fd, aname); fs = fsmount(fd, aname);
if(fs == nil){ if(fs == nil){

View file

@ -7,21 +7,68 @@
static char attrbuf[4096]; static char attrbuf[4096];
char *home; char *home;
static Fsys *fsplumb;
static int pfd = -1;
static Fid *pfid;
int int
plumbopen(char *name, int omode) plumbopen(char *name, int omode)
{ {
Fsys *fs;
int fd; int fd;
fs = nsmount("plumb", ""); if(fsplumb == nil)
if(fs == nil) fsplumb = nsmount("plumb", "");
if(fsplumb == nil)
return -1; return -1;
fd = fsopenfd(fs, name, omode); /*
fsunmount(fs); * It's important that when we send something,
* we find out whether it was a valid plumb write.
* (If it isn't, the client might fall back to some
* other mechanism or indicate to the user what happened.)
* We can't use a pipe for this, so we have to use the
* fid interface. But we need to return a fd.
* Return a fd for /dev/null so that we return a unique
* file descriptor. In plumbsend we'll look for pfd
* and use the recorded fid instead.
*/
if((omode&3) == OWRITE){
if(pfd != -1){
werrstr("already have plumb send open");
return -1;
}
pfd = open("/dev/null", OWRITE);
if(pfd < 0)
return -1;
pfid = fsopen(fsplumb, name, omode);
if(pfid == nil){
close(pfd);
pfd = -1;
return -1;
}
return pfd;
}
fd = fsopenfd(fsplumb, name, omode);
return fd; return fd;
} }
int
plumbsend(int fd, Plumbmsg *m)
{
char *buf;
int n;
if(fd != pfd){
werrstr("fd is not the plumber");
return -1;
}
buf = plumbpack(m, &n);
if(buf == nil)
return -1;
n = fswrite(pfid, buf, n);
free(buf);
return n;
}
static int static int
Strlen(char *s) Strlen(char *s)
{ {
@ -144,20 +191,6 @@ plumbpack(Plumbmsg *m, int *np)
return buf; return buf;
} }
int
plumbsend(int fd, Plumbmsg *m)
{
char *buf;
int n;
buf = plumbpack(m, &n);
if(buf == nil)
return -1;
n = write(fd, buf, n);
free(buf);
return n;
}
static int static int
plumbline(char **linep, char *buf, int i, int n, int *bad) plumbline(char **linep, char *buf, int i, int n, int *bad)
{ {

View file

@ -30,20 +30,20 @@ _gotolabel:
ret ret
.globl _xinc # .globl _xinc
_xinc: # _xinc:
movl 4(%esp), %eax # movl 4(%esp), %eax
lock incl 0(%eax) # lock incl 0(%eax)
ret # ret
#
.globl _xdec # .globl _xdec
_xdec: # _xdec:
movl 4(%esp), %eax # movl 4(%esp), %eax
lock decl 0(%eax) # lock decl 0(%eax)
jz iszero # jz iszero
movl $1, %eax # movl $1, %eax
ret # ret
iszero: # iszero:
movl $0, %eax # movl $0, %eax
ret # ret
#

View file

@ -122,6 +122,7 @@ efork(void *ve)
for(i=3; i<40; i++) for(i=3; i<40; i++)
if(i != e->fd[1]) if(i != e->fd[1])
close(i); close(i);
rfork(RFNOTEG);
execvp(e->prog, e->args); execvp(e->prog, e->args);
_threaddebug(DBGEXEC, "_schedexec failed: %r"); _threaddebug(DBGEXEC, "_schedexec failed: %r");
rerrstr(buf, sizeof buf); rerrstr(buf, sizeof buf);

View file

@ -3,11 +3,18 @@
void void
incref(Ref *r) incref(Ref *r)
{ {
_xinc(&r->ref); lock(&r->lk);
r->ref++;
unlock(&r->lk);
} }
long long
decref(Ref *r) decref(Ref *r)
{ {
return _xdec(&r->ref); long n;
lock(&r->lk);
n = --r->ref;
unlock(&r->lk);
return n;
} }