From d5d40f56d6c42f68b1cb278e4500a42283457569 Mon Sep 17 00:00:00 2001 From: michael-grunder Date: Tue, 7 Apr 2020 14:59:07 -0700 Subject: [PATCH 1/2] Support timeouts in libev adapater --- adapters/libev.h | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/adapters/libev.h b/adapters/libev.h index abad43634..6cd4c2135 100644 --- a/adapters/libev.h +++ b/adapters/libev.h @@ -41,6 +41,7 @@ typedef struct redisLibevEvents { struct ev_loop *loop; int reading, writing; ev_io rev, wev; + ev_timer timer; } redisLibevEvents; static void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) { @@ -103,13 +104,41 @@ static void redisLibevDelWrite(void *privdata) { } } +static void redisLibevStopTimer(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + struct ev_loop *loop = e->loop; + ((void)loop); + ev_timer_stop(EV_A_ &e->timer); +} + static void redisLibevCleanup(void *privdata) { redisLibevEvents *e = (redisLibevEvents*)privdata; redisLibevDelRead(privdata); redisLibevDelWrite(privdata); + redisLibevStopTimer(privdata); free(e); } +static void redisLibevTimeout(EV_P_ ev_timer *timer, int revents) { + ((void)revents); + redisLibevEvents *e = timer->data; + redisAsyncHandleTimeout(e->context); +} + +static void redisLibevScheduleTimer(void *privdata, struct timeval tv) { + redisLibevEvents *e = privdata; + struct ev_loop *loop = e->loop; + ((void)loop); + + if (!ev_is_active(&e->timer)) { + ev_init(&e->timer, redisLibevTimeout); + e->timer.data = e; + } + + e->timer.repeat = tv.tv_sec + tv.tv_usec / 1000000.00; + ev_timer_again(EV_A_ &e->timer); +} + static int redisLibevAttach(EV_P_ redisAsyncContext *ac) { redisContext *c = &(ac->c); redisLibevEvents *e; @@ -119,14 +148,13 @@ static int redisLibevAttach(EV_P_ redisAsyncContext *ac) { return REDIS_ERR; /* Create container for context and r/w events */ - e = (redisLibevEvents*)hi_malloc(sizeof(*e)); + e = (redisLibevEvents*)hi_calloc(1, sizeof(*e)); e->context = ac; #if EV_MULTIPLICITY e->loop = loop; #else e->loop = NULL; #endif - e->reading = e->writing = 0; e->rev.data = e; e->wev.data = e; @@ -136,8 +164,13 @@ static int redisLibevAttach(EV_P_ redisAsyncContext *ac) { ac->ev.addWrite = redisLibevAddWrite; ac->ev.delWrite = redisLibevDelWrite; ac->ev.cleanup = redisLibevCleanup; + ac->ev.scheduleTimer = redisLibevScheduleTimer; ac->ev.data = e; + if (ac->c.timeout->tv_sec != 0 || ac->c.timeout->tv_usec != 0) { + redisLibevScheduleTimer(e, *ac->c.timeout); + } + /* Initialize read/write events */ ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ); ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE); From cd0a978ffeecaeff895c25390b28b9aba384a9b5 Mon Sep 17 00:00:00 2001 From: michael-grunder Date: Mon, 27 Apr 2020 11:12:04 -0700 Subject: [PATCH 2/2] Consistency with libevent adapter * Change timeout scheduling function name to redisLibevSetTimeout to align with redisLibevSetTimeout. * Stop scheduling timer on attach to align with what our libevent adapter does. See #795 --- adapters/libev.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/adapters/libev.h b/adapters/libev.h index 6cd4c2135..1520923e2 100644 --- a/adapters/libev.h +++ b/adapters/libev.h @@ -125,7 +125,7 @@ static void redisLibevTimeout(EV_P_ ev_timer *timer, int revents) { redisAsyncHandleTimeout(e->context); } -static void redisLibevScheduleTimer(void *privdata, struct timeval tv) { +static void redisLibevSetTimeout(void *privdata, struct timeval tv) { redisLibevEvents *e = privdata; struct ev_loop *loop = e->loop; ((void)loop); @@ -164,13 +164,9 @@ static int redisLibevAttach(EV_P_ redisAsyncContext *ac) { ac->ev.addWrite = redisLibevAddWrite; ac->ev.delWrite = redisLibevDelWrite; ac->ev.cleanup = redisLibevCleanup; - ac->ev.scheduleTimer = redisLibevScheduleTimer; + ac->ev.scheduleTimer = redisLibevSetTimeout; ac->ev.data = e; - if (ac->c.timeout->tv_sec != 0 || ac->c.timeout->tv_usec != 0) { - redisLibevScheduleTimer(e, *ac->c.timeout); - } - /* Initialize read/write events */ ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ); ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE);