summaryrefslogtreecommitdiff
path: root/adapters/ae.h
blob: 1edcd0e9c1b69924a43c26165ebf199880410cdf (plain)
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
/*
 * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
 *
 * 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_AE_H__
#define __HIREDICT_AE_H__
#include <sys/types.h>
#include <ae.h>
#include "../hiredict.h"
#include "../async.h"

typedef struct redictAeEvents {
    redictAsyncContext *context;
    aeEventLoop *loop;
    int fd;
    int reading, writing;
} redictAeEvents;

static void redictAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
    ((void)el); ((void)fd); ((void)mask);

    redictAeEvents *e = (redictAeEvents*)privdata;
    redictAsyncHandleRead(e->context);
}

static void redictAeWriteEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
    ((void)el); ((void)fd); ((void)mask);

    redictAeEvents *e = (redictAeEvents*)privdata;
    redictAsyncHandleWrite(e->context);
}

static void redictAeAddRead(void *privdata) {
    redictAeEvents *e = (redictAeEvents*)privdata;
    aeEventLoop *loop = e->loop;
    if (!e->reading) {
        e->reading = 1;
        aeCreateFileEvent(loop,e->fd,AE_READABLE,redictAeReadEvent,e);
    }
}

static void redictAeDelRead(void *privdata) {
    redictAeEvents *e = (redictAeEvents*)privdata;
    aeEventLoop *loop = e->loop;
    if (e->reading) {
        e->reading = 0;
        aeDeleteFileEvent(loop,e->fd,AE_READABLE);
    }
}

static void redictAeAddWrite(void *privdata) {
    redictAeEvents *e = (redictAeEvents*)privdata;
    aeEventLoop *loop = e->loop;
    if (!e->writing) {
        e->writing = 1;
        aeCreateFileEvent(loop,e->fd,AE_WRITABLE,redictAeWriteEvent,e);
    }
}

static void redictAeDelWrite(void *privdata) {
    redictAeEvents *e = (redictAeEvents*)privdata;
    aeEventLoop *loop = e->loop;
    if (e->writing) {
        e->writing = 0;
        aeDeleteFileEvent(loop,e->fd,AE_WRITABLE);
    }
}

static void redictAeCleanup(void *privdata) {
    redictAeEvents *e = (redictAeEvents*)privdata;
    redictAeDelRead(privdata);
    redictAeDelWrite(privdata);
    hi_free(e);
}

static int redictAeAttach(aeEventLoop *loop, redictAsyncContext *ac) {
    redictContext *c = &(ac->c);
    redictAeEvents *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 = (redictAeEvents*)hi_malloc(sizeof(*e));
    if (e == NULL)
        return REDICT_ERR;

    e->context = ac;
    e->loop = loop;
    e->fd = c->fd;
    e->reading = e->writing = 0;

    /* Register functions to start/stop listening for events */
    ac->ev.addRead = redictAeAddRead;
    ac->ev.delRead = redictAeDelRead;
    ac->ev.addWrite = redictAeAddWrite;
    ac->ev.delWrite = redictAeDelWrite;
    ac->ev.cleanup = redictAeCleanup;
    ac->ev.data = e;

    return REDICT_OK;
}
#endif