File Coverage

src/libev_adapter.h
Criterion Covered Total %
statement 0 70 0.0
branch 0 18 0.0
condition n/a
subroutine n/a
pod n/a
total 0 88 0.0


line stmt bran cond sub pod time code
1             /* modified version of hiredis's libev adapter */
2             #ifndef __HIREDIS_LIBEV_H__
3             #define __HIREDIS_LIBEV_H__
4             #include "EXTERN.h"
5             #include "perl.h"
6             #include "XSUB.h"
7             #include "ppport.h"
8              
9             #include
10             #include
11              
12             #include "EVAPI.h"
13              
14             #include "hiredis.h"
15             #include "async.h"
16              
17             typedef struct redisLibevEvents {
18             redisAsyncContext *context;
19             struct ev_loop *loop;
20             int reading, writing, timing;
21             ev_io rev, wev;
22             ev_timer timer;
23             } redisLibevEvents;
24              
25 0           static void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) {
26             #if EV_MULTIPLICITY
27             ((void)loop);
28             #endif
29             ((void)revents);
30              
31 0           redisLibevEvents *e = (redisLibevEvents*)watcher->data;
32 0           redisAsyncHandleRead(e->context);
33 0           }
34              
35 0           static void redisLibevWriteEvent(EV_P_ ev_io *watcher, int revents) {
36             #if EV_MULTIPLICITY
37             ((void)loop);
38             #endif
39             ((void)revents);
40              
41 0           redisLibevEvents *e = (redisLibevEvents*)watcher->data;
42 0           redisAsyncHandleWrite(e->context);
43 0           }
44              
45 0           static void redisLibevAddRead(void *privdata) {
46             redisLibevEvents *e = (redisLibevEvents*)privdata;
47 0           struct ev_loop *loop = e->loop;
48             ((void)loop);
49 0 0         if (!e->reading) {
50 0           e->reading = 1;
51 0           ev_io_start(loop, &e->rev);
52             }
53 0           }
54              
55 0           static void redisLibevDelRead(void *privdata) {
56             redisLibevEvents *e = (redisLibevEvents*)privdata;
57 0           struct ev_loop *loop = e->loop;
58             ((void)loop);
59 0 0         if (e->reading) {
    0          
60 0           e->reading = 0;
61 0           ev_io_stop(loop, &e->rev);
62             }
63 0           }
64              
65 0           static void redisLibevAddWrite(void *privdata) {
66             redisLibevEvents *e = (redisLibevEvents*)privdata;
67 0           struct ev_loop *loop = e->loop;
68             ((void)loop);
69 0 0         if (!e->writing) {
70 0           e->writing = 1;
71 0           ev_io_start(loop, &e->wev);
72             }
73 0           }
74              
75 0           static void redisLibevDelWrite(void *privdata) {
76             redisLibevEvents *e = (redisLibevEvents*)privdata;
77 0           struct ev_loop *loop = e->loop;
78             ((void)loop);
79 0 0         if (e->writing) {
    0          
80 0           e->writing = 0;
81 0           ev_io_stop(loop, &e->wev);
82             }
83 0           }
84              
85             static void redisLibevStopTimer(void *privdata) {
86             redisLibevEvents *e = (redisLibevEvents*)privdata;
87 0           struct ev_loop *loop = e->loop;
88             ((void)loop);
89 0 0         if (e->timing) {
90 0           e->timing = 0;
91 0           ev_timer_stop(loop, &e->timer);
92             }
93             }
94              
95              
96 0           static void redisLibevCleanup(void *privdata) {
97             redisLibevEvents *e = (redisLibevEvents*)privdata;
98             redisLibevDelRead(privdata);
99             redisLibevDelWrite(privdata);
100             redisLibevStopTimer(privdata);
101 0           free(e);
102 0           }
103              
104 0           static void redisLibevTimeout(EV_P_ ev_timer *timer, int revents) {
105             #if EV_MULTIPLICITY
106             ((void)loop);
107             #endif
108             ((void)revents);
109              
110 0           redisLibevEvents *e = (redisLibevEvents*)timer->data;
111 0           redisAsyncHandleTimeout(e->context);
112 0           }
113              
114 0           static void redisLibevSetTimeout(void *privdata, struct timeval tv) {
115             redisLibevEvents *e = (redisLibevEvents*)privdata;
116 0           struct ev_loop *loop = e->loop;
117             ((void)loop);
118              
119 0 0         if (!e->timing) {
120 0           e->timing = 1;
121 0           ev_init(&e->timer, redisLibevTimeout);
122 0           e->timer.data = e;
123             }
124              
125 0           e->timer.repeat = tv.tv_sec + tv.tv_usec / 1000000.00;
126 0           ev_timer_again(loop, &e->timer);
127 0           }
128              
129              
130 0           static int redisLibevAttach(EV_P_ redisAsyncContext *ac) {
131             redisContext *c = &(ac->c);
132             redisLibevEvents *e;
133              
134             /* Nothing should be attached when something is already attached */
135 0 0         if (ac->ev.data != NULL)
136             return REDIS_ERR;
137              
138             /* Create container for context and r/w events */
139 0           e = (redisLibevEvents*)malloc(sizeof(*e));
140 0           e->context = ac;
141             #if EV_MULTIPLICITY
142 0           e->loop = loop;
143             #else
144             e->loop = NULL;
145             #endif
146 0           e->reading = e->writing = e->timing = 0;
147 0           e->rev.data = (SV*)e;
148 0           e->wev.data = (SV*)e;
149              
150             /* Register functions to start/stop listening for events */
151 0           ac->ev.addRead = redisLibevAddRead;
152 0           ac->ev.delRead = redisLibevDelRead;
153 0           ac->ev.addWrite = redisLibevAddWrite;
154 0           ac->ev.delWrite = redisLibevDelWrite;
155 0           ac->ev.cleanup = redisLibevCleanup;
156 0           ac->ev.scheduleTimer = redisLibevSetTimeout;
157 0           ac->ev.data = e;
158              
159             /* Initialize read/write events */
160 0           ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ);
161 0           ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE);
162 0           return REDIS_OK;
163             }
164              
165             #endif