From 6ca69b6039750eb3e910cda0802ba963ba752a23 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 2 Jan 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-01-02 --- ip/tcp.c | 78 ++++++++++++++++++++++++++++++++++++++------------- port/devmnt.c | 6 ++-- 2 files changed, 61 insertions(+), 23 deletions(-) diff --git a/ip/tcp.c b/ip/tcp.c index 760550945ec9f5fb32177a2f9cc4521c87b7d629..0c65ef3024a0874c4ef659b77e0b2e80a9b61466 100644 --- a/ip/tcp.c +++ b/ip/tcp.c @@ -251,7 +251,7 @@ void tcprcvwin(Conv*); void tcpacktimer(void*); void tcpkeepalive(void*); void tcpsetkacounter(Tcpctl*); -void tcprxmit(Conv*, int); +void tcprxmit(Conv*); void tcpsetstate(Conv *s, uchar newstate) @@ -407,14 +407,21 @@ tcpkick(Conv *s, int len) /* * Push data */ + if(waserror()){ + qunlock(s); + nexterror(); + } qlock(s); tcb->sndcnt += len; tcprcvwin(s); tcpoutput(s); qunlock(s); + poperror(); break; default: + qlock(s); localclose(s, "Hangup"); + qunlock(s); } } @@ -442,11 +449,18 @@ tcpacktimer(void *v) s = v; tcb = (Tcpctl*)s->ptcl; + if(waserror()){ + qunlock(s); + nexterror(); + } qlock(s); - tcb->flags |= FORCE; - tcprcvwin(s); - tcpoutput(s); + if(tcb->state != Closed){ + tcb->flags |= FORCE; + tcprcvwin(s); + tcpoutput(s); + } qunlock(s); + poperror(); } static void @@ -583,6 +597,7 @@ localclose(Conv *s, char *reason) /* called with tcb locked */ freeblist(rp->bp); free(rp); } + tcb->reseq = nil; if(tcb->state == Syn_sent) Fsconnected(s, reason); @@ -592,7 +607,6 @@ localclose(Conv *s, char *reason) /* called with tcb locked */ qhangup(s->rq, reason); qhangup(s->wq, reason); - tcb->reseq = nil; tcpsetstate(s, Closed); } @@ -685,11 +699,16 @@ tcpstart(Conv *s, int mode, ushort window) tpriv->tstats.tcpActiveOpens++; /* Send SYN, go into SYN_SENT state */ qlock(s); + if(waserror()){ + qunlock(s); + nexterror(); + } tcb->flags |= ACTIVE; tcpsndsyn(tcb); tcpsetstate(s, Syn_sent); tcpoutput(s); qunlock(s); + poperror(); break; } } @@ -1065,7 +1084,7 @@ update(Conv *s, Tcp *seg) tcb->snd.recovery = 1; tcb->snd.rxt = tcb->snd.nxt; // print("fast rxt %lud, nxt %lud\n", tcb->snd.una, tcb->snd.nxt); - tcprxmit(s, 0); + tcprxmit(s); } else { /* do reno tcp here. */ } @@ -1301,6 +1320,10 @@ tcpiput(Proto *tcp, uchar*, Block *bp) * Out-of-band data is ignored - it was always a bad idea. */ tcb = (Tcpctl*)s->ptcl; + if(waserror()){ + qunlock(s); + nexterror(); + } qlock(s); qunlock(tcp); @@ -1355,6 +1378,7 @@ tcpiput(Proto *tcp, uchar*, Block *bp) freeblist(bp); qunlock(s); + poperror(); return; case Syn_received: /* doesn't matter if it's the correct ack, we're just trying to set timing */ @@ -1380,6 +1404,7 @@ tcpiput(Proto *tcp, uchar*, Block *bp) goto output; } qunlock(s); + poperror(); return; } @@ -1522,6 +1547,7 @@ tcpiput(Proto *tcp, uchar*, Block *bp) freeblist(bp); sndrst(tcp, source, dest, length, &seg); qunlock(s); + poperror(); return; } } @@ -1587,9 +1613,11 @@ tcpiput(Proto *tcp, uchar*, Block *bp) output: tcpoutput(s); qunlock(s); + poperror(); return; raise: qunlock(s); + poperror(); freeblist(bp); tcpkick(s, 0); } @@ -1853,14 +1881,21 @@ tcpkeepalive(void *v) s = v; tcb = (Tcpctl*)s->ptcl; - if(--(tcb->kacounter) <= 0) - localclose(s, Etimedout); - else { - qlock(s); - tcpsendka(s); + if(waserror()){ qunlock(s); - tcpgo(s->p->priv, &tcb->katimer); + nexterror(); } + qlock(s); + if(tcb->state != Closed){ + if(--(tcb->kacounter) <= 0) { + localclose(s, Etimedout); + } else { + tcpsendka(s); + tcpgo(s->p->priv, &tcb->katimer); + } + } + qunlock(s); + poperror(); } /* @@ -1885,14 +1920,12 @@ tcpstartka(Conv *s, char **f, int n) } void -tcprxmit(Conv *s, int dolock) +tcprxmit(Conv *s) { Tcpctl *tcb; tcb = (Tcpctl*)s->ptcl; - if(dolock) - qlock(s); tcb->flags |= RETRAN|FORCE; tcb->snd.ptr = tcb->snd.una; @@ -1912,9 +1945,6 @@ tcprxmit(Conv *s, int dolock) */ tcb->cwind = tcb->mss; tcpoutput(s); - - if(dolock) - qunlock(s); } void @@ -1929,7 +1959,11 @@ tcptimeout(void *arg) tpriv = s->p->priv; tcb = (Tcpctl*)s->ptcl; - + if(waserror()){ + qunlock(s); + nexterror(); + } + qlock(s); switch(tcb->state){ default: tcb->backoff++; @@ -1942,14 +1976,18 @@ tcptimeout(void *arg) localclose(s, Etimedout); break; } - tcprxmit(s, 1); + tcprxmit(s); tpriv->tstats.tcpRetransTimeouts++; tcb->snd.dupacks = 0; break; case Time_wait: localclose(s, nil); break; + case Closed: + break; } + qunlock(s); + poperror(); } int diff --git a/port/devmnt.c b/port/devmnt.c index d2fd307e728ca08f87439bd5d98e38996977b4f3..f7370eee9b1bc53cb5b3a81b94f4ef58db8ed8a8 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -615,7 +615,7 @@ mountrpc(Mnt *m, Mntrpc *r) int t; r->reply.tag = 0; - r->reply.type = 4; + r->reply.type = Tmax; /* can't ever be a valid message type */ mountio(m, r); @@ -750,8 +750,6 @@ mountmux(Mnt *m, Mntrpc *r) if((q->flushed==0 && q->request.tag == r->reply.tag) || (q->flushed && q->flushtag == r->reply.tag)) { *l = q->list; - q->done = 1; - unlock(m); if(q != r) { /* * Completed someone else. @@ -762,6 +760,8 @@ mountmux(Mnt *m, Mntrpc *r) r->rpc = dp; q->reply = r->reply; } + q->done = 1; + unlock(m); if(mntstats != nil) (*mntstats)(q->request.type, m->c, q->stime,