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