M ip/devip.c => ip/devip.c +5 -0
@@ 409,12 409,17 @@ ipopen(Chan* c, int omode)
nc = nil;
while(nc == nil) {
+ /* give up if we got a hangup */
+ if(qisclosed(cv->rq))
+ error("listen hungup");
+
qlock(&cv->listenq);
if(waserror()) {
qunlock(&cv->listenq);
nexterror();
}
+ /* wait for a connect */
sleep(&cv->listenr, incoming, cv);
lock(cv);
M ip/rudp.c => ip/rudp.c +2 -2
@@ 774,7 774,7 @@ relstate(Rudpcb *ucb, uchar *addr, ushort port, char *from)
/* no state for this addr/port, create some */
if(r == nil){
- if(generation == 0)
+ while(generation == 0)
generation = rand();
DPRINT("from %s new state %lud for %I!%ud\n",
from, generation, addr, port);
@@ 834,7 834,7 @@ reliput(Conv *c, Block *bp, uchar *addr, ushort port)
/* make sure we're not talking to a new remote side */
if(r->rcvgen != sgen){
- if(seq != 1)
+ if(seq != 0 && seq != 1)
return -1;
/* new connection */
M ip/tcp.c => ip/tcp.c +2 -0
@@ 567,6 567,8 @@ localclose(Conv *s, char *reason) /* called with tcb locked */
if(tcb->state == Syn_sent)
Fsconnected(s, reason);
+ if(s->state == Announced)
+ wakeup(&s->listenr);
qhangup(s->rq, reason);
qhangup(s->wq, reason);
M port/portfns.h => port/portfns.h +1 -0
@@ 224,6 224,7 @@ void qflush(Queue*);
int qfull(Queue*);
Block* qget(Queue*);
void qhangup(Queue*, char*);
+int qisclosed(Queue*);
void qinit(void);
int qiwrite(Queue*, void*, int);
int qlen(Queue*);
M port/qio.c => port/qio.c +13 -2
@@ 147,14 147,16 @@ iallocb(int size)
int n;
if(ialloc.bytes > conf.ialloc){
- iprint("iallocb: limited %d/%d\n", ialloc.bytes, conf.ialloc);
+ print("iallocb: limited %d/%d\n",
+ ialloc.bytes, conf.ialloc);
return 0;
}
n = sizeof(Block) + size + (BY2V-1);
b = mallocz(n+Hdrspc, 0);
if(b == nil){
- iprint("iallocb: no memory %d/%d\n", ialloc.bytes, conf.ialloc);
+ print("iallocb: no memory %d/%d\n",
+ ialloc.bytes, conf.ialloc);
return nil;
}
memset(b, 0, sizeof(Block));
@@ 1230,6 1232,15 @@ qhangup(Queue *q, char *msg)
}
/*
+ * return non-zero if the q is hungup
+ */
+int
+qisclosed(Queue *q)
+{
+ return q->state & Qclosed;
+}
+
+/*
* mark a queue as no longer hung up
*/
void