From c6c843613a1693ec695f546967715172493e4cb4 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 13 Apr 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-04-13 --- port/chan.c | 24 ++++++++++++++++-------- port/devlance.c | 4 +++- port/devnonet.c | 19 ++++++++++--------- port/stnoether.c | 1 + port/stream.c | 17 ++++++++++++++++- ss/dat.h | 3 ++- ss/fns.h | 2 +- 7 files changed, 49 insertions(+), 21 deletions(-) diff --git a/port/chan.c b/port/chan.c index 4830e89500d9d38c2a6315382ae91b25d3fa9be7..9dcf9d8fdf4efc18debf05416e35a9e14197a51a 100644 --- a/port/chan.c +++ b/port/chan.c @@ -98,21 +98,29 @@ loop: goto loop; } +void +freechan(Chan *c) +{ + c->flag = CFREE; + lock(&chanalloc); + c->next = chanalloc.free; + chanalloc.free = c; + unlock(&chanalloc); +} + void close(Chan *c) { if(c->flag & CFREE) panic("close"); if(decref(c) == 0){ - if(!waserror()){ - (*devtab[c->type].close)(c); - poperror(); + if(waserror()) { + freechan(c); + nexterror(); } - c->flag = CFREE; - lock(&chanalloc); - c->next = chanalloc.free; - chanalloc.free = c; - unlock(&chanalloc); + (*devtab[c->type].close)(c); + freechan(c); + poperror(); } } diff --git a/port/devlance.c b/port/devlance.c index a8011550b0dd3357d27cd670fb34e70c5033ed7c..b8b6045c1a4d302e4258893516197ca680941e9a 100644 --- a/port/devlance.c +++ b/port/devlance.c @@ -310,11 +310,13 @@ lanceoput(Queue *q, Block *bp ) { int n, len; Etherpkt *p; + Ethertype *e; Msg *m; if(bp->type == M_CTL){ if(streamparse("connect", bp)){ - ((Ethertype *)q->ptr)->type = strtoul((char *)bp->rptr, 0, 0); + n = strtoul((char *)bp->rptr, 0, 0); + ((Ethertype *)q->ptr)->type = n; } freeb(bp); return; diff --git a/port/devnonet.c b/port/devnonet.c index 4774a0ef5414cf51f3f208b75484a41834ebbf8b..51538ad551635034d090628eec4ddfec2abc26c3 100644 --- a/port/devnonet.c +++ b/port/devnonet.c @@ -82,13 +82,13 @@ Dirtab nosubdir[]={ * Nonet conversation states (for Noconv.state) */ enum { - Cclosed, - Copen, - Cannounced, - Cconnected, - Cconnecting, - Chungup, - Creset, + Cclosed= 0, + Copen= 1, + Cannounced= 2, + Cconnected= 3, + Cconnecting= 4, + Chungup= 5, + Creset= 6, }; /* @@ -680,6 +680,7 @@ nostartconv(Noconv *cp, int circuit, char *raddr, int state) cp->out[0].mid = 0; cp->out[0].acked = 1; cp->out[0].rem = 0; + cp->afirst = cp->anext = 0; cp->first = cp->next = 1; cp->rexmit = cp->bad = cp->sent = cp->rcvd = 0; cp->lastacked = Nnomsg|(Nnomsg-1); @@ -1425,9 +1426,9 @@ loop: */ ep = ifc->conv + conf.nnoconv; for(cp = ifc->conv; cp < ep; cp++){ - if(cp->state==Cclosed || !canqlock(cp)) + if(cp->state<=Copen || !canqlock(cp)) continue; - if(cp->state == Cclosed){ + if(cp->state <= Copen){ qunlock(cp); continue; } diff --git a/port/stnoether.c b/port/stnoether.c index dad1e1994c5b2acd87dbabaf6dbc7eb1b18b189e..ee9972ba8d39c3ae0d15a1c68ac72816255f488f 100644 --- a/port/stnoether.c +++ b/port/stnoether.c @@ -62,6 +62,7 @@ noetherconnect(Noconv *cp, char *ea) static void noetheropen(Queue *q, Stream *s) { + streamenter(s); nonetnewifc(q, s, ETHERMAXTU, ETHERMINTU, ETHERHDRSIZE, noetherconnect); } diff --git a/port/stream.c b/port/stream.c index 13f8b4686cdfd2a539ab8f42212ed02a39e6907f..4a3417a2b988212ece9ab0638e958900f30d8a75 100644 --- a/port/stream.c +++ b/port/stream.c @@ -382,10 +382,12 @@ pushq(Stream* s, Qinfo *qi) /* * push */ + qlock(s); RD(nq)->next = q; RD(WR(q)->next)->next = RD(nq); WR(nq)->next = WR(q)->next; WR(q)->next = WR(nq); + qunlock(s); if(qi->open) (*qi->open)(RD(nq), s); @@ -401,6 +403,11 @@ popq(Stream *s) { Queue *q; + if(waserror()){ + qunlock(s); + nexterror(); + } + qlock(s); if(s->procq->next == WR(s->devq)) error(Ebadld); q = s->procq->next; @@ -408,6 +415,7 @@ popq(Stream *s) (*q->info->close)(RD(q)); s->procq->next = q->next; RD(q->next)->next = RD(s->procq); + qunlock(s); freeq(q); } @@ -918,17 +926,22 @@ streamclose1(Stream *s) Queue *q, *nq; Block *bp; int rv; + char err[ERRLEN]; /* * decrement the reference count */ qlock(s); + *err = 0; if(s->opens == 1){ /* * descend the stream closing the queues */ for(q = s->procq; q; q = q->next){ - if(!waserror()){ + if(waserror()){ + if(*err == 0) + strncpy(err, u->error, ERRLEN-1); + } else { if(q->info->close) (*q->info->close)(q->other); poperror(); @@ -957,6 +970,8 @@ streamclose1(Stream *s) */ streamexit(s, 1); qunlock(s); + if(*err) + errors(err); return rv; } int diff --git a/ss/dat.h b/ss/dat.h index ac8b2c16bffa753a8646e07348ae7ec298ee8c92..c54ed2e5948c9104b1fe7758d51ba40f756599e7 100644 --- a/ss/dat.h +++ b/ss/dat.h @@ -92,7 +92,8 @@ struct Alarm #define CHEXCL 0x20000000L struct Chan { - QLock; /* general access */ + QLock rdl; + QLock wrl; Ref; union{ Chan *next; /* allocation */ diff --git a/ss/fns.h b/ss/fns.h index cf39f90bfd939b933fc6c0d0c5a8ae39ad743d56..45d0f23c59b5b8a231c4211cb8c15327df771d5b 100644 --- a/ss/fns.h +++ b/ss/fns.h @@ -213,7 +213,7 @@ Stream *streamnew(ushort, ushort, ushort, Qinfo*, int); void streamopen(Chan*, Qinfo*); int streamparse(char*, Block*); void streamstat(Chan*, char*, char*); -long stringread(Chan*, void*, long, char*); +long stringread(Chan*, void*, long, char*, ulong); long syscall(Ureg*); int tas(char*); void touser(ulong);