summaryrefslogtreecommitdiff
path: root/sys/src/cmd/fossil/9proc.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@localhost>2011-04-18 06:35:33 +0000
committercinap_lenrek <cinap_lenrek@localhost>2011-04-18 06:35:33 +0000
commitad5522be0fbfcad7b47bb9baca9a44dadb4b6461 (patch)
tree4e5622e0b5d1d0037406ac345d2a91e2c11e1bfc /sys/src/cmd/fossil/9proc.c
parenta455c61024cab80bfc50c898d8686068cd8ea06a (diff)
remove fossil
Diffstat (limited to 'sys/src/cmd/fossil/9proc.c')
-rw-r--r--sys/src/cmd/fossil/9proc.c825
1 files changed, 0 insertions, 825 deletions
diff --git a/sys/src/cmd/fossil/9proc.c b/sys/src/cmd/fossil/9proc.c
deleted file mode 100644
index bddd3baa1..000000000
--- a/sys/src/cmd/fossil/9proc.c
+++ /dev/null
@@ -1,825 +0,0 @@
-#include "stdinc.h"
-
-#include "9.h"
-#include "dat.h"
-#include "fns.h"
-
-enum {
- NConInit = 128,
- NMsgInit = 384,
- NMsgProcInit = 64,
- NMsizeInit = 8192+IOHDRSZ,
-};
-
-static struct {
- VtLock* alock; /* alloc */
- Msg* ahead;
- VtRendez* arendez;
-
- int maxmsg;
- int nmsg;
- int nmsgstarve;
-
- VtLock* rlock; /* read */
- Msg* rhead;
- Msg* rtail;
- VtRendez* rrendez;
-
- int maxproc;
- int nproc;
- int nprocstarve;
-
- u32int msize; /* immutable */
-} mbox;
-
-static struct {
- VtLock* alock; /* alloc */
- Con* ahead;
- VtRendez* arendez;
-
- VtLock* clock;
- Con* chead;
- Con* ctail;
-
- int maxcon;
- int ncon;
- int nconstarve;
-
- u32int msize;
-} cbox;
-
-static void
-conFree(Con* con)
-{
- assert(con->version == nil);
- assert(con->mhead == nil);
- assert(con->whead == nil);
- assert(con->nfid == 0);
- assert(con->state == ConMoribund);
-
- if(con->fd >= 0){
- close(con->fd);
- con->fd = -1;
- }
- con->state = ConDead;
- con->aok = 0;
- con->flags = 0;
- con->isconsole = 0;
-
- vtLock(cbox.alock);
- if(con->cprev != nil)
- con->cprev->cnext = con->cnext;
- else
- cbox.chead = con->cnext;
- if(con->cnext != nil)
- con->cnext->cprev = con->cprev;
- else
- cbox.ctail = con->cprev;
- con->cprev = con->cnext = nil;
-
- if(cbox.ncon > cbox.maxcon){
- if(con->name != nil)
- vtMemFree(con->name);
- vtLockFree(con->fidlock);
- vtMemFree(con->data);
- vtRendezFree(con->wrendez);
- vtLockFree(con->wlock);
- vtRendezFree(con->mrendez);
- vtLockFree(con->mlock);
- vtRendezFree(con->rendez);
- vtLockFree(con->lock);
- vtMemFree(con);
- cbox.ncon--;
- vtUnlock(cbox.alock);
- return;
- }
- con->anext = cbox.ahead;
- cbox.ahead = con;
- if(con->anext == nil)
- vtWakeup(cbox.arendez);
- vtUnlock(cbox.alock);
-}
-
-static void
-msgFree(Msg* m)
-{
- assert(m->rwnext == nil);
- assert(m->flush == nil);
-
- vtLock(mbox.alock);
- if(mbox.nmsg > mbox.maxmsg){
- vtMemFree(m->data);
- vtMemFree(m);
- mbox.nmsg--;
- vtUnlock(mbox.alock);
- return;
- }
- m->anext = mbox.ahead;
- mbox.ahead = m;
- if(m->anext == nil)
- vtWakeup(mbox.arendez);
- vtUnlock(mbox.alock);
-}
-
-static Msg*
-msgAlloc(Con* con)
-{
- Msg *m;
-
- vtLock(mbox.alock);
- while(mbox.ahead == nil){
- if(mbox.nmsg >= mbox.maxmsg){
- mbox.nmsgstarve++;
- vtSleep(mbox.arendez);
- continue;
- }
- m = vtMemAllocZ(sizeof(Msg));
- m->data = vtMemAlloc(mbox.msize);
- m->msize = mbox.msize;
- mbox.nmsg++;
- mbox.ahead = m;
- break;
- }
- m = mbox.ahead;
- mbox.ahead = m->anext;
- m->anext = nil;
- vtUnlock(mbox.alock);
-
- m->con = con;
- m->state = MsgR;
- m->nowq = 0;
-
- return m;
-}
-
-static void
-msgMunlink(Msg* m)
-{
- Con *con;
-
- con = m->con;
-
- if(m->mprev != nil)
- m->mprev->mnext = m->mnext;
- else
- con->mhead = m->mnext;
- if(m->mnext != nil)
- m->mnext->mprev = m->mprev;
- else
- con->mtail = m->mprev;
- m->mprev = m->mnext = nil;
-}
-
-void
-msgFlush(Msg* m)
-{
- Con *con;
- Msg *flush, *old;
-
- con = m->con;
-
- if(Dflag)
- fprint(2, "msgFlush %F\n", &m->t);
-
- /*
- * If this Tflush has been flushed, nothing to do.
- * Look for the message to be flushed in the
- * queue of all messages still on this connection.
- * If it's not found must assume Elvis has already
- * left the building and reply normally.
- */
- vtLock(con->mlock);
- if(m->state == MsgF){
- vtUnlock(con->mlock);
- return;
- }
- for(old = con->mhead; old != nil; old = old->mnext)
- if(old->t.tag == m->t.oldtag)
- break;
- if(old == nil){
- if(Dflag)
- fprint(2, "msgFlush: cannot find %d\n", m->t.oldtag);
- vtUnlock(con->mlock);
- return;
- }
-
- if(Dflag)
- fprint(2, "\tmsgFlush found %F\n", &old->t);
-
- /*
- * Found it.
- * There are two cases where the old message can be
- * truly flushed and no reply to the original message given.
- * The first is when the old message is in MsgR state; no
- * processing has been done yet and it is still on the read
- * queue. The second is if old is a Tflush, which doesn't
- * affect the server state. In both cases, put the old
- * message into MsgF state and let MsgWrite toss it after
- * pulling it off the queue.
- */
- if(old->state == MsgR || old->t.type == Tflush){
- old->state = MsgF;
- if(Dflag)
- fprint(2, "msgFlush: change %d from MsgR to MsgF\n",
- m->t.oldtag);
- }
-
- /*
- * Link this flush message and the old message
- * so multiple flushes can be coalesced (if there are
- * multiple Tflush messages for a particular pending
- * request, it is only necessary to respond to the last
- * one, so any previous can be removed) and to be
- * sure flushes wait for their corresponding old
- * message to go out first.
- * Waiting flush messages do not go on the write queue,
- * they are processed after the old message is dealt
- * with. There's no real need to protect the setting of
- * Msg.nowq, the only code to check it runs in this
- * process after this routine returns.
- */
- if((flush = old->flush) != nil){
- if(Dflag)
- fprint(2, "msgFlush: remove %d from %d list\n",
- old->flush->t.tag, old->t.tag);
- m->flush = flush->flush;
- flush->flush = nil;
- msgMunlink(flush);
- msgFree(flush);
- }
- old->flush = m;
- m->nowq = 1;
-
- if(Dflag)
- fprint(2, "msgFlush: add %d to %d queue\n",
- m->t.tag, old->t.tag);
- vtUnlock(con->mlock);
-}
-
-static void
-msgProc(void*)
-{
- Msg *m;
- char *e;
- Con *con;
-
- vtThreadSetName("msgProc");
-
- for(;;){
- /*
- * If surplus to requirements, exit.
- * If not, wait for and pull a message off
- * the read queue.
- */
- vtLock(mbox.rlock);
- if(mbox.nproc > mbox.maxproc){
- mbox.nproc--;
- vtUnlock(mbox.rlock);
- break;
- }
- while(mbox.rhead == nil)
- vtSleep(mbox.rrendez);
- m = mbox.rhead;
- mbox.rhead = m->rwnext;
- m->rwnext = nil;
- vtUnlock(mbox.rlock);
-
- con = m->con;
- e = nil;
-
- /*
- * If the message has been flushed before
- * any 9P processing has started, mark it so
- * none will be attempted.
- */
- vtLock(con->mlock);
- if(m->state == MsgF)
- e = "flushed";
- else
- m->state = Msg9;
- vtUnlock(con->mlock);
-
- if(e == nil){
- /*
- * explain this
- */
- vtLock(con->lock);
- if(m->t.type == Tversion){
- con->version = m;
- con->state = ConDown;
- while(con->mhead != m)
- vtSleep(con->rendez);
- assert(con->state == ConDown);
- if(con->version == m){
- con->version = nil;
- con->state = ConInit;
- }
- else
- e = "Tversion aborted";
- }
- else if(con->state != ConUp)
- e = "connection not ready";
- vtUnlock(con->lock);
- }
-
- /*
- * Dispatch if not error already.
- */
- m->r.tag = m->t.tag;
- if(e == nil && !(*rFcall[m->t.type])(m))
- e = vtGetError();
- if(e != nil){
- m->r.type = Rerror;
- m->r.ename = e;
- }
- else
- m->r.type = m->t.type+1;
-
- /*
- * Put the message (with reply) on the
- * write queue and wakeup the write process.
- */
- if(!m->nowq){
- vtLock(con->wlock);
- if(con->whead == nil)
- con->whead = m;
- else
- con->wtail->rwnext = m;
- con->wtail = m;
- vtWakeup(con->wrendez);
- vtUnlock(con->wlock);
- }
- }
-}
-
-static void
-msgRead(void* v)
-{
- Msg *m;
- Con *con;
- int eof, fd, n;
-
- vtThreadSetName("msgRead");
-
- con = v;
- fd = con->fd;
- eof = 0;
-
- while(!eof){
- m = msgAlloc(con);
-
- while((n = read9pmsg(fd, m->data, con->msize)) == 0)
- ;
- if(n < 0){
- m->t.type = Tversion;
- m->t.fid = NOFID;
- m->t.tag = NOTAG;
- m->t.msize = con->msize;
- m->t.version = "9PEoF";
- eof = 1;
- }
- else if(convM2S(m->data, n, &m->t) != n){
- if(Dflag)
- fprint(2, "msgRead: convM2S error: %s\n",
- con->name);
- msgFree(m);
- continue;
- }
- if(Dflag)
- fprint(2, "msgRead %p: t %F\n", con, &m->t);
-
- vtLock(con->mlock);
- if(con->mtail != nil){
- m->mprev = con->mtail;
- con->mtail->mnext = m;
- }
- else{
- con->mhead = m;
- m->mprev = nil;
- }
- con->mtail = m;
- vtUnlock(con->mlock);
-
- vtLock(mbox.rlock);
- if(mbox.rhead == nil){
- mbox.rhead = m;
- if(!vtWakeup(mbox.rrendez)){
- if(mbox.nproc < mbox.maxproc){
- if(vtThread(msgProc, nil) > 0)
- mbox.nproc++;
- }
- else
- mbox.nprocstarve++;
- }
- /*
- * don't need this surely?
- vtWakeup(mbox.rrendez);
- */
- }
- else
- mbox.rtail->rwnext = m;
- mbox.rtail = m;
- vtUnlock(mbox.rlock);
- }
-}
-
-static void
-msgWrite(void* v)
-{
- Con *con;
- int eof, n;
- Msg *flush, *m;
-
- vtThreadSetName("msgWrite");
-
- con = v;
- if(vtThread(msgRead, con) < 0){
- conFree(con);
- return;
- }
-
- for(;;){
- /*
- * Wait for and pull a message off the write queue.
- */
- vtLock(con->wlock);
- while(con->whead == nil)
- vtSleep(con->wrendez);
- m = con->whead;
- con->whead = m->rwnext;
- m->rwnext = nil;
- assert(!m->nowq);
- vtUnlock(con->wlock);
-
- eof = 0;
-
- /*
- * Write each message (if it hasn't been flushed)
- * followed by any messages waiting for it to complete.
- */
- vtLock(con->mlock);
- while(m != nil){
- msgMunlink(m);
-
- if(Dflag)
- fprint(2, "msgWrite %d: r %F\n",
- m->state, &m->r);
-
- if(m->state != MsgF){
- m->state = MsgW;
- vtUnlock(con->mlock);
-
- n = convS2M(&m->r, con->data, con->msize);
- if(write(con->fd, con->data, n) != n)
- eof = 1;
-
- vtLock(con->mlock);
- }
-
- if((flush = m->flush) != nil){
- assert(flush->nowq);
- m->flush = nil;
- }
- msgFree(m);
- m = flush;
- }
- vtUnlock(con->mlock);
-
- vtLock(con->lock);
- if(eof && con->fd >= 0){
- close(con->fd);
- con->fd = -1;
- }
- if(con->state == ConDown)
- vtWakeup(con->rendez);
- if(con->state == ConMoribund && con->mhead == nil){
- vtUnlock(con->lock);
- conFree(con);
- break;
- }
- vtUnlock(con->lock);
- }
-}
-
-Con*
-conAlloc(int fd, char* name, int flags)
-{
- Con *con;
- char buf[128], *p;
- int rfd, n;
-
- vtLock(cbox.alock);
- while(cbox.ahead == nil){
- if(cbox.ncon >= cbox.maxcon){
- cbox.nconstarve++;
- vtSleep(cbox.arendez);
- continue;
- }
- con = vtMemAllocZ(sizeof(Con));
- con->lock = vtLockAlloc();
- con->rendez = vtRendezAlloc(con->lock);
- con->data = vtMemAlloc(cbox.msize);
- con->msize = cbox.msize;
- con->alock = vtLockAlloc();
- con->mlock = vtLockAlloc();
- con->mrendez = vtRendezAlloc(con->mlock);
- con->wlock = vtLockAlloc();
- con->wrendez = vtRendezAlloc(con->wlock);
- con->fidlock = vtLockAlloc();
-
- cbox.ncon++;
- cbox.ahead = con;
- break;
- }
- con = cbox.ahead;
- cbox.ahead = con->anext;
- con->anext = nil;
-
- if(cbox.ctail != nil){
- con->cprev = cbox.ctail;
- cbox.ctail->cnext = con;
- }
- else{
- cbox.chead = con;
- con->cprev = nil;
- }
- cbox.ctail = con;
-
- assert(con->mhead == nil);
- assert(con->whead == nil);
- assert(con->fhead == nil);
- assert(con->nfid == 0);
-
- con->state = ConNew;
- con->fd = fd;
- if(con->name != nil){
- vtMemFree(con->name);
- con->name = nil;
- }
- if(name != nil)
- con->name = vtStrDup(name);
- else
- con->name = vtStrDup("unknown");
- con->remote[0] = 0;
- snprint(buf, sizeof buf, "%s/remote", con->name);
- if((rfd = open(buf, OREAD)) >= 0){
- n = read(rfd, buf, sizeof buf-1);
- close(rfd);
- if(n > 0){
- buf[n] = 0;
- if((p = strchr(buf, '\n')) != nil)
- *p = 0;
- strecpy(con->remote, con->remote+sizeof con->remote, buf);
- }
- }
- con->flags = flags;
- con->isconsole = 0;
- vtUnlock(cbox.alock);
-
- if(vtThread(msgWrite, con) < 0){
- conFree(con);
- return nil;
- }
-
- return con;
-}
-
-static int
-cmdMsg(int argc, char* argv[])
-{
- char *p;
- char *usage = "usage: msg [-m nmsg] [-p nproc]";
- int maxmsg, nmsg, nmsgstarve, maxproc, nproc, nprocstarve;
-
- maxmsg = maxproc = 0;
-
- ARGBEGIN{
- default:
- return cliError(usage);
- case 'm':
- p = ARGF();
- if(p == nil)
- return cliError(usage);
- maxmsg = strtol(argv[0], &p, 0);
- if(maxmsg <= 0 || p == argv[0] || *p != '\0')
- return cliError(usage);
- break;
- case 'p':
- p = ARGF();
- if(p == nil)
- return cliError(usage);
- maxproc = strtol(argv[0], &p, 0);
- if(maxproc <= 0 || p == argv[0] || *p != '\0')
- return cliError(usage);
- break;
- }ARGEND
- if(argc)
- return cliError(usage);
-
- vtLock(mbox.alock);
- if(maxmsg)
- mbox.maxmsg = maxmsg;
- maxmsg = mbox.maxmsg;
- nmsg = mbox.nmsg;
- nmsgstarve = mbox.nmsgstarve;
- vtUnlock(mbox.alock);
-
- vtLock(mbox.rlock);
- if(maxproc)
- mbox.maxproc = maxproc;
- maxproc = mbox.maxproc;
- nproc = mbox.nproc;
- nprocstarve = mbox.nprocstarve;
- vtUnlock(mbox.rlock);
-
- consPrint("\tmsg -m %d -p %d\n", maxmsg, maxproc);
- consPrint("\tnmsg %d nmsgstarve %d nproc %d nprocstarve %d\n",
- nmsg, nmsgstarve, nproc, nprocstarve);
-
- return 1;
-}
-
-static int
-scmp(Fid *a, Fid *b)
-{
- if(a == 0)
- return 1;
- if(b == 0)
- return -1;
- return strcmp(a->uname, b->uname);
-}
-
-static Fid*
-fidMerge(Fid *a, Fid *b)
-{
- Fid *s, **l;
-
- l = &s;
- while(a || b){
- if(scmp(a, b) < 0){
- *l = a;
- l = &a->sort;
- a = a->sort;
- }else{
- *l = b;
- l = &b->sort;
- b = b->sort;
- }
- }
- *l = 0;
- return s;
-}
-
-static Fid*
-fidMergeSort(Fid *f)
-{
- int delay;
- Fid *a, *b;
-
- if(f == nil)
- return nil;
- if(f->sort == nil)
- return f;
-
- a = b = f;
- delay = 1;
- while(a && b){
- if(delay) /* easy way to handle 2-element list */
- delay = 0;
- else
- a = a->sort;
- if(b = b->sort)
- b = b->sort;
- }
-
- b = a->sort;
- a->sort = nil;
-
- a = fidMergeSort(f);
- b = fidMergeSort(b);
-
- return fidMerge(a, b);
-}
-
-static int
-cmdWho(int argc, char* argv[])
-{
- char *usage = "usage: who";
- int i, l1, l2, l;
- Con *con;
- Fid *fid, *last;
-
- ARGBEGIN{
- default:
- return cliError(usage);
- }ARGEND
-
- if(argc > 0)
- return cliError(usage);
-
- vtRLock(cbox.clock);
- l1 = 0;
- l2 = 0;
- for(con=cbox.chead; con; con=con->cnext){
- if((l = strlen(con->name)) > l1)
- l1 = l;
- if((l = strlen(con->remote)) > l2)
- l2 = l;
- }
- for(con=cbox.chead; con; con=con->cnext){
- consPrint("\t%-*s %-*s", l1, con->name, l2, con->remote);
- vtLock(con->fidlock);
- last = nil;
- for(i=0; i<NFidHash; i++)
- for(fid=con->fidhash[i]; fid; fid=fid->hash)
- if(fid->fidno != NOFID && fid->uname){
- fid->sort = last;
- last = fid;
- }
- fid = fidMergeSort(last);
- last = nil;
- for(; fid; last=fid, fid=fid->sort)
- if(last==nil || strcmp(fid->uname, last->uname) != 0)
- consPrint(" %q", fid->uname);
- vtUnlock(con->fidlock);
- consPrint("\n");
- }
- vtRUnlock(cbox.clock);
- return 1;
-}
-
-void
-msgInit(void)
-{
- mbox.alock = vtLockAlloc();
- mbox.arendez = vtRendezAlloc(mbox.alock);
-
- mbox.rlock = vtLockAlloc();
- mbox.rrendez = vtRendezAlloc(mbox.rlock);
-
- mbox.maxmsg = NMsgInit;
- mbox.maxproc = NMsgProcInit;
- mbox.msize = NMsizeInit;
-
- cliAddCmd("msg", cmdMsg);
-}
-
-static int
-cmdCon(int argc, char* argv[])
-{
- char *p;
- Con *con;
- char *usage = "usage: con [-m ncon]";
- int maxcon, ncon, nconstarve;
-
- maxcon = 0;
-
- ARGBEGIN{
- default:
- return cliError(usage);
- case 'm':
- p = ARGF();
- if(p == nil)
- return cliError(usage);
- maxcon = strtol(argv[0], &p, 0);
- if(maxcon <= 0 || p == argv[0] || *p != '\0')
- return cliError(usage);
- break;
- }ARGEND
- if(argc)
- return cliError(usage);
-
- vtLock(cbox.clock);
- if(maxcon)
- cbox.maxcon = maxcon;
- maxcon = cbox.maxcon;
- ncon = cbox.ncon;
- nconstarve = cbox.nconstarve;
- vtUnlock(cbox.clock);
-
- consPrint("\tcon -m %d\n", maxcon);
- consPrint("\tncon %d nconstarve %d\n", ncon, nconstarve);
-
- vtRLock(cbox.clock);
- for(con = cbox.chead; con != nil; con = con->cnext){
- consPrint("\t%s\n", con->name);
- }
- vtRUnlock(cbox.clock);
-
- return 1;
-}
-
-void
-conInit(void)
-{
- cbox.alock = vtLockAlloc();
- cbox.arendez = vtRendezAlloc(cbox.alock);
-
- cbox.clock = vtLockAlloc();
-
- cbox.maxcon = NConInit;
- cbox.msize = NMsizeInit;
-
- cliAddCmd("con", cmdCon);
- cliAddCmd("who", cmdWho);
-}