Commit 891889f0 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Retool SES_RxReq() from a REQ specific thing to a general "receive som

stuff on this TCP connection with timeouts" function.

Inpired by colliding patches from Martin & Lasse.
parent a40ceb07
......@@ -980,8 +980,8 @@ void SES_RxInit(struct http_conn *htc, struct ws *ws,
unsigned maxbytes, unsigned maxhdr);
void SES_RxReInit(struct http_conn *htc);
enum htc_status_e SES_Rx(struct http_conn *htc, double tmo);
enum htc_status_e SES_RxReq(const struct worker *, struct req *,
htc_complete_f *func);
enum htc_status_e SES_RxStuff(struct http_conn *, htc_complete_f *, double t0,
double *t1, double *t2, double ti, double tn);
#define SESS_ATTR(UP, low, typ, len) \
int SES_Get_##low(const struct sess *sp, typ *dst); \
......
......@@ -217,66 +217,73 @@ SES_Rx(struct http_conn *htc, double tmo)
/*----------------------------------------------------------------------
* Receive a request/packet/whatever, with timeouts
*
* t0 is when we start
* *t1 becomes time of first non-idle rx
* *t2 becomes time of complete rx
* ti is when we return IDLE if nothing has arrived
* tn is when we timeout on non-complete
*/
enum htc_status_e
SES_RxReq(const struct worker *wrk, struct req *req, htc_complete_f *func)
SES_RxStuff(struct http_conn *htc, htc_complete_f *func, double t0,
double *t1, double *t2, double ti, double tn)
{
double tmo;
double now, when;
struct sess *sp;
double now;
enum htc_status_e hs;
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
sp = req->sp;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
AZ(isnan(sp->t_idle));
assert(isnan(req->t_first));
AZ(isnan(t0));
AZ(isnan(tn));
if (t1 != NULL)
assert(isnan(*t1));
when = sp->t_idle + cache_param->timeout_idle;
tmo = cache_param->timeout_linger;
now = t0;
while (1) {
hs = SES_Rx(req->htc, tmo);
now = VTIM_real();
if (!isnan(ti))
tmo = ti - t0;
else
tmo = tn - t0;
hs = SES_Rx(htc, tmo);
if (hs == HTC_S_EOF) {
WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b);
WS_ReleaseP(htc->ws, htc->rxbuf_b);
return (HTC_S_CLOSE);
}
if (hs == HTC_S_OVERFLOW) {
WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b);
WS_ReleaseP(htc->ws, htc->rxbuf_b);
return (HTC_S_OVERFLOW);
}
hs = func(req->htc);
now = VTIM_real();
hs = func(htc);
if (hs == HTC_S_OVERFLOW) {
WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b);
WS_ReleaseP(htc->ws, htc->rxbuf_b);
return (HTC_S_OVERFLOW);
}
if (hs == HTC_S_JUNK) {
WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b);
WS_ReleaseP(htc->ws, htc->rxbuf_b);
return (HTC_S_JUNK);
}
if (hs == HTC_S_COMPLETE) {
/* Got it, run with it */
if (isnan(req->t_first))
req->t_first = now;
req->t_req = now;
if (t1 != NULL && isnan(*t1))
*t1 = now;
if (t2 != NULL)
*t2 = now;
return (HTC_S_COMPLETE);
}
if (when < now)
if (tn < now)
return (HTC_S_TIMEOUT);
if (hs == HTC_S_MORE) {
/* Working on it */
if (isnan(req->t_first))
req->t_first = now;
tmo = when - now;
if (t1 != NULL && isnan(*t1))
*t1 = now;
tmo = tn - now;
continue;
}
assert(hs == HTC_S_EMPTY);
/* Nothing but whitespace */
tmo = sp->t_idle + cache_param->timeout_linger - now;
if (tmo < 0)
if (ti < now)
return (HTC_S_IDLE);
}
}
......
......@@ -199,7 +199,10 @@ HTTP1_Session(struct worker *wrk, struct req *req)
AZ(req->vcl);
AZ(req->esi_level);
hs = SES_RxReq(wrk, req, HTTP1_Complete);
hs = SES_RxStuff(req->htc, HTTP1_Complete, sp->t_idle,
&req->t_first, &req->t_req,
sp->t_idle + cache_param->timeout_linger,
sp->t_idle + cache_param->timeout_idle);
if (hs < HTC_S_EMPTY) {
req->acct.req_hdrbytes +=
req->htc->rxbuf_e - req->htc->rxbuf_b;
......
......@@ -351,7 +351,8 @@ VPX_Proto_Sess(struct worker *wrk, void *priv)
assert(sizeof vpx1_sig == 5);
assert(sizeof vpx2_sig == 12);
hs = SES_RxReq(wrk, req, vpx_complete);
hs = SES_RxStuff(req->htc, vpx_complete, sp->t_idle,
NULL, NULL, NAN, sp->t_idle + cache_param->timeout_idle);
if (hs != HTC_S_COMPLETE) {
Req_Release(req);
SES_Delete(sp, SC_RX_JUNK, NAN);
......@@ -377,8 +378,6 @@ VPX_Proto_Sess(struct worker *wrk, void *priv)
req->htc->pipeline_e = req->htc->rxbuf_e;
WS_Release(req->htc->ws, 0);
SES_RxReInit(req->htc);
req->t_req = NAN;
req->t_first = NAN;
req->sp->sess_step = S_STP_H1NEWREQ;
wrk->task.func = SES_Proto_Req;
wrk->task.priv = req;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment