diff options
| author | Mitja Felicijan <mitja.felicijan@gmail.com> | 2026-01-21 22:40:55 +0100 |
|---|---|---|
| committer | Mitja Felicijan <mitja.felicijan@gmail.com> | 2026-01-21 22:40:55 +0100 |
| commit | 5d8dfe892a2ea89f706ee140c3bdcfd89fe03fda (patch) | |
| tree | 1acdfa5220cd13b7be43a2a01368e80d306473ca /examples/redis-unstable/deps/hiredis/adapters | |
| parent | c7ab12bba64d9c20ccd79b132dac475f7bc3923e (diff) | |
| download | crep-5d8dfe892a2ea89f706ee140c3bdcfd89fe03fda.tar.gz | |
Add Redis source code for testing
Diffstat (limited to 'examples/redis-unstable/deps/hiredis/adapters')
| -rw-r--r-- | examples/redis-unstable/deps/hiredis/adapters/ae.h | 130 | ||||
| -rw-r--r-- | examples/redis-unstable/deps/hiredis/adapters/glib.h | 156 | ||||
| -rw-r--r-- | examples/redis-unstable/deps/hiredis/adapters/ivykis.h | 84 | ||||
| -rw-r--r-- | examples/redis-unstable/deps/hiredis/adapters/libev.h | 188 | ||||
| -rw-r--r-- | examples/redis-unstable/deps/hiredis/adapters/libevent.h | 175 | ||||
| -rw-r--r-- | examples/redis-unstable/deps/hiredis/adapters/libhv.h | 123 | ||||
| -rw-r--r-- | examples/redis-unstable/deps/hiredis/adapters/libsdevent.h | 177 | ||||
| -rw-r--r-- | examples/redis-unstable/deps/hiredis/adapters/libuv.h | 171 | ||||
| -rw-r--r-- | examples/redis-unstable/deps/hiredis/adapters/macosx.h | 115 | ||||
| -rw-r--r-- | examples/redis-unstable/deps/hiredis/adapters/poll.h | 197 | ||||
| -rw-r--r-- | examples/redis-unstable/deps/hiredis/adapters/qt.h | 135 | ||||
| -rw-r--r-- | examples/redis-unstable/deps/hiredis/adapters/redismoduleapi.h | 144 |
12 files changed, 1795 insertions, 0 deletions
diff --git a/examples/redis-unstable/deps/hiredis/adapters/ae.h b/examples/redis-unstable/deps/hiredis/adapters/ae.h new file mode 100644 index 0000000..660d82e --- /dev/null +++ b/examples/redis-unstable/deps/hiredis/adapters/ae.h | |||
| @@ -0,0 +1,130 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com> | ||
| 3 | * | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions are met: | ||
| 8 | * | ||
| 9 | * * Redistributions of source code must retain the above copyright notice, | ||
| 10 | * this list of conditions and the following disclaimer. | ||
| 11 | * * Redistributions in binary form must reproduce the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer in the | ||
| 13 | * documentation and/or other materials provided with the distribution. | ||
| 14 | * * Neither the name of Redis nor the names of its contributors may be used | ||
| 15 | * to endorse or promote products derived from this software without | ||
| 16 | * specific prior written permission. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
| 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
| 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
| 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
| 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 28 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #ifndef __HIREDIS_AE_H__ | ||
| 32 | #define __HIREDIS_AE_H__ | ||
| 33 | #include <sys/types.h> | ||
| 34 | #include <ae.h> | ||
| 35 | #include "../hiredis.h" | ||
| 36 | #include "../async.h" | ||
| 37 | |||
| 38 | typedef struct redisAeEvents { | ||
| 39 | redisAsyncContext *context; | ||
| 40 | aeEventLoop *loop; | ||
| 41 | int fd; | ||
| 42 | int reading, writing; | ||
| 43 | } redisAeEvents; | ||
| 44 | |||
| 45 | static void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) { | ||
| 46 | ((void)el); ((void)fd); ((void)mask); | ||
| 47 | |||
| 48 | redisAeEvents *e = (redisAeEvents*)privdata; | ||
| 49 | redisAsyncHandleRead(e->context); | ||
| 50 | } | ||
| 51 | |||
| 52 | static void redisAeWriteEvent(aeEventLoop *el, int fd, void *privdata, int mask) { | ||
| 53 | ((void)el); ((void)fd); ((void)mask); | ||
| 54 | |||
| 55 | redisAeEvents *e = (redisAeEvents*)privdata; | ||
| 56 | redisAsyncHandleWrite(e->context); | ||
| 57 | } | ||
| 58 | |||
| 59 | static void redisAeAddRead(void *privdata) { | ||
| 60 | redisAeEvents *e = (redisAeEvents*)privdata; | ||
| 61 | aeEventLoop *loop = e->loop; | ||
| 62 | if (!e->reading) { | ||
| 63 | e->reading = 1; | ||
| 64 | aeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e); | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | static void redisAeDelRead(void *privdata) { | ||
| 69 | redisAeEvents *e = (redisAeEvents*)privdata; | ||
| 70 | aeEventLoop *loop = e->loop; | ||
| 71 | if (e->reading) { | ||
| 72 | e->reading = 0; | ||
| 73 | aeDeleteFileEvent(loop,e->fd,AE_READABLE); | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | static void redisAeAddWrite(void *privdata) { | ||
| 78 | redisAeEvents *e = (redisAeEvents*)privdata; | ||
| 79 | aeEventLoop *loop = e->loop; | ||
| 80 | if (!e->writing) { | ||
| 81 | e->writing = 1; | ||
| 82 | aeCreateFileEvent(loop,e->fd,AE_WRITABLE,redisAeWriteEvent,e); | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | static void redisAeDelWrite(void *privdata) { | ||
| 87 | redisAeEvents *e = (redisAeEvents*)privdata; | ||
| 88 | aeEventLoop *loop = e->loop; | ||
| 89 | if (e->writing) { | ||
| 90 | e->writing = 0; | ||
| 91 | aeDeleteFileEvent(loop,e->fd,AE_WRITABLE); | ||
| 92 | } | ||
| 93 | } | ||
| 94 | |||
| 95 | static void redisAeCleanup(void *privdata) { | ||
| 96 | redisAeEvents *e = (redisAeEvents*)privdata; | ||
| 97 | redisAeDelRead(privdata); | ||
| 98 | redisAeDelWrite(privdata); | ||
| 99 | hi_free(e); | ||
| 100 | } | ||
| 101 | |||
| 102 | static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) { | ||
| 103 | redisContext *c = &(ac->c); | ||
| 104 | redisAeEvents *e; | ||
| 105 | |||
| 106 | /* Nothing should be attached when something is already attached */ | ||
| 107 | if (ac->ev.data != NULL) | ||
| 108 | return REDIS_ERR; | ||
| 109 | |||
| 110 | /* Create container for context and r/w events */ | ||
| 111 | e = (redisAeEvents*)hi_malloc(sizeof(*e)); | ||
| 112 | if (e == NULL) | ||
| 113 | return REDIS_ERR; | ||
| 114 | |||
| 115 | e->context = ac; | ||
| 116 | e->loop = loop; | ||
| 117 | e->fd = c->fd; | ||
| 118 | e->reading = e->writing = 0; | ||
| 119 | |||
| 120 | /* Register functions to start/stop listening for events */ | ||
| 121 | ac->ev.addRead = redisAeAddRead; | ||
| 122 | ac->ev.delRead = redisAeDelRead; | ||
| 123 | ac->ev.addWrite = redisAeAddWrite; | ||
| 124 | ac->ev.delWrite = redisAeDelWrite; | ||
| 125 | ac->ev.cleanup = redisAeCleanup; | ||
| 126 | ac->ev.data = e; | ||
| 127 | |||
| 128 | return REDIS_OK; | ||
| 129 | } | ||
| 130 | #endif | ||
diff --git a/examples/redis-unstable/deps/hiredis/adapters/glib.h b/examples/redis-unstable/deps/hiredis/adapters/glib.h new file mode 100644 index 0000000..ad59dd1 --- /dev/null +++ b/examples/redis-unstable/deps/hiredis/adapters/glib.h | |||
| @@ -0,0 +1,156 @@ | |||
| 1 | #ifndef __HIREDIS_GLIB_H__ | ||
| 2 | #define __HIREDIS_GLIB_H__ | ||
| 3 | |||
| 4 | #include <glib.h> | ||
| 5 | |||
| 6 | #include "../hiredis.h" | ||
| 7 | #include "../async.h" | ||
| 8 | |||
| 9 | typedef struct | ||
| 10 | { | ||
| 11 | GSource source; | ||
| 12 | redisAsyncContext *ac; | ||
| 13 | GPollFD poll_fd; | ||
| 14 | } RedisSource; | ||
| 15 | |||
| 16 | static void | ||
| 17 | redis_source_add_read (gpointer data) | ||
| 18 | { | ||
| 19 | RedisSource *source = (RedisSource *)data; | ||
| 20 | g_return_if_fail(source); | ||
| 21 | source->poll_fd.events |= G_IO_IN; | ||
| 22 | g_main_context_wakeup(g_source_get_context((GSource *)data)); | ||
| 23 | } | ||
| 24 | |||
| 25 | static void | ||
| 26 | redis_source_del_read (gpointer data) | ||
| 27 | { | ||
| 28 | RedisSource *source = (RedisSource *)data; | ||
| 29 | g_return_if_fail(source); | ||
| 30 | source->poll_fd.events &= ~G_IO_IN; | ||
| 31 | g_main_context_wakeup(g_source_get_context((GSource *)data)); | ||
| 32 | } | ||
| 33 | |||
| 34 | static void | ||
| 35 | redis_source_add_write (gpointer data) | ||
| 36 | { | ||
| 37 | RedisSource *source = (RedisSource *)data; | ||
| 38 | g_return_if_fail(source); | ||
| 39 | source->poll_fd.events |= G_IO_OUT; | ||
| 40 | g_main_context_wakeup(g_source_get_context((GSource *)data)); | ||
| 41 | } | ||
| 42 | |||
| 43 | static void | ||
| 44 | redis_source_del_write (gpointer data) | ||
| 45 | { | ||
| 46 | RedisSource *source = (RedisSource *)data; | ||
| 47 | g_return_if_fail(source); | ||
| 48 | source->poll_fd.events &= ~G_IO_OUT; | ||
| 49 | g_main_context_wakeup(g_source_get_context((GSource *)data)); | ||
| 50 | } | ||
| 51 | |||
| 52 | static void | ||
| 53 | redis_source_cleanup (gpointer data) | ||
| 54 | { | ||
| 55 | RedisSource *source = (RedisSource *)data; | ||
| 56 | |||
| 57 | g_return_if_fail(source); | ||
| 58 | |||
| 59 | redis_source_del_read(source); | ||
| 60 | redis_source_del_write(source); | ||
| 61 | /* | ||
| 62 | * It is not our responsibility to remove ourself from the | ||
| 63 | * current main loop. However, we will remove the GPollFD. | ||
| 64 | */ | ||
| 65 | if (source->poll_fd.fd >= 0) { | ||
| 66 | g_source_remove_poll((GSource *)data, &source->poll_fd); | ||
| 67 | source->poll_fd.fd = -1; | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | static gboolean | ||
| 72 | redis_source_prepare (GSource *source, | ||
| 73 | gint *timeout_) | ||
| 74 | { | ||
| 75 | RedisSource *redis = (RedisSource *)source; | ||
| 76 | *timeout_ = -1; | ||
| 77 | return !!(redis->poll_fd.events & redis->poll_fd.revents); | ||
| 78 | } | ||
| 79 | |||
| 80 | static gboolean | ||
| 81 | redis_source_check (GSource *source) | ||
| 82 | { | ||
| 83 | RedisSource *redis = (RedisSource *)source; | ||
| 84 | return !!(redis->poll_fd.events & redis->poll_fd.revents); | ||
| 85 | } | ||
| 86 | |||
| 87 | static gboolean | ||
| 88 | redis_source_dispatch (GSource *source, | ||
| 89 | GSourceFunc callback, | ||
| 90 | gpointer user_data) | ||
| 91 | { | ||
| 92 | RedisSource *redis = (RedisSource *)source; | ||
| 93 | |||
| 94 | if ((redis->poll_fd.revents & G_IO_OUT)) { | ||
| 95 | redisAsyncHandleWrite(redis->ac); | ||
| 96 | redis->poll_fd.revents &= ~G_IO_OUT; | ||
| 97 | } | ||
| 98 | |||
| 99 | if ((redis->poll_fd.revents & G_IO_IN)) { | ||
| 100 | redisAsyncHandleRead(redis->ac); | ||
| 101 | redis->poll_fd.revents &= ~G_IO_IN; | ||
| 102 | } | ||
| 103 | |||
| 104 | if (callback) { | ||
| 105 | return callback(user_data); | ||
| 106 | } | ||
| 107 | |||
| 108 | return TRUE; | ||
| 109 | } | ||
| 110 | |||
| 111 | static void | ||
| 112 | redis_source_finalize (GSource *source) | ||
| 113 | { | ||
| 114 | RedisSource *redis = (RedisSource *)source; | ||
| 115 | |||
| 116 | if (redis->poll_fd.fd >= 0) { | ||
| 117 | g_source_remove_poll(source, &redis->poll_fd); | ||
| 118 | redis->poll_fd.fd = -1; | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | static GSource * | ||
| 123 | redis_source_new (redisAsyncContext *ac) | ||
| 124 | { | ||
| 125 | static GSourceFuncs source_funcs = { | ||
| 126 | .prepare = redis_source_prepare, | ||
| 127 | .check = redis_source_check, | ||
| 128 | .dispatch = redis_source_dispatch, | ||
| 129 | .finalize = redis_source_finalize, | ||
| 130 | }; | ||
| 131 | redisContext *c = &ac->c; | ||
| 132 | RedisSource *source; | ||
| 133 | |||
| 134 | g_return_val_if_fail(ac != NULL, NULL); | ||
| 135 | |||
| 136 | source = (RedisSource *)g_source_new(&source_funcs, sizeof *source); | ||
| 137 | if (source == NULL) | ||
| 138 | return NULL; | ||
| 139 | |||
| 140 | source->ac = ac; | ||
| 141 | source->poll_fd.fd = c->fd; | ||
| 142 | source->poll_fd.events = 0; | ||
| 143 | source->poll_fd.revents = 0; | ||
| 144 | g_source_add_poll((GSource *)source, &source->poll_fd); | ||
| 145 | |||
| 146 | ac->ev.addRead = redis_source_add_read; | ||
| 147 | ac->ev.delRead = redis_source_del_read; | ||
| 148 | ac->ev.addWrite = redis_source_add_write; | ||
| 149 | ac->ev.delWrite = redis_source_del_write; | ||
| 150 | ac->ev.cleanup = redis_source_cleanup; | ||
| 151 | ac->ev.data = source; | ||
| 152 | |||
| 153 | return (GSource *)source; | ||
| 154 | } | ||
| 155 | |||
| 156 | #endif /* __HIREDIS_GLIB_H__ */ | ||
diff --git a/examples/redis-unstable/deps/hiredis/adapters/ivykis.h b/examples/redis-unstable/deps/hiredis/adapters/ivykis.h new file mode 100644 index 0000000..179f6ab --- /dev/null +++ b/examples/redis-unstable/deps/hiredis/adapters/ivykis.h | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | #ifndef __HIREDIS_IVYKIS_H__ | ||
| 2 | #define __HIREDIS_IVYKIS_H__ | ||
| 3 | #include <iv.h> | ||
| 4 | #include "../hiredis.h" | ||
| 5 | #include "../async.h" | ||
| 6 | |||
| 7 | typedef struct redisIvykisEvents { | ||
| 8 | redisAsyncContext *context; | ||
| 9 | struct iv_fd fd; | ||
| 10 | } redisIvykisEvents; | ||
| 11 | |||
| 12 | static void redisIvykisReadEvent(void *arg) { | ||
| 13 | redisAsyncContext *context = (redisAsyncContext *)arg; | ||
| 14 | redisAsyncHandleRead(context); | ||
| 15 | } | ||
| 16 | |||
| 17 | static void redisIvykisWriteEvent(void *arg) { | ||
| 18 | redisAsyncContext *context = (redisAsyncContext *)arg; | ||
| 19 | redisAsyncHandleWrite(context); | ||
| 20 | } | ||
| 21 | |||
| 22 | static void redisIvykisAddRead(void *privdata) { | ||
| 23 | redisIvykisEvents *e = (redisIvykisEvents*)privdata; | ||
| 24 | iv_fd_set_handler_in(&e->fd, redisIvykisReadEvent); | ||
| 25 | } | ||
| 26 | |||
| 27 | static void redisIvykisDelRead(void *privdata) { | ||
| 28 | redisIvykisEvents *e = (redisIvykisEvents*)privdata; | ||
| 29 | iv_fd_set_handler_in(&e->fd, NULL); | ||
| 30 | } | ||
| 31 | |||
| 32 | static void redisIvykisAddWrite(void *privdata) { | ||
| 33 | redisIvykisEvents *e = (redisIvykisEvents*)privdata; | ||
| 34 | iv_fd_set_handler_out(&e->fd, redisIvykisWriteEvent); | ||
| 35 | } | ||
| 36 | |||
| 37 | static void redisIvykisDelWrite(void *privdata) { | ||
| 38 | redisIvykisEvents *e = (redisIvykisEvents*)privdata; | ||
| 39 | iv_fd_set_handler_out(&e->fd, NULL); | ||
| 40 | } | ||
| 41 | |||
| 42 | static void redisIvykisCleanup(void *privdata) { | ||
| 43 | redisIvykisEvents *e = (redisIvykisEvents*)privdata; | ||
| 44 | |||
| 45 | iv_fd_unregister(&e->fd); | ||
| 46 | hi_free(e); | ||
| 47 | } | ||
| 48 | |||
| 49 | static int redisIvykisAttach(redisAsyncContext *ac) { | ||
| 50 | redisContext *c = &(ac->c); | ||
| 51 | redisIvykisEvents *e; | ||
| 52 | |||
| 53 | /* Nothing should be attached when something is already attached */ | ||
| 54 | if (ac->ev.data != NULL) | ||
| 55 | return REDIS_ERR; | ||
| 56 | |||
| 57 | /* Create container for context and r/w events */ | ||
| 58 | e = (redisIvykisEvents*)hi_malloc(sizeof(*e)); | ||
| 59 | if (e == NULL) | ||
| 60 | return REDIS_ERR; | ||
| 61 | |||
| 62 | e->context = ac; | ||
| 63 | |||
| 64 | /* Register functions to start/stop listening for events */ | ||
| 65 | ac->ev.addRead = redisIvykisAddRead; | ||
| 66 | ac->ev.delRead = redisIvykisDelRead; | ||
| 67 | ac->ev.addWrite = redisIvykisAddWrite; | ||
| 68 | ac->ev.delWrite = redisIvykisDelWrite; | ||
| 69 | ac->ev.cleanup = redisIvykisCleanup; | ||
| 70 | ac->ev.data = e; | ||
| 71 | |||
| 72 | /* Initialize and install read/write events */ | ||
| 73 | IV_FD_INIT(&e->fd); | ||
| 74 | e->fd.fd = c->fd; | ||
| 75 | e->fd.handler_in = redisIvykisReadEvent; | ||
| 76 | e->fd.handler_out = redisIvykisWriteEvent; | ||
| 77 | e->fd.handler_err = NULL; | ||
| 78 | e->fd.cookie = e->context; | ||
| 79 | |||
| 80 | iv_fd_register(&e->fd); | ||
| 81 | |||
| 82 | return REDIS_OK; | ||
| 83 | } | ||
| 84 | #endif | ||
diff --git a/examples/redis-unstable/deps/hiredis/adapters/libev.h b/examples/redis-unstable/deps/hiredis/adapters/libev.h new file mode 100644 index 0000000..c59d3da --- /dev/null +++ b/examples/redis-unstable/deps/hiredis/adapters/libev.h | |||
| @@ -0,0 +1,188 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com> | ||
| 3 | * | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions are met: | ||
| 8 | * | ||
| 9 | * * Redistributions of source code must retain the above copyright notice, | ||
| 10 | * this list of conditions and the following disclaimer. | ||
| 11 | * * Redistributions in binary form must reproduce the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer in the | ||
| 13 | * documentation and/or other materials provided with the distribution. | ||
| 14 | * * Neither the name of Redis nor the names of its contributors may be used | ||
| 15 | * to endorse or promote products derived from this software without | ||
| 16 | * specific prior written permission. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
| 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
| 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
| 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
| 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 28 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #ifndef __HIREDIS_LIBEV_H__ | ||
| 32 | #define __HIREDIS_LIBEV_H__ | ||
| 33 | #include <stdlib.h> | ||
| 34 | #include <sys/types.h> | ||
| 35 | #include <ev.h> | ||
| 36 | #include "../hiredis.h" | ||
| 37 | #include "../async.h" | ||
| 38 | |||
| 39 | typedef struct redisLibevEvents { | ||
| 40 | redisAsyncContext *context; | ||
| 41 | struct ev_loop *loop; | ||
| 42 | int reading, writing; | ||
| 43 | ev_io rev, wev; | ||
| 44 | ev_timer timer; | ||
| 45 | } redisLibevEvents; | ||
| 46 | |||
| 47 | static void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) { | ||
| 48 | #if EV_MULTIPLICITY | ||
| 49 | ((void)EV_A); | ||
| 50 | #endif | ||
| 51 | ((void)revents); | ||
| 52 | |||
| 53 | redisLibevEvents *e = (redisLibevEvents*)watcher->data; | ||
| 54 | redisAsyncHandleRead(e->context); | ||
| 55 | } | ||
| 56 | |||
| 57 | static void redisLibevWriteEvent(EV_P_ ev_io *watcher, int revents) { | ||
| 58 | #if EV_MULTIPLICITY | ||
| 59 | ((void)EV_A); | ||
| 60 | #endif | ||
| 61 | ((void)revents); | ||
| 62 | |||
| 63 | redisLibevEvents *e = (redisLibevEvents*)watcher->data; | ||
| 64 | redisAsyncHandleWrite(e->context); | ||
| 65 | } | ||
| 66 | |||
| 67 | static void redisLibevAddRead(void *privdata) { | ||
| 68 | redisLibevEvents *e = (redisLibevEvents*)privdata; | ||
| 69 | #if EV_MULTIPLICITY | ||
| 70 | struct ev_loop *loop = e->loop; | ||
| 71 | #endif | ||
| 72 | if (!e->reading) { | ||
| 73 | e->reading = 1; | ||
| 74 | ev_io_start(EV_A_ &e->rev); | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | static void redisLibevDelRead(void *privdata) { | ||
| 79 | redisLibevEvents *e = (redisLibevEvents*)privdata; | ||
| 80 | #if EV_MULTIPLICITY | ||
| 81 | struct ev_loop *loop = e->loop; | ||
| 82 | #endif | ||
| 83 | if (e->reading) { | ||
| 84 | e->reading = 0; | ||
| 85 | ev_io_stop(EV_A_ &e->rev); | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | static void redisLibevAddWrite(void *privdata) { | ||
| 90 | redisLibevEvents *e = (redisLibevEvents*)privdata; | ||
| 91 | #if EV_MULTIPLICITY | ||
| 92 | struct ev_loop *loop = e->loop; | ||
| 93 | #endif | ||
| 94 | if (!e->writing) { | ||
| 95 | e->writing = 1; | ||
| 96 | ev_io_start(EV_A_ &e->wev); | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | static void redisLibevDelWrite(void *privdata) { | ||
| 101 | redisLibevEvents *e = (redisLibevEvents*)privdata; | ||
| 102 | #if EV_MULTIPLICITY | ||
| 103 | struct ev_loop *loop = e->loop; | ||
| 104 | #endif | ||
| 105 | if (e->writing) { | ||
| 106 | e->writing = 0; | ||
| 107 | ev_io_stop(EV_A_ &e->wev); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | static void redisLibevStopTimer(void *privdata) { | ||
| 112 | redisLibevEvents *e = (redisLibevEvents*)privdata; | ||
| 113 | #if EV_MULTIPLICITY | ||
| 114 | struct ev_loop *loop = e->loop; | ||
| 115 | #endif | ||
| 116 | ev_timer_stop(EV_A_ &e->timer); | ||
| 117 | } | ||
| 118 | |||
| 119 | static void redisLibevCleanup(void *privdata) { | ||
| 120 | redisLibevEvents *e = (redisLibevEvents*)privdata; | ||
| 121 | redisLibevDelRead(privdata); | ||
| 122 | redisLibevDelWrite(privdata); | ||
| 123 | redisLibevStopTimer(privdata); | ||
| 124 | hi_free(e); | ||
| 125 | } | ||
| 126 | |||
| 127 | static void redisLibevTimeout(EV_P_ ev_timer *timer, int revents) { | ||
| 128 | #if EV_MULTIPLICITY | ||
| 129 | ((void)EV_A); | ||
| 130 | #endif | ||
| 131 | ((void)revents); | ||
| 132 | redisLibevEvents *e = (redisLibevEvents*)timer->data; | ||
| 133 | redisAsyncHandleTimeout(e->context); | ||
| 134 | } | ||
| 135 | |||
| 136 | static void redisLibevSetTimeout(void *privdata, struct timeval tv) { | ||
| 137 | redisLibevEvents *e = (redisLibevEvents*)privdata; | ||
| 138 | #if EV_MULTIPLICITY | ||
| 139 | struct ev_loop *loop = e->loop; | ||
| 140 | #endif | ||
| 141 | |||
| 142 | if (!ev_is_active(&e->timer)) { | ||
| 143 | ev_init(&e->timer, redisLibevTimeout); | ||
| 144 | e->timer.data = e; | ||
| 145 | } | ||
| 146 | |||
| 147 | e->timer.repeat = tv.tv_sec + tv.tv_usec / 1000000.00; | ||
| 148 | ev_timer_again(EV_A_ &e->timer); | ||
| 149 | } | ||
| 150 | |||
| 151 | static int redisLibevAttach(EV_P_ redisAsyncContext *ac) { | ||
| 152 | redisContext *c = &(ac->c); | ||
| 153 | redisLibevEvents *e; | ||
| 154 | |||
| 155 | /* Nothing should be attached when something is already attached */ | ||
| 156 | if (ac->ev.data != NULL) | ||
| 157 | return REDIS_ERR; | ||
| 158 | |||
| 159 | /* Create container for context and r/w events */ | ||
| 160 | e = (redisLibevEvents*)hi_calloc(1, sizeof(*e)); | ||
| 161 | if (e == NULL) | ||
| 162 | return REDIS_ERR; | ||
| 163 | |||
| 164 | e->context = ac; | ||
| 165 | #if EV_MULTIPLICITY | ||
| 166 | e->loop = EV_A; | ||
| 167 | #else | ||
| 168 | e->loop = NULL; | ||
| 169 | #endif | ||
| 170 | e->rev.data = e; | ||
| 171 | e->wev.data = e; | ||
| 172 | |||
| 173 | /* Register functions to start/stop listening for events */ | ||
| 174 | ac->ev.addRead = redisLibevAddRead; | ||
| 175 | ac->ev.delRead = redisLibevDelRead; | ||
| 176 | ac->ev.addWrite = redisLibevAddWrite; | ||
| 177 | ac->ev.delWrite = redisLibevDelWrite; | ||
| 178 | ac->ev.cleanup = redisLibevCleanup; | ||
| 179 | ac->ev.scheduleTimer = redisLibevSetTimeout; | ||
| 180 | ac->ev.data = e; | ||
| 181 | |||
| 182 | /* Initialize read/write events */ | ||
| 183 | ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ); | ||
| 184 | ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE); | ||
| 185 | return REDIS_OK; | ||
| 186 | } | ||
| 187 | |||
| 188 | #endif | ||
diff --git a/examples/redis-unstable/deps/hiredis/adapters/libevent.h b/examples/redis-unstable/deps/hiredis/adapters/libevent.h new file mode 100644 index 0000000..73bb8ed --- /dev/null +++ b/examples/redis-unstable/deps/hiredis/adapters/libevent.h | |||
| @@ -0,0 +1,175 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com> | ||
| 3 | * | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions are met: | ||
| 8 | * | ||
| 9 | * * Redistributions of source code must retain the above copyright notice, | ||
| 10 | * this list of conditions and the following disclaimer. | ||
| 11 | * * Redistributions in binary form must reproduce the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer in the | ||
| 13 | * documentation and/or other materials provided with the distribution. | ||
| 14 | * * Neither the name of Redis nor the names of its contributors may be used | ||
| 15 | * to endorse or promote products derived from this software without | ||
| 16 | * specific prior written permission. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
| 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
| 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
| 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
| 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 28 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #ifndef __HIREDIS_LIBEVENT_H__ | ||
| 32 | #define __HIREDIS_LIBEVENT_H__ | ||
| 33 | #include <event2/event.h> | ||
| 34 | #include "../hiredis.h" | ||
| 35 | #include "../async.h" | ||
| 36 | |||
| 37 | #define REDIS_LIBEVENT_DELETED 0x01 | ||
| 38 | #define REDIS_LIBEVENT_ENTERED 0x02 | ||
| 39 | |||
| 40 | typedef struct redisLibeventEvents { | ||
| 41 | redisAsyncContext *context; | ||
| 42 | struct event *ev; | ||
| 43 | struct event_base *base; | ||
| 44 | struct timeval tv; | ||
| 45 | short flags; | ||
| 46 | short state; | ||
| 47 | } redisLibeventEvents; | ||
| 48 | |||
| 49 | static void redisLibeventDestroy(redisLibeventEvents *e) { | ||
| 50 | hi_free(e); | ||
| 51 | } | ||
| 52 | |||
| 53 | static void redisLibeventHandler(evutil_socket_t fd, short event, void *arg) { | ||
| 54 | ((void)fd); | ||
| 55 | redisLibeventEvents *e = (redisLibeventEvents*)arg; | ||
| 56 | e->state |= REDIS_LIBEVENT_ENTERED; | ||
| 57 | |||
| 58 | #define CHECK_DELETED() if (e->state & REDIS_LIBEVENT_DELETED) {\ | ||
| 59 | redisLibeventDestroy(e);\ | ||
| 60 | return; \ | ||
| 61 | } | ||
| 62 | |||
| 63 | if ((event & EV_TIMEOUT) && (e->state & REDIS_LIBEVENT_DELETED) == 0) { | ||
| 64 | redisAsyncHandleTimeout(e->context); | ||
| 65 | CHECK_DELETED(); | ||
| 66 | } | ||
| 67 | |||
| 68 | if ((event & EV_READ) && e->context && (e->state & REDIS_LIBEVENT_DELETED) == 0) { | ||
| 69 | redisAsyncHandleRead(e->context); | ||
| 70 | CHECK_DELETED(); | ||
| 71 | } | ||
| 72 | |||
| 73 | if ((event & EV_WRITE) && e->context && (e->state & REDIS_LIBEVENT_DELETED) == 0) { | ||
| 74 | redisAsyncHandleWrite(e->context); | ||
| 75 | CHECK_DELETED(); | ||
| 76 | } | ||
| 77 | |||
| 78 | e->state &= ~REDIS_LIBEVENT_ENTERED; | ||
| 79 | #undef CHECK_DELETED | ||
| 80 | } | ||
| 81 | |||
| 82 | static void redisLibeventUpdate(void *privdata, short flag, int isRemove) { | ||
| 83 | redisLibeventEvents *e = (redisLibeventEvents *)privdata; | ||
| 84 | const struct timeval *tv = e->tv.tv_sec || e->tv.tv_usec ? &e->tv : NULL; | ||
| 85 | |||
| 86 | if (isRemove) { | ||
| 87 | if ((e->flags & flag) == 0) { | ||
| 88 | return; | ||
| 89 | } else { | ||
| 90 | e->flags &= ~flag; | ||
| 91 | } | ||
| 92 | } else { | ||
| 93 | if (e->flags & flag) { | ||
| 94 | return; | ||
| 95 | } else { | ||
| 96 | e->flags |= flag; | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | event_del(e->ev); | ||
| 101 | event_assign(e->ev, e->base, e->context->c.fd, e->flags | EV_PERSIST, | ||
| 102 | redisLibeventHandler, privdata); | ||
| 103 | event_add(e->ev, tv); | ||
| 104 | } | ||
| 105 | |||
| 106 | static void redisLibeventAddRead(void *privdata) { | ||
| 107 | redisLibeventUpdate(privdata, EV_READ, 0); | ||
| 108 | } | ||
| 109 | |||
| 110 | static void redisLibeventDelRead(void *privdata) { | ||
| 111 | redisLibeventUpdate(privdata, EV_READ, 1); | ||
| 112 | } | ||
| 113 | |||
| 114 | static void redisLibeventAddWrite(void *privdata) { | ||
| 115 | redisLibeventUpdate(privdata, EV_WRITE, 0); | ||
| 116 | } | ||
| 117 | |||
| 118 | static void redisLibeventDelWrite(void *privdata) { | ||
| 119 | redisLibeventUpdate(privdata, EV_WRITE, 1); | ||
| 120 | } | ||
| 121 | |||
| 122 | static void redisLibeventCleanup(void *privdata) { | ||
| 123 | redisLibeventEvents *e = (redisLibeventEvents*)privdata; | ||
| 124 | if (!e) { | ||
| 125 | return; | ||
| 126 | } | ||
| 127 | event_del(e->ev); | ||
| 128 | event_free(e->ev); | ||
| 129 | e->ev = NULL; | ||
| 130 | |||
| 131 | if (e->state & REDIS_LIBEVENT_ENTERED) { | ||
| 132 | e->state |= REDIS_LIBEVENT_DELETED; | ||
| 133 | } else { | ||
| 134 | redisLibeventDestroy(e); | ||
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | static void redisLibeventSetTimeout(void *privdata, struct timeval tv) { | ||
| 139 | redisLibeventEvents *e = (redisLibeventEvents *)privdata; | ||
| 140 | short flags = e->flags; | ||
| 141 | e->flags = 0; | ||
| 142 | e->tv = tv; | ||
| 143 | redisLibeventUpdate(e, flags, 0); | ||
| 144 | } | ||
| 145 | |||
| 146 | static int redisLibeventAttach(redisAsyncContext *ac, struct event_base *base) { | ||
| 147 | redisContext *c = &(ac->c); | ||
| 148 | redisLibeventEvents *e; | ||
| 149 | |||
| 150 | /* Nothing should be attached when something is already attached */ | ||
| 151 | if (ac->ev.data != NULL) | ||
| 152 | return REDIS_ERR; | ||
| 153 | |||
| 154 | /* Create container for context and r/w events */ | ||
| 155 | e = (redisLibeventEvents*)hi_calloc(1, sizeof(*e)); | ||
| 156 | if (e == NULL) | ||
| 157 | return REDIS_ERR; | ||
| 158 | |||
| 159 | e->context = ac; | ||
| 160 | |||
| 161 | /* Register functions to start/stop listening for events */ | ||
| 162 | ac->ev.addRead = redisLibeventAddRead; | ||
| 163 | ac->ev.delRead = redisLibeventDelRead; | ||
| 164 | ac->ev.addWrite = redisLibeventAddWrite; | ||
| 165 | ac->ev.delWrite = redisLibeventDelWrite; | ||
| 166 | ac->ev.cleanup = redisLibeventCleanup; | ||
| 167 | ac->ev.scheduleTimer = redisLibeventSetTimeout; | ||
| 168 | ac->ev.data = e; | ||
| 169 | |||
| 170 | /* Initialize and install read/write events */ | ||
| 171 | e->ev = event_new(base, c->fd, EV_READ | EV_WRITE, redisLibeventHandler, e); | ||
| 172 | e->base = base; | ||
| 173 | return REDIS_OK; | ||
| 174 | } | ||
| 175 | #endif | ||
diff --git a/examples/redis-unstable/deps/hiredis/adapters/libhv.h b/examples/redis-unstable/deps/hiredis/adapters/libhv.h new file mode 100644 index 0000000..3b54c70 --- /dev/null +++ b/examples/redis-unstable/deps/hiredis/adapters/libhv.h | |||
| @@ -0,0 +1,123 @@ | |||
| 1 | #ifndef __HIREDIS_LIBHV_H__ | ||
| 2 | #define __HIREDIS_LIBHV_H__ | ||
| 3 | |||
| 4 | #include <hv/hloop.h> | ||
| 5 | #include "../hiredis.h" | ||
| 6 | #include "../async.h" | ||
| 7 | |||
| 8 | typedef struct redisLibhvEvents { | ||
| 9 | hio_t *io; | ||
| 10 | htimer_t *timer; | ||
| 11 | } redisLibhvEvents; | ||
| 12 | |||
| 13 | static void redisLibhvHandleEvents(hio_t* io) { | ||
| 14 | redisAsyncContext* context = (redisAsyncContext*)hevent_userdata(io); | ||
| 15 | int events = hio_events(io); | ||
| 16 | int revents = hio_revents(io); | ||
| 17 | if (context && (events & HV_READ) && (revents & HV_READ)) { | ||
| 18 | redisAsyncHandleRead(context); | ||
| 19 | } | ||
| 20 | if (context && (events & HV_WRITE) && (revents & HV_WRITE)) { | ||
| 21 | redisAsyncHandleWrite(context); | ||
| 22 | } | ||
| 23 | } | ||
| 24 | |||
| 25 | static void redisLibhvAddRead(void *privdata) { | ||
| 26 | redisLibhvEvents* events = (redisLibhvEvents*)privdata; | ||
| 27 | hio_add(events->io, redisLibhvHandleEvents, HV_READ); | ||
| 28 | } | ||
| 29 | |||
| 30 | static void redisLibhvDelRead(void *privdata) { | ||
| 31 | redisLibhvEvents* events = (redisLibhvEvents*)privdata; | ||
| 32 | hio_del(events->io, HV_READ); | ||
| 33 | } | ||
| 34 | |||
| 35 | static void redisLibhvAddWrite(void *privdata) { | ||
| 36 | redisLibhvEvents* events = (redisLibhvEvents*)privdata; | ||
| 37 | hio_add(events->io, redisLibhvHandleEvents, HV_WRITE); | ||
| 38 | } | ||
| 39 | |||
| 40 | static void redisLibhvDelWrite(void *privdata) { | ||
| 41 | redisLibhvEvents* events = (redisLibhvEvents*)privdata; | ||
| 42 | hio_del(events->io, HV_WRITE); | ||
| 43 | } | ||
| 44 | |||
| 45 | static void redisLibhvCleanup(void *privdata) { | ||
| 46 | redisLibhvEvents* events = (redisLibhvEvents*)privdata; | ||
| 47 | |||
| 48 | if (events->timer) | ||
| 49 | htimer_del(events->timer); | ||
| 50 | |||
| 51 | hio_close(events->io); | ||
| 52 | hevent_set_userdata(events->io, NULL); | ||
| 53 | |||
| 54 | hi_free(events); | ||
| 55 | } | ||
| 56 | |||
| 57 | static void redisLibhvTimeout(htimer_t* timer) { | ||
| 58 | hio_t* io = (hio_t*)hevent_userdata(timer); | ||
| 59 | redisAsyncHandleTimeout((redisAsyncContext*)hevent_userdata(io)); | ||
| 60 | } | ||
| 61 | |||
| 62 | static void redisLibhvSetTimeout(void *privdata, struct timeval tv) { | ||
| 63 | redisLibhvEvents* events; | ||
| 64 | uint32_t millis; | ||
| 65 | hloop_t* loop; | ||
| 66 | |||
| 67 | events = (redisLibhvEvents*)privdata; | ||
| 68 | millis = tv.tv_sec * 1000 + tv.tv_usec / 1000; | ||
| 69 | |||
| 70 | if (millis == 0) { | ||
| 71 | /* Libhv disallows zero'd timers so treat this as a delete or NO OP */ | ||
| 72 | if (events->timer) { | ||
| 73 | htimer_del(events->timer); | ||
| 74 | events->timer = NULL; | ||
| 75 | } | ||
| 76 | } else if (events->timer == NULL) { | ||
| 77 | /* Add new timer */ | ||
| 78 | loop = hevent_loop(events->io); | ||
| 79 | events->timer = htimer_add(loop, redisLibhvTimeout, millis, 1); | ||
| 80 | hevent_set_userdata(events->timer, events->io); | ||
| 81 | } else { | ||
| 82 | /* Update existing timer */ | ||
| 83 | htimer_reset(events->timer, millis); | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | static int redisLibhvAttach(redisAsyncContext* ac, hloop_t* loop) { | ||
| 88 | redisContext *c = &(ac->c); | ||
| 89 | redisLibhvEvents *events; | ||
| 90 | hio_t* io = NULL; | ||
| 91 | |||
| 92 | if (ac->ev.data != NULL) { | ||
| 93 | return REDIS_ERR; | ||
| 94 | } | ||
| 95 | |||
| 96 | /* Create container struct to keep track of our io and any timer */ | ||
| 97 | events = (redisLibhvEvents*)hi_malloc(sizeof(*events)); | ||
| 98 | if (events == NULL) { | ||
| 99 | return REDIS_ERR; | ||
| 100 | } | ||
| 101 | |||
| 102 | io = hio_get(loop, c->fd); | ||
| 103 | if (io == NULL) { | ||
| 104 | hi_free(events); | ||
| 105 | return REDIS_ERR; | ||
| 106 | } | ||
| 107 | |||
| 108 | hevent_set_userdata(io, ac); | ||
| 109 | |||
| 110 | events->io = io; | ||
| 111 | events->timer = NULL; | ||
| 112 | |||
| 113 | ac->ev.addRead = redisLibhvAddRead; | ||
| 114 | ac->ev.delRead = redisLibhvDelRead; | ||
| 115 | ac->ev.addWrite = redisLibhvAddWrite; | ||
| 116 | ac->ev.delWrite = redisLibhvDelWrite; | ||
| 117 | ac->ev.cleanup = redisLibhvCleanup; | ||
| 118 | ac->ev.scheduleTimer = redisLibhvSetTimeout; | ||
| 119 | ac->ev.data = events; | ||
| 120 | |||
| 121 | return REDIS_OK; | ||
| 122 | } | ||
| 123 | #endif | ||
diff --git a/examples/redis-unstable/deps/hiredis/adapters/libsdevent.h b/examples/redis-unstable/deps/hiredis/adapters/libsdevent.h new file mode 100644 index 0000000..1268ed9 --- /dev/null +++ b/examples/redis-unstable/deps/hiredis/adapters/libsdevent.h | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | #ifndef HIREDIS_LIBSDEVENT_H | ||
| 2 | #define HIREDIS_LIBSDEVENT_H | ||
| 3 | #include <systemd/sd-event.h> | ||
| 4 | #include "../hiredis.h" | ||
| 5 | #include "../async.h" | ||
| 6 | |||
| 7 | #define REDIS_LIBSDEVENT_DELETED 0x01 | ||
| 8 | #define REDIS_LIBSDEVENT_ENTERED 0x02 | ||
| 9 | |||
| 10 | typedef struct redisLibsdeventEvents { | ||
| 11 | redisAsyncContext *context; | ||
| 12 | struct sd_event *event; | ||
| 13 | struct sd_event_source *fdSource; | ||
| 14 | struct sd_event_source *timerSource; | ||
| 15 | int fd; | ||
| 16 | short flags; | ||
| 17 | short state; | ||
| 18 | } redisLibsdeventEvents; | ||
| 19 | |||
| 20 | static void redisLibsdeventDestroy(redisLibsdeventEvents *e) { | ||
| 21 | if (e->fdSource) { | ||
| 22 | e->fdSource = sd_event_source_disable_unref(e->fdSource); | ||
| 23 | } | ||
| 24 | if (e->timerSource) { | ||
| 25 | e->timerSource = sd_event_source_disable_unref(e->timerSource); | ||
| 26 | } | ||
| 27 | sd_event_unref(e->event); | ||
| 28 | hi_free(e); | ||
| 29 | } | ||
| 30 | |||
| 31 | static int redisLibsdeventTimeoutHandler(sd_event_source *s, uint64_t usec, void *userdata) { | ||
| 32 | ((void)s); | ||
| 33 | ((void)usec); | ||
| 34 | redisLibsdeventEvents *e = (redisLibsdeventEvents*)userdata; | ||
| 35 | redisAsyncHandleTimeout(e->context); | ||
| 36 | return 0; | ||
| 37 | } | ||
| 38 | |||
| 39 | static int redisLibsdeventHandler(sd_event_source *s, int fd, uint32_t event, void *userdata) { | ||
| 40 | ((void)s); | ||
| 41 | ((void)fd); | ||
| 42 | redisLibsdeventEvents *e = (redisLibsdeventEvents*)userdata; | ||
| 43 | e->state |= REDIS_LIBSDEVENT_ENTERED; | ||
| 44 | |||
| 45 | #define CHECK_DELETED() if (e->state & REDIS_LIBSDEVENT_DELETED) {\ | ||
| 46 | redisLibsdeventDestroy(e);\ | ||
| 47 | return 0; \ | ||
| 48 | } | ||
| 49 | |||
| 50 | if ((event & EPOLLIN) && e->context && (e->state & REDIS_LIBSDEVENT_DELETED) == 0) { | ||
| 51 | redisAsyncHandleRead(e->context); | ||
| 52 | CHECK_DELETED(); | ||
| 53 | } | ||
| 54 | |||
| 55 | if ((event & EPOLLOUT) && e->context && (e->state & REDIS_LIBSDEVENT_DELETED) == 0) { | ||
| 56 | redisAsyncHandleWrite(e->context); | ||
| 57 | CHECK_DELETED(); | ||
| 58 | } | ||
| 59 | |||
| 60 | e->state &= ~REDIS_LIBSDEVENT_ENTERED; | ||
| 61 | #undef CHECK_DELETED | ||
| 62 | |||
| 63 | return 0; | ||
| 64 | } | ||
| 65 | |||
| 66 | static void redisLibsdeventAddRead(void *userdata) { | ||
| 67 | redisLibsdeventEvents *e = (redisLibsdeventEvents*)userdata; | ||
| 68 | |||
| 69 | if (e->flags & EPOLLIN) { | ||
| 70 | return; | ||
| 71 | } | ||
| 72 | |||
| 73 | e->flags |= EPOLLIN; | ||
| 74 | |||
| 75 | if (e->flags & EPOLLOUT) { | ||
| 76 | sd_event_source_set_io_events(e->fdSource, e->flags); | ||
| 77 | } else { | ||
| 78 | sd_event_add_io(e->event, &e->fdSource, e->fd, e->flags, redisLibsdeventHandler, e); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | static void redisLibsdeventDelRead(void *userdata) { | ||
| 83 | redisLibsdeventEvents *e = (redisLibsdeventEvents*)userdata; | ||
| 84 | |||
| 85 | e->flags &= ~EPOLLIN; | ||
| 86 | |||
| 87 | if (e->flags) { | ||
| 88 | sd_event_source_set_io_events(e->fdSource, e->flags); | ||
| 89 | } else { | ||
| 90 | e->fdSource = sd_event_source_disable_unref(e->fdSource); | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | static void redisLibsdeventAddWrite(void *userdata) { | ||
| 95 | redisLibsdeventEvents *e = (redisLibsdeventEvents*)userdata; | ||
| 96 | |||
| 97 | if (e->flags & EPOLLOUT) { | ||
| 98 | return; | ||
| 99 | } | ||
| 100 | |||
| 101 | e->flags |= EPOLLOUT; | ||
| 102 | |||
| 103 | if (e->flags & EPOLLIN) { | ||
| 104 | sd_event_source_set_io_events(e->fdSource, e->flags); | ||
| 105 | } else { | ||
| 106 | sd_event_add_io(e->event, &e->fdSource, e->fd, e->flags, redisLibsdeventHandler, e); | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | static void redisLibsdeventDelWrite(void *userdata) { | ||
| 111 | redisLibsdeventEvents *e = (redisLibsdeventEvents*)userdata; | ||
| 112 | |||
| 113 | e->flags &= ~EPOLLOUT; | ||
| 114 | |||
| 115 | if (e->flags) { | ||
| 116 | sd_event_source_set_io_events(e->fdSource, e->flags); | ||
| 117 | } else { | ||
| 118 | e->fdSource = sd_event_source_disable_unref(e->fdSource); | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | static void redisLibsdeventCleanup(void *userdata) { | ||
| 123 | redisLibsdeventEvents *e = (redisLibsdeventEvents*)userdata; | ||
| 124 | |||
| 125 | if (!e) { | ||
| 126 | return; | ||
| 127 | } | ||
| 128 | |||
| 129 | if (e->state & REDIS_LIBSDEVENT_ENTERED) { | ||
| 130 | e->state |= REDIS_LIBSDEVENT_DELETED; | ||
| 131 | } else { | ||
| 132 | redisLibsdeventDestroy(e); | ||
| 133 | } | ||
| 134 | } | ||
| 135 | |||
| 136 | static void redisLibsdeventSetTimeout(void *userdata, struct timeval tv) { | ||
| 137 | redisLibsdeventEvents *e = (redisLibsdeventEvents *)userdata; | ||
| 138 | |||
| 139 | uint64_t usec = tv.tv_sec * 1000000 + tv.tv_usec; | ||
| 140 | if (!e->timerSource) { | ||
| 141 | sd_event_add_time_relative(e->event, &e->timerSource, CLOCK_MONOTONIC, usec, 1, redisLibsdeventTimeoutHandler, e); | ||
| 142 | } else { | ||
| 143 | sd_event_source_set_time_relative(e->timerSource, usec); | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | static int redisLibsdeventAttach(redisAsyncContext *ac, struct sd_event *event) { | ||
| 148 | redisContext *c = &(ac->c); | ||
| 149 | redisLibsdeventEvents *e; | ||
| 150 | |||
| 151 | /* Nothing should be attached when something is already attached */ | ||
| 152 | if (ac->ev.data != NULL) | ||
| 153 | return REDIS_ERR; | ||
| 154 | |||
| 155 | /* Create container for context and r/w events */ | ||
| 156 | e = (redisLibsdeventEvents*)hi_calloc(1, sizeof(*e)); | ||
| 157 | if (e == NULL) | ||
| 158 | return REDIS_ERR; | ||
| 159 | |||
| 160 | /* Initialize and increase event refcount */ | ||
| 161 | e->context = ac; | ||
| 162 | e->event = event; | ||
| 163 | e->fd = c->fd; | ||
| 164 | sd_event_ref(event); | ||
| 165 | |||
| 166 | /* Register functions to start/stop listening for events */ | ||
| 167 | ac->ev.addRead = redisLibsdeventAddRead; | ||
| 168 | ac->ev.delRead = redisLibsdeventDelRead; | ||
| 169 | ac->ev.addWrite = redisLibsdeventAddWrite; | ||
| 170 | ac->ev.delWrite = redisLibsdeventDelWrite; | ||
| 171 | ac->ev.cleanup = redisLibsdeventCleanup; | ||
| 172 | ac->ev.scheduleTimer = redisLibsdeventSetTimeout; | ||
| 173 | ac->ev.data = e; | ||
| 174 | |||
| 175 | return REDIS_OK; | ||
| 176 | } | ||
| 177 | #endif | ||
diff --git a/examples/redis-unstable/deps/hiredis/adapters/libuv.h b/examples/redis-unstable/deps/hiredis/adapters/libuv.h new file mode 100644 index 0000000..268edab --- /dev/null +++ b/examples/redis-unstable/deps/hiredis/adapters/libuv.h | |||
| @@ -0,0 +1,171 @@ | |||
| 1 | #ifndef __HIREDIS_LIBUV_H__ | ||
| 2 | #define __HIREDIS_LIBUV_H__ | ||
| 3 | #include <stdlib.h> | ||
| 4 | #include <uv.h> | ||
| 5 | #include "../hiredis.h" | ||
| 6 | #include "../async.h" | ||
| 7 | #include <string.h> | ||
| 8 | |||
| 9 | typedef struct redisLibuvEvents { | ||
| 10 | redisAsyncContext* context; | ||
| 11 | uv_poll_t handle; | ||
| 12 | uv_timer_t timer; | ||
| 13 | int events; | ||
| 14 | } redisLibuvEvents; | ||
| 15 | |||
| 16 | |||
| 17 | static void redisLibuvPoll(uv_poll_t* handle, int status, int events) { | ||
| 18 | redisLibuvEvents* p = (redisLibuvEvents*)handle->data; | ||
| 19 | int ev = (status ? p->events : events); | ||
| 20 | |||
| 21 | if (p->context != NULL && (ev & UV_READABLE)) { | ||
| 22 | redisAsyncHandleRead(p->context); | ||
| 23 | } | ||
| 24 | if (p->context != NULL && (ev & UV_WRITABLE)) { | ||
| 25 | redisAsyncHandleWrite(p->context); | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | |||
| 30 | static void redisLibuvAddRead(void *privdata) { | ||
| 31 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; | ||
| 32 | |||
| 33 | if (p->events & UV_READABLE) { | ||
| 34 | return; | ||
| 35 | } | ||
| 36 | |||
| 37 | p->events |= UV_READABLE; | ||
| 38 | |||
| 39 | uv_poll_start(&p->handle, p->events, redisLibuvPoll); | ||
| 40 | } | ||
| 41 | |||
| 42 | |||
| 43 | static void redisLibuvDelRead(void *privdata) { | ||
| 44 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; | ||
| 45 | |||
| 46 | p->events &= ~UV_READABLE; | ||
| 47 | |||
| 48 | if (p->events) { | ||
| 49 | uv_poll_start(&p->handle, p->events, redisLibuvPoll); | ||
| 50 | } else { | ||
| 51 | uv_poll_stop(&p->handle); | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | |||
| 56 | static void redisLibuvAddWrite(void *privdata) { | ||
| 57 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; | ||
| 58 | |||
| 59 | if (p->events & UV_WRITABLE) { | ||
| 60 | return; | ||
| 61 | } | ||
| 62 | |||
| 63 | p->events |= UV_WRITABLE; | ||
| 64 | |||
| 65 | uv_poll_start(&p->handle, p->events, redisLibuvPoll); | ||
| 66 | } | ||
| 67 | |||
| 68 | |||
| 69 | static void redisLibuvDelWrite(void *privdata) { | ||
| 70 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; | ||
| 71 | |||
| 72 | p->events &= ~UV_WRITABLE; | ||
| 73 | |||
| 74 | if (p->events) { | ||
| 75 | uv_poll_start(&p->handle, p->events, redisLibuvPoll); | ||
| 76 | } else { | ||
| 77 | uv_poll_stop(&p->handle); | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | static void on_timer_close(uv_handle_t *handle) { | ||
| 82 | redisLibuvEvents* p = (redisLibuvEvents*)handle->data; | ||
| 83 | p->timer.data = NULL; | ||
| 84 | if (!p->handle.data) { | ||
| 85 | // both timer and handle are closed | ||
| 86 | hi_free(p); | ||
| 87 | } | ||
| 88 | // else, wait for `on_handle_close` | ||
| 89 | } | ||
| 90 | |||
| 91 | static void on_handle_close(uv_handle_t *handle) { | ||
| 92 | redisLibuvEvents* p = (redisLibuvEvents*)handle->data; | ||
| 93 | p->handle.data = NULL; | ||
| 94 | if (!p->timer.data) { | ||
| 95 | // timer never started, or timer already destroyed | ||
| 96 | hi_free(p); | ||
| 97 | } | ||
| 98 | // else, wait for `on_timer_close` | ||
| 99 | } | ||
| 100 | |||
| 101 | // libuv removed `status` parameter since v0.11.23 | ||
| 102 | // see: https://github.com/libuv/libuv/blob/v0.11.23/include/uv.h | ||
| 103 | #if (UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR < 11) || \ | ||
| 104 | (UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR == 11 && UV_VERSION_PATCH < 23) | ||
| 105 | static void redisLibuvTimeout(uv_timer_t *timer, int status) { | ||
| 106 | (void)status; // unused | ||
| 107 | #else | ||
| 108 | static void redisLibuvTimeout(uv_timer_t *timer) { | ||
| 109 | #endif | ||
| 110 | redisLibuvEvents *e = (redisLibuvEvents*)timer->data; | ||
| 111 | redisAsyncHandleTimeout(e->context); | ||
| 112 | } | ||
| 113 | |||
| 114 | static void redisLibuvSetTimeout(void *privdata, struct timeval tv) { | ||
| 115 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; | ||
| 116 | |||
| 117 | uint64_t millsec = tv.tv_sec * 1000 + tv.tv_usec / 1000.0; | ||
| 118 | if (!p->timer.data) { | ||
| 119 | // timer is uninitialized | ||
| 120 | if (uv_timer_init(p->handle.loop, &p->timer) != 0) { | ||
| 121 | return; | ||
| 122 | } | ||
| 123 | p->timer.data = p; | ||
| 124 | } | ||
| 125 | // updates the timeout if the timer has already started | ||
| 126 | // or start the timer | ||
| 127 | uv_timer_start(&p->timer, redisLibuvTimeout, millsec, 0); | ||
| 128 | } | ||
| 129 | |||
| 130 | static void redisLibuvCleanup(void *privdata) { | ||
| 131 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; | ||
| 132 | |||
| 133 | p->context = NULL; // indicate that context might no longer exist | ||
| 134 | if (p->timer.data) { | ||
| 135 | uv_close((uv_handle_t*)&p->timer, on_timer_close); | ||
| 136 | } | ||
| 137 | uv_close((uv_handle_t*)&p->handle, on_handle_close); | ||
| 138 | } | ||
| 139 | |||
| 140 | |||
| 141 | static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) { | ||
| 142 | redisContext *c = &(ac->c); | ||
| 143 | |||
| 144 | if (ac->ev.data != NULL) { | ||
| 145 | return REDIS_ERR; | ||
| 146 | } | ||
| 147 | |||
| 148 | ac->ev.addRead = redisLibuvAddRead; | ||
| 149 | ac->ev.delRead = redisLibuvDelRead; | ||
| 150 | ac->ev.addWrite = redisLibuvAddWrite; | ||
| 151 | ac->ev.delWrite = redisLibuvDelWrite; | ||
| 152 | ac->ev.cleanup = redisLibuvCleanup; | ||
| 153 | ac->ev.scheduleTimer = redisLibuvSetTimeout; | ||
| 154 | |||
| 155 | redisLibuvEvents* p = (redisLibuvEvents*)hi_malloc(sizeof(*p)); | ||
| 156 | if (p == NULL) | ||
| 157 | return REDIS_ERR; | ||
| 158 | |||
| 159 | memset(p, 0, sizeof(*p)); | ||
| 160 | |||
| 161 | if (uv_poll_init_socket(loop, &p->handle, c->fd) != 0) { | ||
| 162 | return REDIS_ERR; | ||
| 163 | } | ||
| 164 | |||
| 165 | ac->ev.data = p; | ||
| 166 | p->handle.data = p; | ||
| 167 | p->context = ac; | ||
| 168 | |||
| 169 | return REDIS_OK; | ||
| 170 | } | ||
| 171 | #endif | ||
diff --git a/examples/redis-unstable/deps/hiredis/adapters/macosx.h b/examples/redis-unstable/deps/hiredis/adapters/macosx.h new file mode 100644 index 0000000..3c87f1b --- /dev/null +++ b/examples/redis-unstable/deps/hiredis/adapters/macosx.h | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | // | ||
| 2 | // Created by Дмитрий Бахвалов on 13.07.15. | ||
| 3 | // Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved. | ||
| 4 | // | ||
| 5 | |||
| 6 | #ifndef __HIREDIS_MACOSX_H__ | ||
| 7 | #define __HIREDIS_MACOSX_H__ | ||
| 8 | |||
| 9 | #include <CoreFoundation/CoreFoundation.h> | ||
| 10 | |||
| 11 | #include "../hiredis.h" | ||
| 12 | #include "../async.h" | ||
| 13 | |||
| 14 | typedef struct { | ||
| 15 | redisAsyncContext *context; | ||
| 16 | CFSocketRef socketRef; | ||
| 17 | CFRunLoopSourceRef sourceRef; | ||
| 18 | } RedisRunLoop; | ||
| 19 | |||
| 20 | static int freeRedisRunLoop(RedisRunLoop* redisRunLoop) { | ||
| 21 | if( redisRunLoop != NULL ) { | ||
| 22 | if( redisRunLoop->sourceRef != NULL ) { | ||
| 23 | CFRunLoopSourceInvalidate(redisRunLoop->sourceRef); | ||
| 24 | CFRelease(redisRunLoop->sourceRef); | ||
| 25 | } | ||
| 26 | if( redisRunLoop->socketRef != NULL ) { | ||
| 27 | CFSocketInvalidate(redisRunLoop->socketRef); | ||
| 28 | CFRelease(redisRunLoop->socketRef); | ||
| 29 | } | ||
| 30 | hi_free(redisRunLoop); | ||
| 31 | } | ||
| 32 | return REDIS_ERR; | ||
| 33 | } | ||
| 34 | |||
| 35 | static void redisMacOSAddRead(void *privdata) { | ||
| 36 | RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; | ||
| 37 | CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack); | ||
| 38 | } | ||
| 39 | |||
| 40 | static void redisMacOSDelRead(void *privdata) { | ||
| 41 | RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; | ||
| 42 | CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack); | ||
| 43 | } | ||
| 44 | |||
| 45 | static void redisMacOSAddWrite(void *privdata) { | ||
| 46 | RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; | ||
| 47 | CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack); | ||
| 48 | } | ||
| 49 | |||
| 50 | static void redisMacOSDelWrite(void *privdata) { | ||
| 51 | RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; | ||
| 52 | CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack); | ||
| 53 | } | ||
| 54 | |||
| 55 | static void redisMacOSCleanup(void *privdata) { | ||
| 56 | RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; | ||
| 57 | freeRedisRunLoop(redisRunLoop); | ||
| 58 | } | ||
| 59 | |||
| 60 | static void redisMacOSAsyncCallback(CFSocketRef __unused s, CFSocketCallBackType callbackType, CFDataRef __unused address, const void __unused *data, void *info) { | ||
| 61 | redisAsyncContext* context = (redisAsyncContext*) info; | ||
| 62 | |||
| 63 | switch (callbackType) { | ||
| 64 | case kCFSocketReadCallBack: | ||
| 65 | redisAsyncHandleRead(context); | ||
| 66 | break; | ||
| 67 | |||
| 68 | case kCFSocketWriteCallBack: | ||
| 69 | redisAsyncHandleWrite(context); | ||
| 70 | break; | ||
| 71 | |||
| 72 | default: | ||
| 73 | break; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | static int redisMacOSAttach(redisAsyncContext *redisAsyncCtx, CFRunLoopRef runLoop) { | ||
| 78 | redisContext *redisCtx = &(redisAsyncCtx->c); | ||
| 79 | |||
| 80 | /* Nothing should be attached when something is already attached */ | ||
| 81 | if( redisAsyncCtx->ev.data != NULL ) return REDIS_ERR; | ||
| 82 | |||
| 83 | RedisRunLoop* redisRunLoop = (RedisRunLoop*) hi_calloc(1, sizeof(RedisRunLoop)); | ||
| 84 | if (redisRunLoop == NULL) | ||
| 85 | return REDIS_ERR; | ||
| 86 | |||
| 87 | /* Setup redis stuff */ | ||
| 88 | redisRunLoop->context = redisAsyncCtx; | ||
| 89 | |||
| 90 | redisAsyncCtx->ev.addRead = redisMacOSAddRead; | ||
| 91 | redisAsyncCtx->ev.delRead = redisMacOSDelRead; | ||
| 92 | redisAsyncCtx->ev.addWrite = redisMacOSAddWrite; | ||
| 93 | redisAsyncCtx->ev.delWrite = redisMacOSDelWrite; | ||
| 94 | redisAsyncCtx->ev.cleanup = redisMacOSCleanup; | ||
| 95 | redisAsyncCtx->ev.data = redisRunLoop; | ||
| 96 | |||
| 97 | /* Initialize and install read/write events */ | ||
| 98 | CFSocketContext socketCtx = { 0, redisAsyncCtx, NULL, NULL, NULL }; | ||
| 99 | |||
| 100 | redisRunLoop->socketRef = CFSocketCreateWithNative(NULL, redisCtx->fd, | ||
| 101 | kCFSocketReadCallBack | kCFSocketWriteCallBack, | ||
| 102 | redisMacOSAsyncCallback, | ||
| 103 | &socketCtx); | ||
| 104 | if( !redisRunLoop->socketRef ) return freeRedisRunLoop(redisRunLoop); | ||
| 105 | |||
| 106 | redisRunLoop->sourceRef = CFSocketCreateRunLoopSource(NULL, redisRunLoop->socketRef, 0); | ||
| 107 | if( !redisRunLoop->sourceRef ) return freeRedisRunLoop(redisRunLoop); | ||
| 108 | |||
| 109 | CFRunLoopAddSource(runLoop, redisRunLoop->sourceRef, kCFRunLoopDefaultMode); | ||
| 110 | |||
| 111 | return REDIS_OK; | ||
| 112 | } | ||
| 113 | |||
| 114 | #endif | ||
| 115 | |||
diff --git a/examples/redis-unstable/deps/hiredis/adapters/poll.h b/examples/redis-unstable/deps/hiredis/adapters/poll.h new file mode 100644 index 0000000..f138650 --- /dev/null +++ b/examples/redis-unstable/deps/hiredis/adapters/poll.h | |||
| @@ -0,0 +1,197 @@ | |||
| 1 | |||
| 2 | #ifndef HIREDIS_POLL_H | ||
| 3 | #define HIREDIS_POLL_H | ||
| 4 | |||
| 5 | #include "../async.h" | ||
| 6 | #include "../sockcompat.h" | ||
| 7 | #include <string.h> // for memset | ||
| 8 | #include <errno.h> | ||
| 9 | |||
| 10 | /* Values to return from redisPollTick */ | ||
| 11 | #define REDIS_POLL_HANDLED_READ 1 | ||
| 12 | #define REDIS_POLL_HANDLED_WRITE 2 | ||
| 13 | #define REDIS_POLL_HANDLED_TIMEOUT 4 | ||
| 14 | |||
| 15 | /* An adapter to allow manual polling of the async context by checking the state | ||
| 16 | * of the underlying file descriptor. Useful in cases where there is no formal | ||
| 17 | * IO event loop but regular ticking can be used, such as in game engines. */ | ||
| 18 | |||
| 19 | typedef struct redisPollEvents { | ||
| 20 | redisAsyncContext *context; | ||
| 21 | redisFD fd; | ||
| 22 | char reading, writing; | ||
| 23 | char in_tick; | ||
| 24 | char deleted; | ||
| 25 | double deadline; | ||
| 26 | } redisPollEvents; | ||
| 27 | |||
| 28 | static double redisPollTimevalToDouble(struct timeval *tv) { | ||
| 29 | if (tv == NULL) | ||
| 30 | return 0.0; | ||
| 31 | return tv->tv_sec + tv->tv_usec / 1000000.00; | ||
| 32 | } | ||
| 33 | |||
| 34 | static double redisPollGetNow(void) { | ||
| 35 | #ifndef _MSC_VER | ||
| 36 | struct timeval tv; | ||
| 37 | gettimeofday(&tv,NULL); | ||
| 38 | return redisPollTimevalToDouble(&tv); | ||
| 39 | #else | ||
| 40 | FILETIME ft; | ||
| 41 | ULARGE_INTEGER li; | ||
| 42 | GetSystemTimeAsFileTime(&ft); | ||
| 43 | li.HighPart = ft.dwHighDateTime; | ||
| 44 | li.LowPart = ft.dwLowDateTime; | ||
| 45 | return (double)li.QuadPart * 1e-7; | ||
| 46 | #endif | ||
| 47 | } | ||
| 48 | |||
| 49 | /* Poll for io, handling any pending callbacks. The timeout argument can be | ||
| 50 | * positive to wait for a maximum given time for IO, zero to poll, or negative | ||
| 51 | * to wait forever */ | ||
| 52 | static int redisPollTick(redisAsyncContext *ac, double timeout) { | ||
| 53 | int reading, writing; | ||
| 54 | struct pollfd pfd; | ||
| 55 | int handled; | ||
| 56 | int ns; | ||
| 57 | int itimeout; | ||
| 58 | |||
| 59 | redisPollEvents *e = (redisPollEvents*)ac->ev.data; | ||
| 60 | if (!e) | ||
| 61 | return 0; | ||
| 62 | |||
| 63 | /* local flags, won't get changed during callbacks */ | ||
| 64 | reading = e->reading; | ||
| 65 | writing = e->writing; | ||
| 66 | if (!reading && !writing) | ||
| 67 | return 0; | ||
| 68 | |||
| 69 | pfd.fd = e->fd; | ||
| 70 | pfd.events = 0; | ||
| 71 | if (reading) | ||
| 72 | pfd.events = POLLIN; | ||
| 73 | if (writing) | ||
| 74 | pfd.events |= POLLOUT; | ||
| 75 | |||
| 76 | if (timeout >= 0.0) { | ||
| 77 | itimeout = (int)(timeout * 1000.0); | ||
| 78 | } else { | ||
| 79 | itimeout = -1; | ||
| 80 | } | ||
| 81 | |||
| 82 | ns = poll(&pfd, 1, itimeout); | ||
| 83 | if (ns < 0) { | ||
| 84 | /* ignore the EINTR error */ | ||
| 85 | if (errno != EINTR) | ||
| 86 | return ns; | ||
| 87 | ns = 0; | ||
| 88 | } | ||
| 89 | |||
| 90 | handled = 0; | ||
| 91 | e->in_tick = 1; | ||
| 92 | if (ns) { | ||
| 93 | if (reading && (pfd.revents & POLLIN)) { | ||
| 94 | redisAsyncHandleRead(ac); | ||
| 95 | handled |= REDIS_POLL_HANDLED_READ; | ||
| 96 | } | ||
| 97 | /* on Windows, connection failure is indicated with the Exception fdset. | ||
| 98 | * handle it the same as writable. */ | ||
| 99 | if (writing && (pfd.revents & (POLLOUT | POLLERR))) { | ||
| 100 | /* context Read callback may have caused context to be deleted, e.g. | ||
| 101 | by doing an redisAsyncDisconnect() */ | ||
| 102 | if (!e->deleted) { | ||
| 103 | redisAsyncHandleWrite(ac); | ||
| 104 | handled |= REDIS_POLL_HANDLED_WRITE; | ||
| 105 | } | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | /* perform timeouts */ | ||
| 110 | if (!e->deleted && e->deadline != 0.0) { | ||
| 111 | double now = redisPollGetNow(); | ||
| 112 | if (now >= e->deadline) { | ||
| 113 | /* deadline has passed. disable timeout and perform callback */ | ||
| 114 | e->deadline = 0.0; | ||
| 115 | redisAsyncHandleTimeout(ac); | ||
| 116 | handled |= REDIS_POLL_HANDLED_TIMEOUT; | ||
| 117 | } | ||
| 118 | } | ||
| 119 | |||
| 120 | /* do a delayed cleanup if required */ | ||
| 121 | if (e->deleted) | ||
| 122 | hi_free(e); | ||
| 123 | else | ||
| 124 | e->in_tick = 0; | ||
| 125 | |||
| 126 | return handled; | ||
| 127 | } | ||
| 128 | |||
| 129 | static void redisPollAddRead(void *data) { | ||
| 130 | redisPollEvents *e = (redisPollEvents*)data; | ||
| 131 | e->reading = 1; | ||
| 132 | } | ||
| 133 | |||
| 134 | static void redisPollDelRead(void *data) { | ||
| 135 | redisPollEvents *e = (redisPollEvents*)data; | ||
| 136 | e->reading = 0; | ||
| 137 | } | ||
| 138 | |||
| 139 | static void redisPollAddWrite(void *data) { | ||
| 140 | redisPollEvents *e = (redisPollEvents*)data; | ||
| 141 | e->writing = 1; | ||
| 142 | } | ||
| 143 | |||
| 144 | static void redisPollDelWrite(void *data) { | ||
| 145 | redisPollEvents *e = (redisPollEvents*)data; | ||
| 146 | e->writing = 0; | ||
| 147 | } | ||
| 148 | |||
| 149 | static void redisPollCleanup(void *data) { | ||
| 150 | redisPollEvents *e = (redisPollEvents*)data; | ||
| 151 | |||
| 152 | /* if we are currently processing a tick, postpone deletion */ | ||
| 153 | if (e->in_tick) | ||
| 154 | e->deleted = 1; | ||
| 155 | else | ||
| 156 | hi_free(e); | ||
| 157 | } | ||
| 158 | |||
| 159 | static void redisPollScheduleTimer(void *data, struct timeval tv) | ||
| 160 | { | ||
| 161 | redisPollEvents *e = (redisPollEvents*)data; | ||
| 162 | double now = redisPollGetNow(); | ||
| 163 | e->deadline = now + redisPollTimevalToDouble(&tv); | ||
| 164 | } | ||
| 165 | |||
| 166 | static int redisPollAttach(redisAsyncContext *ac) { | ||
| 167 | redisContext *c = &(ac->c); | ||
| 168 | redisPollEvents *e; | ||
| 169 | |||
| 170 | /* Nothing should be attached when something is already attached */ | ||
| 171 | if (ac->ev.data != NULL) | ||
| 172 | return REDIS_ERR; | ||
| 173 | |||
| 174 | /* Create container for context and r/w events */ | ||
| 175 | e = (redisPollEvents*)hi_malloc(sizeof(*e)); | ||
| 176 | if (e == NULL) | ||
| 177 | return REDIS_ERR; | ||
| 178 | memset(e, 0, sizeof(*e)); | ||
| 179 | |||
| 180 | e->context = ac; | ||
| 181 | e->fd = c->fd; | ||
| 182 | e->reading = e->writing = 0; | ||
| 183 | e->in_tick = e->deleted = 0; | ||
| 184 | e->deadline = 0.0; | ||
| 185 | |||
| 186 | /* Register functions to start/stop listening for events */ | ||
| 187 | ac->ev.addRead = redisPollAddRead; | ||
| 188 | ac->ev.delRead = redisPollDelRead; | ||
| 189 | ac->ev.addWrite = redisPollAddWrite; | ||
| 190 | ac->ev.delWrite = redisPollDelWrite; | ||
| 191 | ac->ev.scheduleTimer = redisPollScheduleTimer; | ||
| 192 | ac->ev.cleanup = redisPollCleanup; | ||
| 193 | ac->ev.data = e; | ||
| 194 | |||
| 195 | return REDIS_OK; | ||
| 196 | } | ||
| 197 | #endif /* HIREDIS_POLL_H */ | ||
diff --git a/examples/redis-unstable/deps/hiredis/adapters/qt.h b/examples/redis-unstable/deps/hiredis/adapters/qt.h new file mode 100644 index 0000000..5cc02e6 --- /dev/null +++ b/examples/redis-unstable/deps/hiredis/adapters/qt.h | |||
| @@ -0,0 +1,135 @@ | |||
| 1 | /*- | ||
| 2 | * Copyright (C) 2014 Pietro Cerutti <gahr@gahr.ch> | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions | ||
| 6 | * are met: | ||
| 7 | * 1. Redistributions of source code must retain the above copyright | ||
| 8 | * notice, this list of conditions and the following disclaimer. | ||
| 9 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * | ||
| 13 | * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 16 | * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 17 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 19 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 20 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 23 | * SUCH DAMAGE. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #ifndef __HIREDIS_QT_H__ | ||
| 27 | #define __HIREDIS_QT_H__ | ||
| 28 | #include <QSocketNotifier> | ||
| 29 | #include "../async.h" | ||
| 30 | |||
| 31 | static void RedisQtAddRead(void *); | ||
| 32 | static void RedisQtDelRead(void *); | ||
| 33 | static void RedisQtAddWrite(void *); | ||
| 34 | static void RedisQtDelWrite(void *); | ||
| 35 | static void RedisQtCleanup(void *); | ||
| 36 | |||
| 37 | class RedisQtAdapter : public QObject { | ||
| 38 | |||
| 39 | Q_OBJECT | ||
| 40 | |||
| 41 | friend | ||
| 42 | void RedisQtAddRead(void * adapter) { | ||
| 43 | RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter); | ||
| 44 | a->addRead(); | ||
| 45 | } | ||
| 46 | |||
| 47 | friend | ||
| 48 | void RedisQtDelRead(void * adapter) { | ||
| 49 | RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter); | ||
| 50 | a->delRead(); | ||
| 51 | } | ||
| 52 | |||
| 53 | friend | ||
| 54 | void RedisQtAddWrite(void * adapter) { | ||
| 55 | RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter); | ||
| 56 | a->addWrite(); | ||
| 57 | } | ||
| 58 | |||
| 59 | friend | ||
| 60 | void RedisQtDelWrite(void * adapter) { | ||
| 61 | RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter); | ||
| 62 | a->delWrite(); | ||
| 63 | } | ||
| 64 | |||
| 65 | friend | ||
| 66 | void RedisQtCleanup(void * adapter) { | ||
| 67 | RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter); | ||
| 68 | a->cleanup(); | ||
| 69 | } | ||
| 70 | |||
| 71 | public: | ||
| 72 | RedisQtAdapter(QObject * parent = 0) | ||
| 73 | : QObject(parent), m_ctx(0), m_read(0), m_write(0) { } | ||
| 74 | |||
| 75 | ~RedisQtAdapter() { | ||
| 76 | if (m_ctx != 0) { | ||
| 77 | m_ctx->ev.data = NULL; | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | int setContext(redisAsyncContext * ac) { | ||
| 82 | if (ac->ev.data != NULL) { | ||
| 83 | return REDIS_ERR; | ||
| 84 | } | ||
| 85 | m_ctx = ac; | ||
| 86 | m_ctx->ev.data = this; | ||
| 87 | m_ctx->ev.addRead = RedisQtAddRead; | ||
| 88 | m_ctx->ev.delRead = RedisQtDelRead; | ||
| 89 | m_ctx->ev.addWrite = RedisQtAddWrite; | ||
| 90 | m_ctx->ev.delWrite = RedisQtDelWrite; | ||
| 91 | m_ctx->ev.cleanup = RedisQtCleanup; | ||
| 92 | return REDIS_OK; | ||
| 93 | } | ||
| 94 | |||
| 95 | private: | ||
| 96 | void addRead() { | ||
| 97 | if (m_read) return; | ||
| 98 | m_read = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Read, 0); | ||
| 99 | connect(m_read, SIGNAL(activated(int)), this, SLOT(read())); | ||
| 100 | } | ||
| 101 | |||
| 102 | void delRead() { | ||
| 103 | if (!m_read) return; | ||
| 104 | delete m_read; | ||
| 105 | m_read = 0; | ||
| 106 | } | ||
| 107 | |||
| 108 | void addWrite() { | ||
| 109 | if (m_write) return; | ||
| 110 | m_write = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Write, 0); | ||
| 111 | connect(m_write, SIGNAL(activated(int)), this, SLOT(write())); | ||
| 112 | } | ||
| 113 | |||
| 114 | void delWrite() { | ||
| 115 | if (!m_write) return; | ||
| 116 | delete m_write; | ||
| 117 | m_write = 0; | ||
| 118 | } | ||
| 119 | |||
| 120 | void cleanup() { | ||
| 121 | delRead(); | ||
| 122 | delWrite(); | ||
| 123 | } | ||
| 124 | |||
| 125 | private slots: | ||
| 126 | void read() { redisAsyncHandleRead(m_ctx); } | ||
| 127 | void write() { redisAsyncHandleWrite(m_ctx); } | ||
| 128 | |||
| 129 | private: | ||
| 130 | redisAsyncContext * m_ctx; | ||
| 131 | QSocketNotifier * m_read; | ||
| 132 | QSocketNotifier * m_write; | ||
| 133 | }; | ||
| 134 | |||
| 135 | #endif /* !__HIREDIS_QT_H__ */ | ||
diff --git a/examples/redis-unstable/deps/hiredis/adapters/redismoduleapi.h b/examples/redis-unstable/deps/hiredis/adapters/redismoduleapi.h new file mode 100644 index 0000000..8a076fe --- /dev/null +++ b/examples/redis-unstable/deps/hiredis/adapters/redismoduleapi.h | |||
| @@ -0,0 +1,144 @@ | |||
| 1 | #ifndef __HIREDIS_REDISMODULEAPI_H__ | ||
| 2 | #define __HIREDIS_REDISMODULEAPI_H__ | ||
| 3 | |||
| 4 | #include "redismodule.h" | ||
| 5 | |||
| 6 | #include "../async.h" | ||
| 7 | #include "../hiredis.h" | ||
| 8 | |||
| 9 | #include <sys/types.h> | ||
| 10 | |||
| 11 | typedef struct redisModuleEvents { | ||
| 12 | redisAsyncContext *context; | ||
| 13 | RedisModuleCtx *module_ctx; | ||
| 14 | int fd; | ||
| 15 | int reading, writing; | ||
| 16 | int timer_active; | ||
| 17 | RedisModuleTimerID timer_id; | ||
| 18 | } redisModuleEvents; | ||
| 19 | |||
| 20 | static inline void redisModuleReadEvent(int fd, void *privdata, int mask) { | ||
| 21 | (void) fd; | ||
| 22 | (void) mask; | ||
| 23 | |||
| 24 | redisModuleEvents *e = (redisModuleEvents*)privdata; | ||
| 25 | redisAsyncHandleRead(e->context); | ||
| 26 | } | ||
| 27 | |||
| 28 | static inline void redisModuleWriteEvent(int fd, void *privdata, int mask) { | ||
| 29 | (void) fd; | ||
| 30 | (void) mask; | ||
| 31 | |||
| 32 | redisModuleEvents *e = (redisModuleEvents*)privdata; | ||
| 33 | redisAsyncHandleWrite(e->context); | ||
| 34 | } | ||
| 35 | |||
| 36 | static inline void redisModuleAddRead(void *privdata) { | ||
| 37 | redisModuleEvents *e = (redisModuleEvents*)privdata; | ||
| 38 | if (!e->reading) { | ||
| 39 | e->reading = 1; | ||
| 40 | RedisModule_EventLoopAdd(e->fd, REDISMODULE_EVENTLOOP_READABLE, redisModuleReadEvent, e); | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 44 | static inline void redisModuleDelRead(void *privdata) { | ||
| 45 | redisModuleEvents *e = (redisModuleEvents*)privdata; | ||
| 46 | if (e->reading) { | ||
| 47 | e->reading = 0; | ||
| 48 | RedisModule_EventLoopDel(e->fd, REDISMODULE_EVENTLOOP_READABLE); | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | static inline void redisModuleAddWrite(void *privdata) { | ||
| 53 | redisModuleEvents *e = (redisModuleEvents*)privdata; | ||
| 54 | if (!e->writing) { | ||
| 55 | e->writing = 1; | ||
| 56 | RedisModule_EventLoopAdd(e->fd, REDISMODULE_EVENTLOOP_WRITABLE, redisModuleWriteEvent, e); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | static inline void redisModuleDelWrite(void *privdata) { | ||
| 61 | redisModuleEvents *e = (redisModuleEvents*)privdata; | ||
| 62 | if (e->writing) { | ||
| 63 | e->writing = 0; | ||
| 64 | RedisModule_EventLoopDel(e->fd, REDISMODULE_EVENTLOOP_WRITABLE); | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | static inline void redisModuleStopTimer(void *privdata) { | ||
| 69 | redisModuleEvents *e = (redisModuleEvents*)privdata; | ||
| 70 | if (e->timer_active) { | ||
| 71 | RedisModule_StopTimer(e->module_ctx, e->timer_id, NULL); | ||
| 72 | } | ||
| 73 | e->timer_active = 0; | ||
| 74 | } | ||
| 75 | |||
| 76 | static inline void redisModuleCleanup(void *privdata) { | ||
| 77 | redisModuleEvents *e = (redisModuleEvents*)privdata; | ||
| 78 | redisModuleDelRead(privdata); | ||
| 79 | redisModuleDelWrite(privdata); | ||
| 80 | redisModuleStopTimer(privdata); | ||
| 81 | hi_free(e); | ||
| 82 | } | ||
| 83 | |||
| 84 | static inline void redisModuleTimeout(RedisModuleCtx *ctx, void *privdata) { | ||
| 85 | (void) ctx; | ||
| 86 | |||
| 87 | redisModuleEvents *e = (redisModuleEvents*)privdata; | ||
| 88 | e->timer_active = 0; | ||
| 89 | redisAsyncHandleTimeout(e->context); | ||
| 90 | } | ||
| 91 | |||
| 92 | static inline void redisModuleSetTimeout(void *privdata, struct timeval tv) { | ||
| 93 | redisModuleEvents* e = (redisModuleEvents*)privdata; | ||
| 94 | |||
| 95 | redisModuleStopTimer(privdata); | ||
| 96 | |||
| 97 | mstime_t millis = tv.tv_sec * 1000 + tv.tv_usec / 1000.0; | ||
| 98 | e->timer_id = RedisModule_CreateTimer(e->module_ctx, millis, redisModuleTimeout, e); | ||
| 99 | e->timer_active = 1; | ||
| 100 | } | ||
| 101 | |||
| 102 | /* Check if Redis version is compatible with the adapter. */ | ||
| 103 | static inline int redisModuleCompatibilityCheck(void) { | ||
| 104 | if (!RedisModule_EventLoopAdd || | ||
| 105 | !RedisModule_EventLoopDel || | ||
| 106 | !RedisModule_CreateTimer || | ||
| 107 | !RedisModule_StopTimer) { | ||
| 108 | return REDIS_ERR; | ||
| 109 | } | ||
| 110 | return REDIS_OK; | ||
| 111 | } | ||
| 112 | |||
| 113 | static inline int redisModuleAttach(redisAsyncContext *ac, RedisModuleCtx *module_ctx) { | ||
| 114 | redisContext *c = &(ac->c); | ||
| 115 | redisModuleEvents *e; | ||
| 116 | |||
| 117 | /* Nothing should be attached when something is already attached */ | ||
| 118 | if (ac->ev.data != NULL) | ||
| 119 | return REDIS_ERR; | ||
| 120 | |||
| 121 | /* Create container for context and r/w events */ | ||
| 122 | e = (redisModuleEvents*)hi_malloc(sizeof(*e)); | ||
| 123 | if (e == NULL) | ||
| 124 | return REDIS_ERR; | ||
| 125 | |||
| 126 | e->context = ac; | ||
| 127 | e->module_ctx = module_ctx; | ||
| 128 | e->fd = c->fd; | ||
| 129 | e->reading = e->writing = 0; | ||
| 130 | e->timer_active = 0; | ||
| 131 | |||
| 132 | /* Register functions to start/stop listening for events */ | ||
| 133 | ac->ev.addRead = redisModuleAddRead; | ||
| 134 | ac->ev.delRead = redisModuleDelRead; | ||
| 135 | ac->ev.addWrite = redisModuleAddWrite; | ||
| 136 | ac->ev.delWrite = redisModuleDelWrite; | ||
| 137 | ac->ev.cleanup = redisModuleCleanup; | ||
| 138 | ac->ev.scheduleTimer = redisModuleSetTimeout; | ||
| 139 | ac->ev.data = e; | ||
| 140 | |||
| 141 | return REDIS_OK; | ||
| 142 | } | ||
| 143 | |||
| 144 | #endif | ||
