Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netinet/tcp_timer.c
Show First 20 Lines • Show All 921 Lines • ▼ Show 20 Lines | switch (timer_type) { | ||||
} | } | ||||
return callout_active(t_callout); | return callout_active(t_callout); | ||||
} | } | ||||
void | void | ||||
tcp_timer_stop(struct tcpcb *tp, uint32_t timer_type) | tcp_timer_stop(struct tcpcb *tp, uint32_t timer_type) | ||||
{ | { | ||||
struct callout *t_callout; | struct callout *t_callout; | ||||
timeout_t *f_callout; | |||||
uint32_t f_reset; | uint32_t f_reset; | ||||
tp->t_timers->tt_flags |= TT_STOPPED; | tp->t_timers->tt_flags |= TT_STOPPED; | ||||
switch (timer_type) { | switch (timer_type) { | ||||
case TT_DELACK: | case TT_DELACK: | ||||
t_callout = &tp->t_timers->tt_delack; | t_callout = &tp->t_timers->tt_delack; | ||||
f_callout = tcp_timer_delack_discard; | |||||
f_reset = TT_DELACK_RST; | f_reset = TT_DELACK_RST; | ||||
break; | break; | ||||
case TT_REXMT: | case TT_REXMT: | ||||
t_callout = &tp->t_timers->tt_rexmt; | t_callout = &tp->t_timers->tt_rexmt; | ||||
f_callout = tcp_timer_rexmt_discard; | |||||
f_reset = TT_REXMT_RST; | f_reset = TT_REXMT_RST; | ||||
break; | break; | ||||
case TT_PERSIST: | case TT_PERSIST: | ||||
t_callout = &tp->t_timers->tt_persist; | t_callout = &tp->t_timers->tt_persist; | ||||
f_callout = tcp_timer_persist_discard; | |||||
f_reset = TT_PERSIST_RST; | f_reset = TT_PERSIST_RST; | ||||
break; | break; | ||||
case TT_KEEP: | case TT_KEEP: | ||||
t_callout = &tp->t_timers->tt_keep; | t_callout = &tp->t_timers->tt_keep; | ||||
f_callout = tcp_timer_keep_discard; | |||||
f_reset = TT_KEEP_RST; | f_reset = TT_KEEP_RST; | ||||
break; | break; | ||||
case TT_2MSL: | case TT_2MSL: | ||||
t_callout = &tp->t_timers->tt_2msl; | t_callout = &tp->t_timers->tt_2msl; | ||||
f_callout = tcp_timer_2msl_discard; | |||||
f_reset = TT_2MSL_RST; | f_reset = TT_2MSL_RST; | ||||
break; | break; | ||||
default: | default: | ||||
if (tp->t_fb->tfb_tcp_timer_stop) { | if (tp->t_fb->tfb_tcp_timer_stop) { | ||||
/* | /* | ||||
* XXXrrs we need to look at this with the | * XXXrrs we need to look at this with the | ||||
* stop case below (flags). | * stop case below (flags). | ||||
*/ | */ | ||||
tp->t_fb->tfb_tcp_timer_stop(tp, timer_type); | tp->t_fb->tfb_tcp_timer_stop(tp, timer_type); | ||||
return; | return; | ||||
} | } | ||||
panic("tp %p bad timer_type %#x", tp, timer_type); | panic("tp %p bad timer_type %#x", tp, timer_type); | ||||
} | } | ||||
if (tp->t_timers->tt_flags & timer_type) { | if (tp->t_timers->tt_flags & timer_type) { | ||||
if ((callout_stop(t_callout) > 0) && | if (callout_async_drain(t_callout, tcp_timer_discard) == 0) { | ||||
(tp->t_timers->tt_flags & f_reset)) { | |||||
tp->t_timers->tt_flags &= ~(timer_type | f_reset); | |||||
} else { | |||||
/* | /* | ||||
* Can't stop the callout, defer tcpcb actual deletion | * Can't stop the callout, defer tcpcb actual deletion | ||||
* to the last tcp timer discard callout. | * to the last one. We do this using the async drain | ||||
* The TT_STOPPED flag will ensure that no tcp timer | * function and incrementing the count in | ||||
* callouts can be restarted on our behalf, and | |||||
* past this point currently running callouts waiting | |||||
* on inp lock will return right away after the | |||||
* classical check for callout reset/stop events: | |||||
* callout_pending() || !callout_active() | |||||
*/ | */ | ||||
callout_reset(t_callout, 1, f_callout, tp); | tp->t_timers->tt_draincnt++; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
#define ticks_to_msecs(t) (1000*(t) / hz) | #define ticks_to_msecs(t) (1000*(t) / hz) | ||||
void | void | ||||
tcp_timer_to_xtimer(struct tcpcb *tp, struct tcp_timer *timer, | tcp_timer_to_xtimer(struct tcpcb *tp, struct tcp_timer *timer, | ||||
Show All 20 Lines |