The first-send-blocked date was originally designed to save the date of the
first send of a series where some data remain blocked. It was relaxed
recently (
3083fd90e "BUG/MEDIUM: stconn: Report a send activity everytime
data were sent") to save the date of the first full blocked send. However,
it is not accurrate.
When all data are sent, the fsb value must be reset to TICK_ETERNITY. When
nothing is sent and if it is not already set, it must be set. But when data
are partially sent, the value must be updated and not reset. Otherwise the
write timeout may be ignored because fsb date is never set.
So, changes brought by the patch above are reverted and
sc_ep_report_blocked_send() was changed to know if some data were sent or
not. This way we are able to update fsb value.
l
This patch must be backported to 2.8.
}
/* Report a send blocked. This function sets <fsb> to now_ms if it was not
- * already set
+ * already set or if something was sent (to renew <fsb>).
*/
-static forceinline void sc_ep_report_blocked_send(struct stconn *sc)
+static forceinline void sc_ep_report_blocked_send(struct stconn *sc, int did_send)
{
- if (!tick_isset(sc->sedesc->fsb))
+ if (did_send || !tick_isset(sc->sedesc->fsb))
sc->sedesc->fsb = now_ms;
}
BUG_ON(!mux->done_fastfwd);
sent = mux->done_fastfwd(se->sc);
- if (sent > 0)
- sc_ep_report_send_activity(se->sc);
- else if (to_send > 0) /* implies sent == 0 */
- sc_ep_report_blocked_send(se->sc);
+ if (to_send) {
+ if (sent == to_send)
+ sc_ep_report_send_activity(se->sc);
+ else
+ sc_ep_report_blocked_send(se->sc, sent != 0);
+ }
}
}
struct stconn *sc, *sco;
unsigned int rate;
size_t count;
+ int did_send = 0;
TRACE_ENTER(APPLET_EV_PROCESS, app);
if (sco->room_needed < 0 || channel_recv_max(sc_oc(sc)) >= sco->room_needed)
sc_have_room(sco);
sc_ep_report_send_activity(sc);
+ did_send = 1;
}
else {
if (!sco->room_needed)
sc_have_room(sco);
- sc_ep_report_blocked_send(sc);
}
if (sc_ic(sc)->flags & CF_READ_EVENT)
sc_ep_set(sc, SE_FL_EOS|SE_FL_ERROR);
}
+ if (!co_data(sc_oc(sc)))
+ sc_ep_report_send_activity(sc);
+ else
+ sc_ep_report_blocked_send(sc, did_send);
+
/* measure the call rate and check for anomalies when too high */
if (((b_size(sc_ib(sc)) && sc->flags & SC_FL_NEED_BUFF) || // asks for a buffer which is present
(b_size(sc_ib(sc)) && !b_data(sc_ib(sc)) && sc->flags & SC_FL_NEED_ROOM) || // asks for room in an empty buffer
oc->flags |= CF_WRITE_EVENT | CF_WROTE_DATA;
if (sc->state == SC_ST_CON)
sc->state = SC_ST_RDY;
- sc_ep_report_send_activity(sc);
- }
- else {
- if (sc_state_in(sc->state, SC_SB_EST|SC_SB_DIS|SC_SB_CLO))
- sc_ep_report_blocked_send(sc);
}
if (!sco->room_needed || (did_send && (sco->room_needed < 0 || channel_recv_max(sc_oc(sc)) >= sco->room_needed)))
sc_have_room(sco);
did_send = 1;
}
+ sc_ep_report_send_activity(sc);
}
else {
/* We couldn't send all of our data, let the mux know we'd like to send more */
conn->mux->subscribe(sc, SUB_RETRY_SEND, &sc->wait_event);
+ if (sc_state_in(sc->state, SC_SB_EST|SC_SB_DIS|SC_SB_CLO))
+ sc_ep_report_blocked_send(sc, did_send);
}
return did_send;