redict/deps/hiredict/adapters/redictmoduleapi.h

156 lines
4.4 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_REDICTMODULEAPI_H__
#define __HIREDICT_REDICTMODULEAPI_H__
#include "redictmodule.h"
#include "../async.h"
#include "../hiredict.h"
#include <sys/types.h>
typedef struct redictModuleEvents {
redictAsyncContext *context;
RedictModuleCtx *module_ctx;
int fd;
int reading, writing;
int timer_active;
RedictModuleTimerID timer_id;
} redictModuleEvents;
static inline void redictModuleReadEvent(int fd, void *privdata, int mask) {
(void) fd;
(void) mask;
redictModuleEvents *e = (redictModuleEvents*)privdata;
redictAsyncHandleRead(e->context);
}
static inline void redictModuleWriteEvent(int fd, void *privdata, int mask) {
(void) fd;
(void) mask;
redictModuleEvents *e = (redictModuleEvents*)privdata;
redictAsyncHandleWrite(e->context);
}
static inline void redictModuleAddRead(void *privdata) {
redictModuleEvents *e = (redictModuleEvents*)privdata;
if (!e->reading) {
e->reading = 1;
RedictModule_EventLoopAdd(e->fd, REDICTMODULE_EVENTLOOP_READABLE, redictModuleReadEvent, e);
}
}
static inline void redictModuleDelRead(void *privdata) {
redictModuleEvents *e = (redictModuleEvents*)privdata;
if (e->reading) {
e->reading = 0;
RedictModule_EventLoopDel(e->fd, REDICTMODULE_EVENTLOOP_READABLE);
}
}
static inline void redictModuleAddWrite(void *privdata) {
redictModuleEvents *e = (redictModuleEvents*)privdata;
if (!e->writing) {
e->writing = 1;
RedictModule_EventLoopAdd(e->fd, REDICTMODULE_EVENTLOOP_WRITABLE, redictModuleWriteEvent, e);
}
}
static inline void redictModuleDelWrite(void *privdata) {
redictModuleEvents *e = (redictModuleEvents*)privdata;
if (e->writing) {
e->writing = 0;
RedictModule_EventLoopDel(e->fd, REDICTMODULE_EVENTLOOP_WRITABLE);
}
}
static inline void redictModuleStopTimer(void *privdata) {
redictModuleEvents *e = (redictModuleEvents*)privdata;
if (e->timer_active) {
RedictModule_StopTimer(e->module_ctx, e->timer_id, NULL);
}
e->timer_active = 0;
}
static inline void redictModuleCleanup(void *privdata) {
redictModuleEvents *e = (redictModuleEvents*)privdata;
redictModuleDelRead(privdata);
redictModuleDelWrite(privdata);
redictModuleStopTimer(privdata);
hi_free(e);
}
static inline void redictModuleTimeout(RedictModuleCtx *ctx, void *privdata) {
(void) ctx;
redictModuleEvents *e = (redictModuleEvents*)privdata;
e->timer_active = 0;
redictAsyncHandleTimeout(e->context);
}
static inline void redictModuleSetTimeout(void *privdata, struct timeval tv) {
redictModuleEvents* e = (redictModuleEvents*)privdata;
redictModuleStopTimer(privdata);
mstime_t millis = tv.tv_sec * 1000 + tv.tv_usec / 1000.0;
e->timer_id = RedictModule_CreateTimer(e->module_ctx, millis, redictModuleTimeout, e);
e->timer_active = 1;
}
/* Check if Redict is compatible with the adapter. */
static inline int redictModuleCompatibilityCheck(void) {
if (!RedictModule_EventLoopAdd ||
!RedictModule_EventLoopDel ||
!RedictModule_CreateTimer ||
!RedictModule_StopTimer) {
return REDICT_ERR;
}
return REDICT_OK;
}
static inline int redictModuleAttach(redictAsyncContext *ac, RedictModuleCtx *module_ctx) {
redictContext *c = &(ac->c);
redictModuleEvents *e;
/* Nothing should be attached when something is already attached */
if (ac->ev.data != NULL)
return REDICT_ERR;
/* Create container for context and r/w events */
e = (redictModuleEvents*)hi_malloc(sizeof(*e));
if (e == NULL)
return REDICT_ERR;
e->context = ac;
e->module_ctx = module_ctx;
e->fd = c->fd;
e->reading = e->writing = 0;
e->timer_active = 0;
/* Register functions to start/stop listening for events */
ac->ev.addRead = redictModuleAddRead;
ac->ev.delRead = redictModuleDelRead;
ac->ev.addWrite = redictModuleAddWrite;
ac->ev.delWrite = redictModuleDelWrite;
ac->ev.cleanup = redictModuleCleanup;
ac->ev.scheduleTimer = redictModuleSetTimeout;
ac->ev.data = e;
return REDICT_OK;
}
#endif