1*7f2fe78bSCy Schubert /*
2*7f2fe78bSCy Schubert * Copyright 2011 Red Hat, Inc.
3*7f2fe78bSCy Schubert *
4*7f2fe78bSCy Schubert * Permission is hereby granted, free of charge, to any person
5*7f2fe78bSCy Schubert * obtaining a copy of this software and associated documentation files
6*7f2fe78bSCy Schubert * (the "Software"), to deal in the Software without restriction,
7*7f2fe78bSCy Schubert * including without limitation the rights to use, copy, modify, merge,
8*7f2fe78bSCy Schubert * publish, distribute, sublicense, and/or sell copies of the Software,
9*7f2fe78bSCy Schubert * and to permit persons to whom the Software is furnished to do so,
10*7f2fe78bSCy Schubert * subject to the following conditions:
11*7f2fe78bSCy Schubert *
12*7f2fe78bSCy Schubert * The above copyright notice and this permission notice shall be
13*7f2fe78bSCy Schubert * included in all copies or substantial portions of the Software.
14*7f2fe78bSCy Schubert *
15*7f2fe78bSCy Schubert * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*7f2fe78bSCy Schubert * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*7f2fe78bSCy Schubert * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18*7f2fe78bSCy Schubert * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19*7f2fe78bSCy Schubert * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20*7f2fe78bSCy Schubert * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21*7f2fe78bSCy Schubert * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22*7f2fe78bSCy Schubert * SOFTWARE.
23*7f2fe78bSCy Schubert */
24*7f2fe78bSCy Schubert
25*7f2fe78bSCy Schubert #include <stdlib.h>
26*7f2fe78bSCy Schubert #include <string.h>
27*7f2fe78bSCy Schubert #include <errno.h>
28*7f2fe78bSCy Schubert
29*7f2fe78bSCy Schubert #include <verto-libev.h>
30*7f2fe78bSCy Schubert #define VERTO_MODULE_TYPES
31*7f2fe78bSCy Schubert typedef struct ev_loop verto_mod_ctx;
32*7f2fe78bSCy Schubert typedef ev_watcher verto_mod_ev;
33*7f2fe78bSCy Schubert #include <verto-module.h>
34*7f2fe78bSCy Schubert
35*7f2fe78bSCy Schubert static verto_mod_ctx *
libev_ctx_new(void)36*7f2fe78bSCy Schubert libev_ctx_new(void)
37*7f2fe78bSCy Schubert {
38*7f2fe78bSCy Schubert return ev_loop_new(EVFLAG_AUTO);
39*7f2fe78bSCy Schubert }
40*7f2fe78bSCy Schubert
41*7f2fe78bSCy Schubert static verto_mod_ctx *
libev_ctx_default(void)42*7f2fe78bSCy Schubert libev_ctx_default(void)
43*7f2fe78bSCy Schubert {
44*7f2fe78bSCy Schubert return ev_default_loop(EVFLAG_AUTO);
45*7f2fe78bSCy Schubert }
46*7f2fe78bSCy Schubert
47*7f2fe78bSCy Schubert static void
libev_ctx_free(verto_mod_ctx * ctx)48*7f2fe78bSCy Schubert libev_ctx_free(verto_mod_ctx *ctx)
49*7f2fe78bSCy Schubert {
50*7f2fe78bSCy Schubert if (ctx != EV_DEFAULT)
51*7f2fe78bSCy Schubert ev_loop_destroy(ctx);
52*7f2fe78bSCy Schubert }
53*7f2fe78bSCy Schubert
54*7f2fe78bSCy Schubert static void
libev_ctx_run(verto_mod_ctx * ctx)55*7f2fe78bSCy Schubert libev_ctx_run(verto_mod_ctx *ctx)
56*7f2fe78bSCy Schubert {
57*7f2fe78bSCy Schubert ev_run(ctx, 0);
58*7f2fe78bSCy Schubert }
59*7f2fe78bSCy Schubert
60*7f2fe78bSCy Schubert static void
libev_ctx_run_once(verto_mod_ctx * ctx)61*7f2fe78bSCy Schubert libev_ctx_run_once(verto_mod_ctx *ctx)
62*7f2fe78bSCy Schubert {
63*7f2fe78bSCy Schubert ev_run(ctx, EVRUN_ONCE);
64*7f2fe78bSCy Schubert }
65*7f2fe78bSCy Schubert
66*7f2fe78bSCy Schubert static void
libev_ctx_break(verto_mod_ctx * ctx)67*7f2fe78bSCy Schubert libev_ctx_break(verto_mod_ctx *ctx)
68*7f2fe78bSCy Schubert {
69*7f2fe78bSCy Schubert ev_break(ctx, EVBREAK_ONE);
70*7f2fe78bSCy Schubert }
71*7f2fe78bSCy Schubert
72*7f2fe78bSCy Schubert static void
libev_ctx_reinitialize(verto_mod_ctx * ctx)73*7f2fe78bSCy Schubert libev_ctx_reinitialize(verto_mod_ctx *ctx)
74*7f2fe78bSCy Schubert {
75*7f2fe78bSCy Schubert ev_loop_fork(ctx);
76*7f2fe78bSCy Schubert }
77*7f2fe78bSCy Schubert
78*7f2fe78bSCy Schubert static void
libev_callback(EV_P_ ev_watcher * w,int revents)79*7f2fe78bSCy Schubert libev_callback(EV_P_ ev_watcher *w, int revents)
80*7f2fe78bSCy Schubert {
81*7f2fe78bSCy Schubert verto_ev_flag state = VERTO_EV_FLAG_NONE;
82*7f2fe78bSCy Schubert
83*7f2fe78bSCy Schubert #if EV_MULTIPLICITY
84*7f2fe78bSCy Schubert /* Match the check in ev.h, which doesn't mark this unused */
85*7f2fe78bSCy Schubert (void) EV_A;
86*7f2fe78bSCy Schubert #endif
87*7f2fe78bSCy Schubert
88*7f2fe78bSCy Schubert if (verto_get_type(w->data)== VERTO_EV_TYPE_CHILD)
89*7f2fe78bSCy Schubert verto_set_proc_status(w->data, ((ev_child*) w)->rstatus);
90*7f2fe78bSCy Schubert
91*7f2fe78bSCy Schubert if (revents & EV_READ)
92*7f2fe78bSCy Schubert state |= VERTO_EV_FLAG_IO_READ;
93*7f2fe78bSCy Schubert if (revents & EV_WRITE)
94*7f2fe78bSCy Schubert state |= VERTO_EV_FLAG_IO_WRITE;
95*7f2fe78bSCy Schubert if (revents & EV_ERROR)
96*7f2fe78bSCy Schubert state |= VERTO_EV_FLAG_IO_ERROR;
97*7f2fe78bSCy Schubert
98*7f2fe78bSCy Schubert verto_set_fd_state(w->data, state);
99*7f2fe78bSCy Schubert verto_fire(w->data);
100*7f2fe78bSCy Schubert }
101*7f2fe78bSCy Schubert
102*7f2fe78bSCy Schubert static void
libev_ctx_set_flags(verto_mod_ctx * ctx,const verto_ev * ev,verto_mod_ev * evpriv)103*7f2fe78bSCy Schubert libev_ctx_set_flags(verto_mod_ctx *ctx, const verto_ev *ev,
104*7f2fe78bSCy Schubert verto_mod_ev *evpriv)
105*7f2fe78bSCy Schubert {
106*7f2fe78bSCy Schubert if (verto_get_type(ev) == VERTO_EV_TYPE_IO) {
107*7f2fe78bSCy Schubert int events = EV_NONE;
108*7f2fe78bSCy Schubert
109*7f2fe78bSCy Schubert if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_READ)
110*7f2fe78bSCy Schubert events |= EV_READ;
111*7f2fe78bSCy Schubert if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_WRITE)
112*7f2fe78bSCy Schubert events |= EV_WRITE;
113*7f2fe78bSCy Schubert
114*7f2fe78bSCy Schubert ev_io_stop(ctx, (ev_io*) evpriv);
115*7f2fe78bSCy Schubert ev_io_set(((ev_io*) evpriv), verto_get_fd(ev), events);
116*7f2fe78bSCy Schubert ev_io_start(ctx, (ev_io*) evpriv);
117*7f2fe78bSCy Schubert }
118*7f2fe78bSCy Schubert }
119*7f2fe78bSCy Schubert
120*7f2fe78bSCy Schubert #define setuptype(type, ...) \
121*7f2fe78bSCy Schubert w.type = malloc(sizeof(ev_ ## type)); \
122*7f2fe78bSCy Schubert if (w.type) { \
123*7f2fe78bSCy Schubert ev_ ## type ## _init(w.type, (EV_CB(type, (*))) __VA_ARGS__); \
124*7f2fe78bSCy Schubert ev_ ## type ## _start(ctx, w.type); \
125*7f2fe78bSCy Schubert } \
126*7f2fe78bSCy Schubert break
127*7f2fe78bSCy Schubert
128*7f2fe78bSCy Schubert static verto_mod_ev *
libev_ctx_add(verto_mod_ctx * ctx,const verto_ev * ev,verto_ev_flag * flags)129*7f2fe78bSCy Schubert libev_ctx_add(verto_mod_ctx *ctx, const verto_ev *ev, verto_ev_flag *flags)
130*7f2fe78bSCy Schubert {
131*7f2fe78bSCy Schubert union {
132*7f2fe78bSCy Schubert ev_watcher *watcher;
133*7f2fe78bSCy Schubert ev_io *io;
134*7f2fe78bSCy Schubert ev_timer *timer;
135*7f2fe78bSCy Schubert ev_idle *idle;
136*7f2fe78bSCy Schubert ev_signal *signal;
137*7f2fe78bSCy Schubert ev_child *child;
138*7f2fe78bSCy Schubert } w;
139*7f2fe78bSCy Schubert ev_tstamp interval;
140*7f2fe78bSCy Schubert
141*7f2fe78bSCy Schubert w.watcher = NULL;
142*7f2fe78bSCy Schubert *flags |= VERTO_EV_FLAG_PERSIST;
143*7f2fe78bSCy Schubert switch (verto_get_type(ev)) {
144*7f2fe78bSCy Schubert case VERTO_EV_TYPE_IO:
145*7f2fe78bSCy Schubert setuptype(io, libev_callback, verto_get_fd(ev), EV_NONE);
146*7f2fe78bSCy Schubert case VERTO_EV_TYPE_TIMEOUT:
147*7f2fe78bSCy Schubert interval = ((ev_tstamp) verto_get_interval(ev)) / 1000.0;
148*7f2fe78bSCy Schubert setuptype(timer, libev_callback, interval, interval);
149*7f2fe78bSCy Schubert case VERTO_EV_TYPE_IDLE:
150*7f2fe78bSCy Schubert setuptype(idle, libev_callback);
151*7f2fe78bSCy Schubert case VERTO_EV_TYPE_SIGNAL:
152*7f2fe78bSCy Schubert setuptype(signal, libev_callback, verto_get_signal(ev));
153*7f2fe78bSCy Schubert case VERTO_EV_TYPE_CHILD:
154*7f2fe78bSCy Schubert *flags &= ~VERTO_EV_FLAG_PERSIST; /* Child events don't persist */
155*7f2fe78bSCy Schubert setuptype(child, libev_callback, verto_get_proc(ev), 0);
156*7f2fe78bSCy Schubert default:
157*7f2fe78bSCy Schubert break; /* Not supported */
158*7f2fe78bSCy Schubert }
159*7f2fe78bSCy Schubert
160*7f2fe78bSCy Schubert if (w.watcher) {
161*7f2fe78bSCy Schubert w.watcher->data = (void*) ev;
162*7f2fe78bSCy Schubert libev_ctx_set_flags(ctx, ev, w.watcher);
163*7f2fe78bSCy Schubert }
164*7f2fe78bSCy Schubert return w.watcher;
165*7f2fe78bSCy Schubert }
166*7f2fe78bSCy Schubert
167*7f2fe78bSCy Schubert static void
libev_ctx_del(verto_mod_ctx * ctx,const verto_ev * ev,verto_mod_ev * evpriv)168*7f2fe78bSCy Schubert libev_ctx_del(verto_mod_ctx *ctx, const verto_ev *ev, verto_mod_ev *evpriv)
169*7f2fe78bSCy Schubert {
170*7f2fe78bSCy Schubert switch (verto_get_type(ev)) {
171*7f2fe78bSCy Schubert case VERTO_EV_TYPE_IO:
172*7f2fe78bSCy Schubert ev_io_stop(ctx, (ev_io*) evpriv);
173*7f2fe78bSCy Schubert break;
174*7f2fe78bSCy Schubert case VERTO_EV_TYPE_TIMEOUT:
175*7f2fe78bSCy Schubert ev_timer_stop(ctx, (ev_timer*) evpriv);
176*7f2fe78bSCy Schubert break;
177*7f2fe78bSCy Schubert case VERTO_EV_TYPE_IDLE:
178*7f2fe78bSCy Schubert ev_idle_stop(ctx, (ev_idle*) evpriv);
179*7f2fe78bSCy Schubert break;
180*7f2fe78bSCy Schubert case VERTO_EV_TYPE_SIGNAL:
181*7f2fe78bSCy Schubert ev_signal_stop(ctx, (ev_signal*) evpriv);
182*7f2fe78bSCy Schubert break;
183*7f2fe78bSCy Schubert case VERTO_EV_TYPE_CHILD:
184*7f2fe78bSCy Schubert ev_child_stop(ctx, (ev_child*) evpriv);
185*7f2fe78bSCy Schubert break;
186*7f2fe78bSCy Schubert default:
187*7f2fe78bSCy Schubert break;
188*7f2fe78bSCy Schubert }
189*7f2fe78bSCy Schubert
190*7f2fe78bSCy Schubert free(evpriv);
191*7f2fe78bSCy Schubert }
192*7f2fe78bSCy Schubert
193*7f2fe78bSCy Schubert VERTO_MODULE(libev, ev_loop_new,
194*7f2fe78bSCy Schubert VERTO_EV_TYPE_IO |
195*7f2fe78bSCy Schubert VERTO_EV_TYPE_TIMEOUT |
196*7f2fe78bSCy Schubert VERTO_EV_TYPE_IDLE |
197*7f2fe78bSCy Schubert VERTO_EV_TYPE_SIGNAL |
198*7f2fe78bSCy Schubert VERTO_EV_TYPE_CHILD);
199*7f2fe78bSCy Schubert
200*7f2fe78bSCy Schubert verto_ctx *
verto_convert_libev(struct ev_loop * loop)201*7f2fe78bSCy Schubert verto_convert_libev(struct ev_loop* loop)
202*7f2fe78bSCy Schubert {
203*7f2fe78bSCy Schubert return verto_convert(libev, 0, loop);
204*7f2fe78bSCy Schubert }
205