Commit 0d9759c8 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Introduce the struct "waitfor" so that the same waiter can be used

for more than one kind of waiting.
parent 26f67269
...@@ -55,6 +55,7 @@ struct tcp_pool { ...@@ -55,6 +55,7 @@ struct tcp_pool {
int refcnt; int refcnt;
struct lock mtx; struct lock mtx;
struct waitfor waitfor;
struct waiter *waiter; struct waiter *waiter;
volatile double timeout; volatile double timeout;
...@@ -162,7 +163,10 @@ VBT_Ref(const struct suckaddr *ip4, const struct suckaddr *ip6) ...@@ -162,7 +163,10 @@ VBT_Ref(const struct suckaddr *ip4, const struct suckaddr *ip6)
VTAILQ_INIT(&tp->killlist); VTAILQ_INIT(&tp->killlist);
VTAILQ_INSERT_HEAD(&pools, tp, list); VTAILQ_INSERT_HEAD(&pools, tp, list);
tp->timeout = 60; tp->timeout = 60;
tp->waiter = Waiter_New(tcp_handle, &tp->timeout); INIT_OBJ(&tp->waitfor, WAITFOR_MAGIC);
tp->waitfor.func = tcp_handle;
tp->waitfor.tmo = &tp->timeout;
tp->waiter = Waiter_New(&tp->waitfor);
return (tp); return (tp);
} }
......
...@@ -573,6 +573,8 @@ SES_Delete(struct sess *sp, enum sess_close reason, double now) ...@@ -573,6 +573,8 @@ SES_Delete(struct sess *sp, enum sess_close reason, double now)
* Create and delete pools * Create and delete pools
*/ */
static struct waitfor ses_wf;
struct sesspool * struct sesspool *
SES_NewPool(struct pool *wp, unsigned pool_no) SES_NewPool(struct pool *wp, unsigned pool_no)
{ {
...@@ -588,7 +590,11 @@ SES_NewPool(struct pool *wp, unsigned pool_no) ...@@ -588,7 +590,11 @@ SES_NewPool(struct pool *wp, unsigned pool_no)
bprintf(nb, "sess%u", pool_no); bprintf(nb, "sess%u", pool_no);
pp->mpl_sess = MPL_New(nb, &cache_param->sess_pool, pp->mpl_sess = MPL_New(nb, &cache_param->sess_pool,
&cache_param->workspace_session); &cache_param->workspace_session);
pp->http1_waiter = Waiter_New(ses_handle, &cache_param->timeout_idle);
INIT_OBJ(&ses_wf, WAITFOR_MAGIC);
ses_wf.func = ses_handle;
ses_wf.tmo = &cache_param->timeout_idle;
pp->http1_waiter = Waiter_New(&ses_wf);
VCA_New_SessPool(wp, pp); VCA_New_SessPool(wp, pp);
return (pp); return (pp);
......
...@@ -62,7 +62,7 @@ Waiter_GetName(void) ...@@ -62,7 +62,7 @@ Waiter_GetName(void)
} }
struct waiter * struct waiter *
Waiter_New(waiter_handle_f *func, volatile double *tmo) Waiter_New(struct waitfor *wf)
{ {
struct waiter *w; struct waiter *w;
...@@ -77,8 +77,7 @@ Waiter_New(waiter_handle_f *func, volatile double *tmo) ...@@ -77,8 +77,7 @@ Waiter_New(waiter_handle_f *func, volatile double *tmo)
INIT_OBJ(w, WAITER_MAGIC); INIT_OBJ(w, WAITER_MAGIC);
w->priv = (void*)(w + 1); w->priv = (void*)(w + 1);
w->impl = waiter; w->impl = waiter;
w->func = func; w->waitfor = wf;
w->tmo = tmo;
VTAILQ_INIT(&w->waithead); VTAILQ_INIT(&w->waithead);
waiter->init(w); waiter->init(w);
......
...@@ -71,13 +71,13 @@ vwe_eev(struct vwe *vwe, const struct epoll_event *ep, double now) ...@@ -71,13 +71,13 @@ vwe_eev(struct vwe *vwe, const struct epoll_event *ep, double now)
AN(ep->data.ptr); AN(ep->data.ptr);
CAST_OBJ_NOTNULL(wp, ep->data.ptr, WAITED_MAGIC); CAST_OBJ_NOTNULL(wp, ep->data.ptr, WAITED_MAGIC);
if (ep->events & EPOLLIN) { if (ep->events & EPOLLIN) {
vwe->waiter->func(wp, WAITER_ACTION, now); Wait_Call(vwe->waiter, wp, WAITER_ACTION, now);
} else if (ep->events & EPOLLERR) { } else if (ep->events & EPOLLERR) {
vwe->waiter->func(wp, WAITER_REMCLOSE, now); Wait_Call(vwe->waiter, wp, WAITER_REMCLOSE, now);
} else if (ep->events & EPOLLHUP) { } else if (ep->events & EPOLLHUP) {
vwe->waiter->func(wp, WAITER_REMCLOSE, now); Wait_Call(vwe->waiter, wp, WAITER_REMCLOSE, now);
} else if (ep->events & EPOLLRDHUP) { } else if (ep->events & EPOLLRDHUP) {
vwe->waiter->func(wp, WAITER_REMCLOSE, now); Wait_Call(vwe->waiter, wp, WAITER_REMCLOSE, now);
} }
} }
...@@ -99,7 +99,7 @@ vwe_thread(void *priv) ...@@ -99,7 +99,7 @@ vwe_thread(void *priv)
last_idle = 0.0; last_idle = 0.0;
while (1) { while (1) {
i = floor(.3 * 1e3 * *vwe->waiter->tmo); i = floor(.3 * 1e3 * Wait_Tmo(vwe->waiter, NULL));
n = epoll_wait(vwe->epfd, ev, NEEV, i); n = epoll_wait(vwe->epfd, ev, NEEV, i);
if (n < 0 && vwe->die) if (n < 0 && vwe->die)
break; break;
...@@ -113,8 +113,8 @@ vwe_thread(void *priv) ...@@ -113,8 +113,8 @@ vwe_thread(void *priv)
Lck_Unlock(&vwe->mtx); Lck_Unlock(&vwe->mtx);
vwe_eev(vwe, ep, now); vwe_eev(vwe, ep, now);
} }
idle = now - *vwe->waiter->tmo; idle = now - Wait_Tmo(vwe->waiter, NULL);
if (now - last_idle < .3 * *vwe->waiter->tmo) if (now - last_idle < .3 * Wait_Tmo(vwe->waiter, NULL))
continue; continue;
last_idle = now; last_idle = now;
VTAILQ_INIT(&tlist); VTAILQ_INIT(&tlist);
...@@ -132,7 +132,7 @@ vwe_thread(void *priv) ...@@ -132,7 +132,7 @@ vwe_thread(void *priv)
if (wp == NULL) if (wp == NULL)
break; break;
VTAILQ_REMOVE(&tlist, wp, list); VTAILQ_REMOVE(&tlist, wp, list);
vwe->waiter->func(wp, WAITER_TIMEOUT, now); Wait_Call(vwe->waiter, wp, WAITER_TIMEOUT, now);
} }
} }
return (NULL); return (NULL);
......
...@@ -75,7 +75,7 @@ vwk_thread(void *priv) ...@@ -75,7 +75,7 @@ vwk_thread(void *priv)
last_idle = 0.0; last_idle = 0.0;
while (1) { while (1) {
now = .3 * *vwk->waiter->tmo; now = .3 * Wait_Tmo(vwk->waiter, NULL);
ts.tv_sec = (time_t)floor(now); ts.tv_sec = (time_t)floor(now);
ts.tv_nsec = (long)(1e9 * (now - ts.tv_sec)); ts.tv_nsec = (long)(1e9 * (now - ts.tv_sec));
n = kevent(vwk->kq, NULL, 0, ke, NKEV, &ts); n = kevent(vwk->kq, NULL, 0, ke, NKEV, &ts);
...@@ -91,12 +91,12 @@ vwk_thread(void *priv) ...@@ -91,12 +91,12 @@ vwk_thread(void *priv)
VTAILQ_REMOVE(&vwk->list, wp, list); VTAILQ_REMOVE(&vwk->list, wp, list);
Lck_Unlock(&vwk->mtx); Lck_Unlock(&vwk->mtx);
if (kp->flags & EV_EOF) if (kp->flags & EV_EOF)
vwk->waiter->func(wp, WAITER_REMCLOSE, now); Wait_Call(vwk->waiter, wp, WAITER_REMCLOSE, now);
else else
vwk->waiter->func(wp, WAITER_ACTION, now); Wait_Call(vwk->waiter, wp, WAITER_ACTION, now);
} }
idle = now - *vwk->waiter->tmo; idle = now - Wait_Tmo(vwk->waiter, NULL);
if (now - last_idle < .3 * *vwk->waiter->tmo) if (now - last_idle < .3 * Wait_Tmo(vwk->waiter, NULL))
continue; continue;
last_idle = now; last_idle = now;
n = 0; n = 0;
...@@ -114,7 +114,7 @@ vwk_thread(void *priv) ...@@ -114,7 +114,7 @@ vwk_thread(void *priv)
for (j = 0; j < n; j++) { for (j = 0; j < n; j++) {
CAST_OBJ_NOTNULL(wp, ke[j].udata, WAITED_MAGIC); CAST_OBJ_NOTNULL(wp, ke[j].udata, WAITED_MAGIC);
VTAILQ_REMOVE(&vwk->list, wp, list); VTAILQ_REMOVE(&vwk->list, wp, list);
vwk->waiter->func(wp, WAITER_TIMEOUT, now); Wait_Call(vwk->waiter, wp, WAITER_TIMEOUT, now);
} }
Lck_Unlock(&vwk->mtx); Lck_Unlock(&vwk->mtx);
} }
......
...@@ -162,12 +162,12 @@ vwp_main(void *priv) ...@@ -162,12 +162,12 @@ vwp_main(void *priv)
while (1) { while (1) {
v = poll(vwp->pollfd, vwp->hpoll, v = poll(vwp->pollfd, vwp->hpoll,
(int)floor(1e3 * *vwp->waiter->tmo)); (int)floor(1e3 * Wait_Tmo(vwp->waiter, NULL)));
assert(v >= 0); assert(v >= 0);
if (v == 0) if (v == 0)
v = vwp->hpoll; v = vwp->hpoll;
now = VTIM_real(); now = VTIM_real();
idle = now - *vwp->waiter->tmo; idle = now - Wait_Tmo(vwp->waiter, NULL);
i = 0; i = 0;
dopipe = 0; dopipe = 0;
while (v > 0 && i < vwp->hpoll) { while (v > 0 && i < vwp->hpoll) {
...@@ -182,12 +182,12 @@ vwp_main(void *priv) ...@@ -182,12 +182,12 @@ vwp_main(void *priv)
wp = vwp->idx[i]; wp = vwp->idx[i];
CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC); CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
if (wp->idle <= idle) { if (wp->idle <= idle) {
vwp->waiter->func(wp, WAITER_TIMEOUT, now); Wait_Call(vwp->waiter, wp, WAITER_TIMEOUT, now);
vwp_del(vwp, i); vwp_del(vwp, i);
} else if (vwp->pollfd[i].revents & POLLIN) { } else if (vwp->pollfd[i].revents & POLLIN) {
assert(wp->fd > 0); assert(wp->fd > 0);
assert(wp->fd == vwp->pollfd[i].fd); assert(wp->fd == vwp->pollfd[i].fd);
vwp->waiter->func(wp, WAITER_ACTION, now); Wait_Call(vwp->waiter, wp, WAITER_ACTION, now);
vwp_del(vwp, i); vwp_del(vwp, i);
} else { } else {
i++; i++;
......
...@@ -42,11 +42,24 @@ ...@@ -42,11 +42,24 @@
* Public interfaces * Public interfaces
*/ */
struct waited;
struct waiter; struct waiter;
/* Connection waiter ------------------------------------------------- enum wait_event {
* Describing a file-descriptor/connection being waited on WAITER_REMCLOSE,
*/ WAITER_TIMEOUT,
WAITER_ACTION,
WAITER_CLOSE
};
typedef void waiter_handle_f(struct waited *, enum wait_event, double now);
struct waitfor {
unsigned magic;
#define WAITFOR_MAGIC 0x16b79246
waiter_handle_f *func;
volatile double *tmo;
};
struct waited { struct waited {
unsigned magic; unsigned magic;
...@@ -57,19 +70,8 @@ struct waited { ...@@ -57,19 +70,8 @@ struct waited {
VTAILQ_ENTRY(waited) list; VTAILQ_ENTRY(waited) list;
}; };
enum wait_event {
WAITER_REMCLOSE,
WAITER_TIMEOUT,
WAITER_ACTION,
WAITER_CLOSE
};
#define WAITER_DEFAULT "platform dependent"
typedef void waiter_handle_f(struct waited *, enum wait_event, double now);
/* cache_waiter.c */ /* cache_waiter.c */
int Wait_Enter(const struct waiter *, struct waited *); int Wait_Enter(const struct waiter *, struct waited *);
struct waiter *Waiter_New(waiter_handle_f *, volatile double *timeout); struct waiter *Waiter_New(struct waitfor *);
void Waiter_Destroy(struct waiter **); void Waiter_Destroy(struct waiter **);
const char *Waiter_GetName(void); const char *Waiter_GetName(void);
...@@ -40,12 +40,10 @@ struct waiter { ...@@ -40,12 +40,10 @@ struct waiter {
int dismantle; int dismantle;
waiter_handle_f * func; struct waitfor *waitfor;
double next_idle; double next_idle;
volatile double *tmo;
void *priv; void *priv;
}; };
...@@ -56,10 +54,31 @@ typedef void waiter_inject_f(const struct waiter *, struct waited *); ...@@ -56,10 +54,31 @@ typedef void waiter_inject_f(const struct waiter *, struct waited *);
typedef void waiter_evict_f(const struct waiter *, struct waited *); typedef void waiter_evict_f(const struct waiter *, struct waited *);
struct waiter_impl { struct waiter_impl {
const char *name; const char *name;
waiter_init_f *init; waiter_init_f *init;
waiter_fini_f *fini; waiter_fini_f *fini;
waiter_enter_f *enter; waiter_enter_f *enter;
waiter_inject_f *inject; waiter_inject_f *inject;
size_t size; size_t size;
}; };
static inline double
Wait_Tmo(const struct waiter *w, const struct waited *wp)
{
CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
CHECK_OBJ_ORNULL(wp, WAITED_MAGIC);
CHECK_OBJ_NOTNULL(w->waitfor, WAITFOR_MAGIC);
AN(w->waitfor->tmo);
return (*w->waitfor->tmo);
}
static inline void
Wait_Call(const struct waiter *w,
struct waited *wp, enum wait_event ev, double now)
{
CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
CHECK_OBJ_NOTNULL(w->waitfor, WAITFOR_MAGIC);
AN(w->waitfor->func);
w->waitfor->func(wp, ev, now);
}
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