diff options
Diffstat (limited to 'sys/netipx/spx_usrreq.c')
-rw-r--r-- | sys/netipx/spx_usrreq.c | 35 |
1 files changed, 16 insertions, 19 deletions
diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c index 409bf46..01cd86b 100644 --- a/sys/netipx/spx_usrreq.c +++ b/sys/netipx/spx_usrreq.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2004, Robert N. M. Watson * Copyright (c) 1995, Mike Mitchell * Copyright (c) 1984, 1985, 1986, 1987, 1993 * The Regents of the University of California. All rights reserved. @@ -1310,7 +1311,7 @@ spx_attach(so, proto, td) if (ipxp != NULL) return (EISCONN); s = splnet(); - error = ipx_pcballoc(so, &ipxpcb, td); + error = ipx_pcballoc(so, &ipxpcb_list, td); if (error) goto spx_attach_end; if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { @@ -1731,9 +1732,7 @@ spx_fasttimo() register struct spxpcb *cb; int s = splnet(); - ipxp = ipxpcb.ipxp_next; - if (ipxp != NULL) - for (; ipxp != &ipxpcb; ipxp = ipxp->ipxp_next) + LIST_FOREACH(ipxp, &ipxpcb_list, ipxp_list) { if ((cb = (struct spxpcb *)ipxp->ipxp_pcb) != NULL && (cb->s_flags & SF_DELACK)) { cb->s_flags &= ~SF_DELACK; @@ -1741,6 +1740,8 @@ spx_fasttimo() spxstat.spxs_delack++; spx_output(cb, (struct mbuf *)NULL); } + } + splx(s); } @@ -1752,36 +1753,32 @@ spx_fasttimo() void spx_slowtimo() { - register struct ipxpcb *ip, *ipnxt; + register struct ipxpcb *ip, *ip_temp; register struct spxpcb *cb; int s = splnet(); register int i; /* - * Search through tcb's and update active timers. + * Search through tcb's and update active timers. Note that timers + * may free the ipxpcb, so be sure to handle that case. */ - ip = ipxpcb.ipxp_next; - if (ip == NULL) { - splx(s); - return; - } - while (ip != &ipxpcb) { + LIST_FOREACH_SAFE(ip, &ipxpcb_list, ipxp_list, ip_temp) { cb = ipxtospxpcb(ip); - ipnxt = ip->ipxp_next; if (cb == NULL) - goto tpgone; + continue; for (i = 0; i < SPXT_NTIMERS; i++) { if (cb->s_timer[i] && --cb->s_timer[i] == 0) { - spx_timers(cb, i); - if (ipnxt->ipxp_prev != ip) - goto tpgone; + /* + * spx_timers() returns (NULL) if it free'd + * the pcb. + */ + if (spx_timers(cb, i) == NULL) + continue; } } cb->s_idle++; if (cb->s_rtt) cb->s_rtt++; -tpgone: - ip = ipnxt; } spx_iss += SPX_ISSINCR/PR_SLOWHZ; /* increment iss */ splx(s); |