Hsize= 1999,
};
-
char *mntpt;
char user[Elemlen];
int Dflag;
int plumbing = 1;
ulong cachetarg = Maxcache;
Mailbox *mbl;
-QLock mbllock;
static int messagesize = 8*1024 + IOHDRSZ;
static int mfd[2];
static Fcall rhdr;
static Fcall thdr;
static Fid *fids;
+static QLock synclock;
void
sanemsg(Message *m)
nf->busy = 1;
nf->open = 0;
nf->mb = f->mb;
- if(nf->mb){
- qlock(nf->mb);
+ if(nf->mb)
mboxincref(nf->mb);
- }
if(nf->m = f->m)
msgincref(gettopmsg(nf->mb, nf->m));
if(nf->mtop = f->mtop)
msgincref(nf->mtop);
nf->qid = f->qid;
- if(nf->mb)
- qunlock(nf->mb);
return nf;
}
t = FILE(f->qid.path);
rv = Enotexist;
- qlock(&mbllock);
- if(f->mb)
- qlock(f->mb);
-
/* this must catch everything except . and .. */
retry:
t1 = FILE(f->qid.path);
if(h != nil){
if(f->m)
msgdecref(f->mb, gettopmsg(f->mb, f->m));
- if(f->mb && f->mb != h->mb){
- qunlock(f->mb);
+ if(f->mb && f->mb != h->mb)
mboxdecref(f->mb);
- }
- if(h->mb && h->mb != f->mb)
- qlock(h->mb);
f->mb = h->mb;
f->m = h->m;
if(f->m)
goto retry;
}
- if(f->mb)
- qunlock(f->mb);
- qunlock(&mbllock);
-
if(rv == nil)
return rv;
f->qid.vers = 0;
mb = f->mb;
f->mb = nil;
- qlock(&mbllock);
mboxdecref(mb);
- qunlock(&mbllock);
break;
case Qdir:
- qlock(f->mb);
if(Topmsg(f->mb, f->m)){
f->qid.path = PATH(f->mb->id, Qmbox);
f->qid.type = QTDIR;
f->qid.path = PATH(f->m->id, Qdir);
f->qid.type = QTDIR;
}
- qunlock(f->mb);
break;
}
rv = nil;
/* make sure we've decoded */
if(file == Qbody){
- qlock(f->mb);
cachebody(f->mb, f->m);
decode(f->m);
convert(f->m);
putcache(f->mb, f->m);
- qunlock(f->mb);
}
rhdr.iounit = 0;
long pos;
Mailbox *mb;
- qlock(&mbllock);
-
n = 0;
pos = 0;
mkstat(&d, nil, nil, Qctl);
m = convD2M(&d, &buf[n], blen);
if(off <= pos){
if(m <= BIT16SZ || m > cnt)
- goto out;
+ return n;
n += m;
cnt -= m;
}
pos += m;
for(mb = mbl; mb != nil; mb = mb->next){
- qlock(mb);
mkstat(&d, mb, nil, Qmbox);
- qunlock(mb);
m = convD2M(&d, &buf[n], blen - n);
if(off <= pos){
if(m <= BIT16SZ || m > cnt)
}
pos += m;
}
-out:
- qlock(&mbllock);
return n;
}
long pos;
Message *msg;
- qlock(f->mb);
if(off == 0)
syncmbox(f->mb, 1);
if(off == 0){
if(m <= BIT16SZ || m > cnt){
f->fptr = nil;
- goto out;
+ return n;
}
n += m;
cnt -= m;
f->foff = pos;
f->fptr = msg;
f->fvers = f->mb->vers;
-out:
- qunlock(f->mb);
return n;
}
long pos;
Message *msg;
- qlock(f->mb);
n = 0;
pos = 0;
for(i = 0; i < Qmax; i++){
m = convD2M(&d, &buf[n], blen - n);
if(off <= pos){
if(m <= BIT16SZ || m > cnt)
- goto out;
+ return n;
n += m;
cnt -= m;
}
}
pos += m;
}
-out:
- qunlock(f->mb);
return n;
}
return nil;
}
- qlock(f->mb);
switch(t){
case Qctl:
rhdr.count = 0;
}
break;
}
- qunlock(f->mb);
return nil;
}
argc = tokenize(thdr.data, argv, nelem(argvbuf));
if(argc == 0)
return Ebadctl;
- qlock(f->mb);
- err = f->mb->ctl(f->mb, argc, argv);
- qunlock(f->mb);
- return err;
+ return f->mb->ctl(f->mb, argc, argv);
}
break;
case Qflags:
*/
if(!f->mb || !f->m)
break;
- qlock(f->mb);
m = gettopmsg(f->mb, f->m);
- err = modflags(f->mb, m, thdr.data);
- qunlock(f->mb);
- return err;
+ return modflags(f->mb, m, thdr.data);
}
return Eperm;
}
f->fid = -1;
f->open = 0;
mb = f->mb;
- if(mb)
- qlock(mb);
if(f->mtop)
msgdecref(mb, f->mtop);
if(f->m)
f->m = f->mtop = nil;
if(mb){
f->mb = nil;
- qunlock(mb);
- qlock(&mbllock);
mboxdecref(mb);
- qunlock(&mbllock);
}
f->busy = 0;
return 0;
rremove(Fid *f)
{
if(f->m != nil){
- qlock(f->mb);
if(!f->m->deleted)
mailplumb(f->mb, f->m, 1);
f->m->deleted = Deleted;
- qunlock(f->mb);
}
return rclunk(f);
}
{
Dir d;
- if(f->mb)
- qlock(f->mb);
if(FILE(f->qid.path) == Qmbox)
syncmbox(f->mb, 1);
mkstat(&d, f->mb, f->m, FILE(f->qid.path));
rhdr.nstat = convD2M(&d, mbuf, messagesize - IOHDRSZ);
rhdr.stat = mbuf;
- if(f->mb)
- qunlock(f->mb);
return 0;
}
if(Dflag)
fprint(2, "%s:<-%F\n", argv0, &thdr);
+ qlock(&synclock);
rhdr.data = (char*)mdata + messagesize;
if(!fcalls[thdr.type])
err = "bad fcall type";
rhdr.fid = thdr.fid;
}
rhdr.tag = thdr.tag;
+ qunlock(&synclock);
+
if(Dflag)
fprint(2, "%s:->%F\n", argv0, &rhdr);
n = convS2M(&rhdr, mdata, messagesize);
setname(readerargv);
sleep(15*1000);
for(;;){
+ qlock(&synclock);
t = time(0);
- qlock(&mbllock);
for(mb = mbl; mb != nil; mb = mb->next){
- if(!canqlock(mb))
- continue;
if(mb->waketime != 0 && t >= mb->waketime){
mb->waketime = 0;
break;
free(d);
}
}
- qunlock(mb);
}
- qunlock(&mbllock);
- if(mb != nil){
+ if(mb != nil) {
syncmbox(mb, 1);
- qunlock(mb);
- } else
+ qunlock(&synclock);
+ } else {
+ qunlock(&synclock);
sleep(15*1000);
+ }
}
}
return to - buf;
}
-QLock hashlock;
-
uint
hash(ulong ppath, char *name)
{
int h;
Hash *hp;
- qlock(&hashlock);
h = hash(ppath, name);
for(hp = htab[h]; hp != nil; hp = hp->next)
- if(ppath == hp->ppath && strcmp(name, hp->name) == 0){
- qunlock(&hashlock);
+ if(ppath == hp->ppath && strcmp(name, hp->name) == 0)
return hp;
- }
- qunlock(&hashlock);
return nil;
}
int h;
Hash *hp, **l;
- qlock(&hashlock);
h = hash(ppath, name);
for(l = &htab[h]; *l != nil; l = &(*l)->next){
hp = *l;
hp->m = m;
hp->mb = mb;
hp->qid = qid;
- qunlock(&hashlock);
return;
}
}
-
*l = hp = emalloc(sizeof(*hp));
hp->m = m;
hp->mb = mb;
hp->qid = qid;
hp->name = name;
hp->ppath = ppath;
- qunlock(&hashlock);
}
void
int h;
Hash *hp, **l;
- qlock(&hashlock);
h = hash(ppath, name);
for(l = &htab[h]; *l != nil; l = &(*l)->next){
hp = *l;
break;
}
}
- qunlock(&hashlock);
}
void
int n, d, y, a;
Message *m, *next;
- assert(!canqlock(mb));
a = mb->root->subname;
if(rdidxfile(mb, doplumb) == -2)
wridxfile(mb);
henter(PATH(0, Qtop), mb->name,
(Qid){PATH(mb->id, Qmbox), mb->vers, QTDIR}, nil, mb);
done:
- if(mb == nil)
- return err;
- qunlock(mb);
return err;
}
}
/* make sure name isn't taken */
- qlock(&mbllock);
for(l = &mbl; *l != nil; l = &(*l)->next)
if(strcmp((*l)->name, mb->name) == 0){
if(strcmp(path, (*l)->path) == 0)
if(mb->close)
mb->close(mb);
free(mb);
- qunlock(&mbllock);
return rv;
}
mb->mtree = avlcreate(mtreecmp);
*l = mb;
- qunlock(&mbllock);
- qlock(mb);
henter(PATH(0, Qtop), mb->name,
(Qid){PATH(mb->id, Qmbox), mb->vers, QTDIR}, nil, mb);
if(mb->ctl)
rv = syncmbox(mb, 0);
if(r)
*r = mb;
- else
- qunlock(mb);
return rv;
}
{
Mailbox **l, *mb;
- qlock(&mbllock);
for(l=&mbl; *l != nil; l=&(*l)->next)
if(strcmp(name, (*l)->name) == 0){
mb = *l;
break;
}
hfree(PATH(0, Qtop), name);
- qunlock(&mbllock);
}
void
char *err;
Mailbox *m;
- qlock(&mbllock);
- for(m = mbl; m != nil; m = m->next){
- qlock(m);
+ for(m = mbl; m != nil; m = m->next)
if(err = syncmbox(m, 1))
eprint("syncmbox: %s\n", err);
- qunlock(m);
- }
- qunlock(&mbllock);
}
Mailbox **l, *mb;
found = 0;
- qlock(&mbllock);
for(l=&mbl; *l != nil; l=&(*l)->next)
if(strcmp(name, (*l)->path) == 0){
mb = *l;
break;
}
hfree(PATH(0, Qtop), name);
- qunlock(&mbllock);
if(found == 0)
return "maibox not found";
Mailbox *mb;
Message *m;
- qlock(&mbllock);
for(mb = mbl; mb != nil; mb = mb->next)
- if(strcmp(av[0], mb->name) == 0){
- qlock(mb);
+ if(strcmp(av[0], mb->name) == 0)
break;
- }
- qunlock(&mbllock);
if(mb == nil)
return "no such mailbox";
}
if(needwrite)
syncmbox(mb, 1);
- qunlock(mb);
return 0;
}
if(argc%2)
return "bad flags";
- qlock(&mbllock);
for(mb = mbl; mb; mb = mb->next)
- if(strcmp(*argv, mb->name) == 0){
- qlock(mb);
+ if(strcmp(*argv, mb->name) == 0)
break;
- }
- qunlock(&mbllock);
if(mb == nil)
return "no such mailbox";
needwrite = 0;
}
if(needwrite)
syncmbox(mb, 1);
- qunlock(mb);
return rerr;
}
-/*
- * the following are called with the mailbox qlocked
- */
void
msgincref(Message *m)
{
void
msgdecref(Mailbox *mb, Message *m)
{
- assert(!canqlock(mb));
assert(m->refs > 0);
m->refs--;
if(m->refs == 0){
}
}
-/*
- * the following are called with mbllock'd
- */
void
mboxincref(Mailbox *mb)
{
void
mboxdecref(Mailbox *mb)
{
- qlock(mb);
assert(mb->refs > 0);
mb->refs--;
if(mb->refs == 0){
free(mb->mtree);
free(mb->d);
free(mb);
- } else
- qunlock(mb);
+ }
}