redis-client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +190 -0
  3. data/CHANGELOG.md +3 -0
  4. data/Gemfile +23 -0
  5. data/Gemfile.lock +67 -0
  6. data/LICENSE.md +21 -0
  7. data/README.md +347 -0
  8. data/Rakefile +86 -0
  9. data/ext/redis_client/hiredis/extconf.rb +54 -0
  10. data/ext/redis_client/hiredis/hiredis_connection.c +696 -0
  11. data/ext/redis_client/hiredis/vendor/.gitignore +9 -0
  12. data/ext/redis_client/hiredis/vendor/.travis.yml +131 -0
  13. data/ext/redis_client/hiredis/vendor/CHANGELOG.md +364 -0
  14. data/ext/redis_client/hiredis/vendor/CMakeLists.txt +165 -0
  15. data/ext/redis_client/hiredis/vendor/COPYING +29 -0
  16. data/ext/redis_client/hiredis/vendor/Makefile +308 -0
  17. data/ext/redis_client/hiredis/vendor/README.md +664 -0
  18. data/ext/redis_client/hiredis/vendor/adapters/ae.h +130 -0
  19. data/ext/redis_client/hiredis/vendor/adapters/glib.h +156 -0
  20. data/ext/redis_client/hiredis/vendor/adapters/ivykis.h +84 -0
  21. data/ext/redis_client/hiredis/vendor/adapters/libev.h +179 -0
  22. data/ext/redis_client/hiredis/vendor/adapters/libevent.h +175 -0
  23. data/ext/redis_client/hiredis/vendor/adapters/libuv.h +117 -0
  24. data/ext/redis_client/hiredis/vendor/adapters/macosx.h +115 -0
  25. data/ext/redis_client/hiredis/vendor/adapters/qt.h +135 -0
  26. data/ext/redis_client/hiredis/vendor/alloc.c +86 -0
  27. data/ext/redis_client/hiredis/vendor/alloc.h +91 -0
  28. data/ext/redis_client/hiredis/vendor/appveyor.yml +24 -0
  29. data/ext/redis_client/hiredis/vendor/async.c +887 -0
  30. data/ext/redis_client/hiredis/vendor/async.h +147 -0
  31. data/ext/redis_client/hiredis/vendor/async_private.h +75 -0
  32. data/ext/redis_client/hiredis/vendor/dict.c +352 -0
  33. data/ext/redis_client/hiredis/vendor/dict.h +126 -0
  34. data/ext/redis_client/hiredis/vendor/fmacros.h +12 -0
  35. data/ext/redis_client/hiredis/vendor/hiredis-config.cmake.in +13 -0
  36. data/ext/redis_client/hiredis/vendor/hiredis.c +1174 -0
  37. data/ext/redis_client/hiredis/vendor/hiredis.h +336 -0
  38. data/ext/redis_client/hiredis/vendor/hiredis.pc.in +12 -0
  39. data/ext/redis_client/hiredis/vendor/hiredis_ssl-config.cmake.in +13 -0
  40. data/ext/redis_client/hiredis/vendor/hiredis_ssl.h +157 -0
  41. data/ext/redis_client/hiredis/vendor/hiredis_ssl.pc.in +12 -0
  42. data/ext/redis_client/hiredis/vendor/net.c +612 -0
  43. data/ext/redis_client/hiredis/vendor/net.h +56 -0
  44. data/ext/redis_client/hiredis/vendor/read.c +739 -0
  45. data/ext/redis_client/hiredis/vendor/read.h +129 -0
  46. data/ext/redis_client/hiredis/vendor/sds.c +1289 -0
  47. data/ext/redis_client/hiredis/vendor/sds.h +278 -0
  48. data/ext/redis_client/hiredis/vendor/sdsalloc.h +44 -0
  49. data/ext/redis_client/hiredis/vendor/sockcompat.c +248 -0
  50. data/ext/redis_client/hiredis/vendor/sockcompat.h +92 -0
  51. data/ext/redis_client/hiredis/vendor/ssl.c +544 -0
  52. data/ext/redis_client/hiredis/vendor/test.c +1401 -0
  53. data/ext/redis_client/hiredis/vendor/test.sh +78 -0
  54. data/ext/redis_client/hiredis/vendor/win32.h +56 -0
  55. data/lib/redis-client.rb +3 -0
  56. data/lib/redis_client/buffered_io.rb +149 -0
  57. data/lib/redis_client/config.rb +174 -0
  58. data/lib/redis_client/connection.rb +86 -0
  59. data/lib/redis_client/hiredis_connection.rb +78 -0
  60. data/lib/redis_client/pooled.rb +86 -0
  61. data/lib/redis_client/resp3.rb +225 -0
  62. data/lib/redis_client/sentinel_config.rb +134 -0
  63. data/lib/redis_client/version.rb +5 -0
  64. data/lib/redis_client.rb +438 -0
  65. data/redis-client.gemspec +34 -0
  66. metadata +125 -0
@@ -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
@@ -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__ */
@@ -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
@@ -0,0 +1,179 @@
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)loop);
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)loop);
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
+ struct ev_loop *loop = e->loop;
70
+ ((void)loop);
71
+ if (!e->reading) {
72
+ e->reading = 1;
73
+ ev_io_start(EV_A_ &e->rev);
74
+ }
75
+ }
76
+
77
+ static void redisLibevDelRead(void *privdata) {
78
+ redisLibevEvents *e = (redisLibevEvents*)privdata;
79
+ struct ev_loop *loop = e->loop;
80
+ ((void)loop);
81
+ if (e->reading) {
82
+ e->reading = 0;
83
+ ev_io_stop(EV_A_ &e->rev);
84
+ }
85
+ }
86
+
87
+ static void redisLibevAddWrite(void *privdata) {
88
+ redisLibevEvents *e = (redisLibevEvents*)privdata;
89
+ struct ev_loop *loop = e->loop;
90
+ ((void)loop);
91
+ if (!e->writing) {
92
+ e->writing = 1;
93
+ ev_io_start(EV_A_ &e->wev);
94
+ }
95
+ }
96
+
97
+ static void redisLibevDelWrite(void *privdata) {
98
+ redisLibevEvents *e = (redisLibevEvents*)privdata;
99
+ struct ev_loop *loop = e->loop;
100
+ ((void)loop);
101
+ if (e->writing) {
102
+ e->writing = 0;
103
+ ev_io_stop(EV_A_ &e->wev);
104
+ }
105
+ }
106
+
107
+ static void redisLibevStopTimer(void *privdata) {
108
+ redisLibevEvents *e = (redisLibevEvents*)privdata;
109
+ struct ev_loop *loop = e->loop;
110
+ ((void)loop);
111
+ ev_timer_stop(EV_A_ &e->timer);
112
+ }
113
+
114
+ static void redisLibevCleanup(void *privdata) {
115
+ redisLibevEvents *e = (redisLibevEvents*)privdata;
116
+ redisLibevDelRead(privdata);
117
+ redisLibevDelWrite(privdata);
118
+ redisLibevStopTimer(privdata);
119
+ hi_free(e);
120
+ }
121
+
122
+ static void redisLibevTimeout(EV_P_ ev_timer *timer, int revents) {
123
+ ((void)revents);
124
+ redisLibevEvents *e = (redisLibevEvents*)timer->data;
125
+ redisAsyncHandleTimeout(e->context);
126
+ }
127
+
128
+ static void redisLibevSetTimeout(void *privdata, struct timeval tv) {
129
+ redisLibevEvents *e = (redisLibevEvents*)privdata;
130
+ struct ev_loop *loop = e->loop;
131
+ ((void)loop);
132
+
133
+ if (!ev_is_active(&e->timer)) {
134
+ ev_init(&e->timer, redisLibevTimeout);
135
+ e->timer.data = e;
136
+ }
137
+
138
+ e->timer.repeat = tv.tv_sec + tv.tv_usec / 1000000.00;
139
+ ev_timer_again(EV_A_ &e->timer);
140
+ }
141
+
142
+ static int redisLibevAttach(EV_P_ redisAsyncContext *ac) {
143
+ redisContext *c = &(ac->c);
144
+ redisLibevEvents *e;
145
+
146
+ /* Nothing should be attached when something is already attached */
147
+ if (ac->ev.data != NULL)
148
+ return REDIS_ERR;
149
+
150
+ /* Create container for context and r/w events */
151
+ e = (redisLibevEvents*)hi_calloc(1, sizeof(*e));
152
+ if (e == NULL)
153
+ return REDIS_ERR;
154
+
155
+ e->context = ac;
156
+ #if EV_MULTIPLICITY
157
+ e->loop = loop;
158
+ #else
159
+ e->loop = NULL;
160
+ #endif
161
+ e->rev.data = e;
162
+ e->wev.data = e;
163
+
164
+ /* Register functions to start/stop listening for events */
165
+ ac->ev.addRead = redisLibevAddRead;
166
+ ac->ev.delRead = redisLibevDelRead;
167
+ ac->ev.addWrite = redisLibevAddWrite;
168
+ ac->ev.delWrite = redisLibevDelWrite;
169
+ ac->ev.cleanup = redisLibevCleanup;
170
+ ac->ev.scheduleTimer = redisLibevSetTimeout;
171
+ ac->ev.data = e;
172
+
173
+ /* Initialize read/write events */
174
+ ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ);
175
+ ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE);
176
+ return REDIS_OK;
177
+ }
178
+
179
+ #endif