redict/deps/hiredict/adapters/libhv.h

135 lines
3.7 KiB
C

/*
* Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
*
* SPDX-FileCopyrightText: 2024 Hiredict Contributors
* SPDX-FileCopyrightText: 2024 Salvatore Sanfilippo <antirez at gmail dot com>
*
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: LGPL-3.0-or-later
*
*/
#ifndef __HIREDICT_LIBHV_H__
#define __HIREDICT_LIBHV_H__
#include <hv/hloop.h>
#include "../hiredict.h"
#include "../async.h"
typedef struct redictLibhvEvents {
hio_t *io;
htimer_t *timer;
} redictLibhvEvents;
static void redictLibhvHandleEvents(hio_t* io) {
redictAsyncContext* context = (redictAsyncContext*)hevent_userdata(io);
int events = hio_events(io);
int revents = hio_revents(io);
if (context && (events & HV_READ) && (revents & HV_READ)) {
redictAsyncHandleRead(context);
}
if (context && (events & HV_WRITE) && (revents & HV_WRITE)) {
redictAsyncHandleWrite(context);
}
}
static void redictLibhvAddRead(void *privdata) {
redictLibhvEvents* events = (redictLibhvEvents*)privdata;
hio_add(events->io, redictLibhvHandleEvents, HV_READ);
}
static void redictLibhvDelRead(void *privdata) {
redictLibhvEvents* events = (redictLibhvEvents*)privdata;
hio_del(events->io, HV_READ);
}
static void redictLibhvAddWrite(void *privdata) {
redictLibhvEvents* events = (redictLibhvEvents*)privdata;
hio_add(events->io, redictLibhvHandleEvents, HV_WRITE);
}
static void redictLibhvDelWrite(void *privdata) {
redictLibhvEvents* events = (redictLibhvEvents*)privdata;
hio_del(events->io, HV_WRITE);
}
static void redictLibhvCleanup(void *privdata) {
redictLibhvEvents* events = (redictLibhvEvents*)privdata;
if (events->timer)
htimer_del(events->timer);
hio_close(events->io);
hevent_set_userdata(events->io, NULL);
hi_free(events);
}
static void redictLibhvTimeout(htimer_t* timer) {
hio_t* io = (hio_t*)hevent_userdata(timer);
redictAsyncHandleTimeout((redictAsyncContext*)hevent_userdata(io));
}
static void redictLibhvSetTimeout(void *privdata, struct timeval tv) {
redictLibhvEvents* events;
uint32_t millis;
hloop_t* loop;
events = (redictLibhvEvents*)privdata;
millis = tv.tv_sec * 1000 + tv.tv_usec / 1000;
if (millis == 0) {
/* Libhv disallows zero'd timers so treat this as a delete or NO OP */
if (events->timer) {
htimer_del(events->timer);
events->timer = NULL;
}
} else if (events->timer == NULL) {
/* Add new timer */
loop = hevent_loop(events->io);
events->timer = htimer_add(loop, redictLibhvTimeout, millis, 1);
hevent_set_userdata(events->timer, events->io);
} else {
/* Update existing timer */
htimer_reset(events->timer, millis);
}
}
static int redictLibhvAttach(redictAsyncContext* ac, hloop_t* loop) {
redictContext *c = &(ac->c);
redictLibhvEvents *events;
hio_t* io = NULL;
if (ac->ev.data != NULL) {
return REDICT_ERR;
}
/* Create container struct to keep track of our io and any timer */
events = (redictLibhvEvents*)hi_malloc(sizeof(*events));
if (events == NULL) {
return REDICT_ERR;
}
io = hio_get(loop, c->fd);
if (io == NULL) {
hi_free(events);
return REDICT_ERR;
}
hevent_set_userdata(io, ac);
events->io = io;
events->timer = NULL;
ac->ev.addRead = redictLibhvAddRead;
ac->ev.delRead = redictLibhvDelRead;
ac->ev.addWrite = redictLibhvAddWrite;
ac->ev.delWrite = redictLibhvDelWrite;
ac->ev.cleanup = redictLibhvCleanup;
ac->ev.scheduleTimer = redictLibhvSetTimeout;
ac->ev.data = events;
return REDICT_OK;
}
#endif