1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
/*
* Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
*
* All rights reserved.
*
* SPDX-FileCopyrightText: 2024 Hiredict Contributors
* SPDX-FileCopyrightText: 2024 Pieter Noordhuis <pcnoordhuis at gmail dot com>
*
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: LGPL-3.0-or-later
*
*/
#ifndef __HIREDICT_LIBEV_H__
#define __HIREDICT_LIBEV_H__
#include <stdlib.h>
#include <sys/types.h>
#include <ev.h>
#include "../hiredict.h"
#include "../async.h"
typedef struct redictLibevEvents {
redictAsyncContext *context;
struct ev_loop *loop;
int reading, writing;
ev_io rev, wev;
ev_timer timer;
} redictLibevEvents;
static void redictLibevReadEvent(EV_P_ ev_io *watcher, int revents) {
#if EV_MULTIPLICITY
((void)EV_A);
#endif
((void)revents);
redictLibevEvents *e = (redictLibevEvents*)watcher->data;
redictAsyncHandleRead(e->context);
}
static void redictLibevWriteEvent(EV_P_ ev_io *watcher, int revents) {
#if EV_MULTIPLICITY
((void)EV_A);
#endif
((void)revents);
redictLibevEvents *e = (redictLibevEvents*)watcher->data;
redictAsyncHandleWrite(e->context);
}
static void redictLibevAddRead(void *privdata) {
redictLibevEvents *e = (redictLibevEvents*)privdata;
#if EV_MULTIPLICITY
struct ev_loop *loop = e->loop;
#endif
if (!e->reading) {
e->reading = 1;
ev_io_start(EV_A_ &e->rev);
}
}
static void redictLibevDelRead(void *privdata) {
redictLibevEvents *e = (redictLibevEvents*)privdata;
#if EV_MULTIPLICITY
struct ev_loop *loop = e->loop;
#endif
if (e->reading) {
e->reading = 0;
ev_io_stop(EV_A_ &e->rev);
}
}
static void redictLibevAddWrite(void *privdata) {
redictLibevEvents *e = (redictLibevEvents*)privdata;
#if EV_MULTIPLICITY
struct ev_loop *loop = e->loop;
#endif
if (!e->writing) {
e->writing = 1;
ev_io_start(EV_A_ &e->wev);
}
}
static void redictLibevDelWrite(void *privdata) {
redictLibevEvents *e = (redictLibevEvents*)privdata;
#if EV_MULTIPLICITY
struct ev_loop *loop = e->loop;
#endif
if (e->writing) {
e->writing = 0;
ev_io_stop(EV_A_ &e->wev);
}
}
static void redictLibevStopTimer(void *privdata) {
redictLibevEvents *e = (redictLibevEvents*)privdata;
#if EV_MULTIPLICITY
struct ev_loop *loop = e->loop;
#endif
ev_timer_stop(EV_A_ &e->timer);
}
static void redictLibevCleanup(void *privdata) {
redictLibevEvents *e = (redictLibevEvents*)privdata;
redictLibevDelRead(privdata);
redictLibevDelWrite(privdata);
redictLibevStopTimer(privdata);
hi_free(e);
}
static void redictLibevTimeout(EV_P_ ev_timer *timer, int revents) {
#if EV_MULTIPLICITY
((void)EV_A);
#endif
((void)revents);
redictLibevEvents *e = (redictLibevEvents*)timer->data;
redictAsyncHandleTimeout(e->context);
}
static void redictLibevSetTimeout(void *privdata, struct timeval tv) {
redictLibevEvents *e = (redictLibevEvents*)privdata;
#if EV_MULTIPLICITY
struct ev_loop *loop = e->loop;
#endif
if (!ev_is_active(&e->timer)) {
ev_init(&e->timer, redictLibevTimeout);
e->timer.data = e;
}
e->timer.repeat = tv.tv_sec + tv.tv_usec / 1000000.00;
ev_timer_again(EV_A_ &e->timer);
}
static int redictLibevAttach(EV_P_ redictAsyncContext *ac) {
redictContext *c = &(ac->c);
redictLibevEvents *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 = (redictLibevEvents*)hi_calloc(1, sizeof(*e));
if (e == NULL)
return REDICT_ERR;
e->context = ac;
#if EV_MULTIPLICITY
e->loop = EV_A;
#else
e->loop = NULL;
#endif
e->rev.data = e;
e->wev.data = e;
/* Register functions to start/stop listening for events */
ac->ev.addRead = redictLibevAddRead;
ac->ev.delRead = redictLibevDelRead;
ac->ev.addWrite = redictLibevAddWrite;
ac->ev.delWrite = redictLibevDelWrite;
ac->ev.cleanup = redictLibevCleanup;
ac->ev.scheduleTimer = redictLibevSetTimeout;
ac->ev.data = e;
/* Initialize read/write events */
ev_io_init(&e->rev,redictLibevReadEvent,c->fd,EV_READ);
ev_io_init(&e->wev,redictLibevWriteEvent,c->fd,EV_WRITE);
return REDICT_OK;
}
#endif
|