]>
Commit | Line | Data |
---|---|---|
1 | #ifndef __HIREDIS_LIBEV_H__ | |
2 | #define __HIREDIS_LIBEV_H__ | |
3 | #include <stdlib.h> | |
4 | #include <sys/types.h> | |
5 | #include <ev.h> | |
6 | #include "../hiredis.h" | |
7 | #include "../async.h" | |
8 | ||
9 | typedef struct redisLibevEvents { | |
10 | redisAsyncContext *context; | |
11 | struct ev_loop *loop; | |
12 | int reading, writing; | |
13 | ev_io rev, wev; | |
14 | } redisLibevEvents; | |
15 | ||
16 | static void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) { | |
17 | #if EV_MULTIPLICITY | |
18 | ((void)loop); | |
19 | #endif | |
20 | ((void)revents); | |
21 | ||
22 | redisLibevEvents *e = (redisLibevEvents*)watcher->data; | |
23 | redisAsyncHandleRead(e->context); | |
24 | } | |
25 | ||
26 | static void redisLibevWriteEvent(EV_P_ ev_io *watcher, int revents) { | |
27 | #if EV_MULTIPLICITY | |
28 | ((void)loop); | |
29 | #endif | |
30 | ((void)revents); | |
31 | ||
32 | redisLibevEvents *e = (redisLibevEvents*)watcher->data; | |
33 | redisAsyncHandleWrite(e->context); | |
34 | } | |
35 | ||
36 | static void redisLibevAddRead(void *privdata) { | |
37 | redisLibevEvents *e = (redisLibevEvents*)privdata; | |
38 | struct ev_loop *loop = e->loop; | |
39 | ((void)loop); | |
40 | if (!e->reading) { | |
41 | e->reading = 1; | |
42 | ev_io_start(EV_A_ &e->rev); | |
43 | } | |
44 | } | |
45 | ||
46 | static void redisLibevDelRead(void *privdata) { | |
47 | redisLibevEvents *e = (redisLibevEvents*)privdata; | |
48 | struct ev_loop *loop = e->loop; | |
49 | ((void)loop); | |
50 | if (e->reading) { | |
51 | e->reading = 0; | |
52 | ev_io_stop(EV_A_ &e->rev); | |
53 | } | |
54 | } | |
55 | ||
56 | static void redisLibevAddWrite(void *privdata) { | |
57 | redisLibevEvents *e = (redisLibevEvents*)privdata; | |
58 | struct ev_loop *loop = e->loop; | |
59 | ((void)loop); | |
60 | if (!e->writing) { | |
61 | e->writing = 1; | |
62 | ev_io_start(EV_A_ &e->wev); | |
63 | } | |
64 | } | |
65 | ||
66 | static void redisLibevDelWrite(void *privdata) { | |
67 | redisLibevEvents *e = (redisLibevEvents*)privdata; | |
68 | struct ev_loop *loop = e->loop; | |
69 | ((void)loop); | |
70 | if (e->writing) { | |
71 | e->writing = 0; | |
72 | ev_io_stop(EV_A_ &e->wev); | |
73 | } | |
74 | } | |
75 | ||
76 | static void redisLibevCleanup(void *privdata) { | |
77 | redisLibevEvents *e = (redisLibevEvents*)privdata; | |
78 | redisLibevDelRead(privdata); | |
79 | redisLibevDelWrite(privdata); | |
80 | free(e); | |
81 | } | |
82 | ||
83 | static int redisLibevAttach(EV_P_ redisAsyncContext *ac) { | |
84 | redisContext *c = &(ac->c); | |
85 | redisLibevEvents *e; | |
86 | ||
87 | /* Nothing should be attached when something is already attached */ | |
88 | if (ac->ev.data != NULL) | |
89 | return REDIS_ERR; | |
90 | ||
91 | /* Create container for context and r/w events */ | |
92 | e = (redisLibevEvents*)malloc(sizeof(*e)); | |
93 | e->context = ac; | |
94 | #if EV_MULTIPLICITY | |
95 | e->loop = loop; | |
96 | #else | |
97 | e->loop = NULL; | |
98 | #endif | |
99 | e->reading = e->writing = 0; | |
100 | e->rev.data = e; | |
101 | e->wev.data = e; | |
102 | ||
103 | /* Register functions to start/stop listening for events */ | |
104 | ac->ev.addRead = redisLibevAddRead; | |
105 | ac->ev.delRead = redisLibevDelRead; | |
106 | ac->ev.addWrite = redisLibevAddWrite; | |
107 | ac->ev.delWrite = redisLibevDelWrite; | |
108 | ac->ev.cleanup = redisLibevCleanup; | |
109 | ac->ev.data = e; | |
110 | ||
111 | /* Initialize read/write events */ | |
112 | ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ); | |
113 | ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE); | |
114 | return REDIS_OK; | |
115 | } | |
116 | ||
117 | #endif |