M port/chan.c => port/chan.c +16 -8
@@ 99,20 99,28 @@ 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();
}
}
M port/devlance.c => port/devlance.c +3 -1
@@ 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;
M port/devnonet.c => port/devnonet.c +10 -9
@@ 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;
}
M port/stnoether.c => port/stnoether.c +1 -0
@@ 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);
}
M port/stream.c => port/stream.c +16 -1
@@ 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
M ss/dat.h => ss/dat.h +2 -1
@@ 92,7 92,8 @@ struct Alarm
#define CHEXCL 0x20000000L
struct Chan
{
- QLock; /* general access */
+ QLock rdl;
+ QLock wrl;
Ref;
union{
Chan *next; /* allocation */
M ss/fns.h => ss/fns.h +1 -1
@@ 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);