xref: /freebsd/crypto/krb5/src/util/verto/verto-k5ev.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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 /*
26*7f2fe78bSCy Schubert  * An edited version of verto-libev.c, using an embedded libev with renamed
27*7f2fe78bSCy Schubert  * symbols.  The corresponding version of verto-libev.c is stored in this
28*7f2fe78bSCy Schubert  * directory for reference, although it is not built here.
29*7f2fe78bSCy Schubert  */
30*7f2fe78bSCy Schubert 
31*7f2fe78bSCy Schubert #include "autoconf.h"
32*7f2fe78bSCy Schubert #include <stdlib.h>
33*7f2fe78bSCy Schubert #include <string.h>
34*7f2fe78bSCy Schubert #include <errno.h>
35*7f2fe78bSCy Schubert 
36*7f2fe78bSCy Schubert #include <verto.h>
37*7f2fe78bSCy Schubert #include <verto-module.h>
38*7f2fe78bSCy Schubert #include "rename.h"
39*7f2fe78bSCy Schubert 
40*7f2fe78bSCy Schubert /* Ignore some warnings generated by the libev code, which the libev maintainer
41*7f2fe78bSCy Schubert  * isn't interested in avoiding. */
42*7f2fe78bSCy Schubert #ifdef __GNUC__
43*7f2fe78bSCy Schubert #pragma GCC diagnostic ignored "-Wunused-value"
44*7f2fe78bSCy Schubert #pragma GCC diagnostic ignored "-Wcomment"
45*7f2fe78bSCy Schubert #pragma GCC diagnostic ignored "-Wunused-result"
46*7f2fe78bSCy Schubert #ifdef __clang__
47*7f2fe78bSCy Schubert #pragma GCC diagnostic ignored "-Wbitwise-op-parentheses"
48*7f2fe78bSCy Schubert #endif
49*7f2fe78bSCy Schubert #endif
50*7f2fe78bSCy Schubert 
51*7f2fe78bSCy Schubert #define EV_API_STATIC 1
52*7f2fe78bSCy Schubert #define EV_STANDALONE 1
53*7f2fe78bSCy Schubert /* Avoid using clock_gettime, which would create a dependency on librt. */
54*7f2fe78bSCy Schubert #define EV_USE_MONOTONIC 0
55*7f2fe78bSCy Schubert #define EV_USE_REALTIME 0
56*7f2fe78bSCy Schubert #define EV_FEATURES 0x4f        /* No back ends or optional watchers */
57*7f2fe78bSCy Schubert /* Enable the optional watcher types we use. */
58*7f2fe78bSCy Schubert #define EV_IDLE_ENABLE 1
59*7f2fe78bSCy Schubert #define EV_SIGNAL_ENABLE 1
60*7f2fe78bSCy Schubert #define EV_CHILD_ENABLE 1
61*7f2fe78bSCy Schubert /* Enable the back ends we want. */
62*7f2fe78bSCy Schubert #ifdef HAVE_POLL_H
63*7f2fe78bSCy Schubert #define EV_USE_POLL 1
64*7f2fe78bSCy Schubert #endif
65*7f2fe78bSCy Schubert /* ev.c explicitly disables poll() on Mac or FreeBSD; fall back to select(). */
66*7f2fe78bSCy Schubert #define EV_USE_SELECT 1
67*7f2fe78bSCy Schubert #include "ev.c"
68*7f2fe78bSCy Schubert 
69*7f2fe78bSCy Schubert static verto_mod_ctx *
k5ev_ctx_new(void)70*7f2fe78bSCy Schubert k5ev_ctx_new(void)
71*7f2fe78bSCy Schubert {
72*7f2fe78bSCy Schubert     return ev_loop_new(EVFLAG_AUTO);
73*7f2fe78bSCy Schubert }
74*7f2fe78bSCy Schubert 
75*7f2fe78bSCy Schubert static verto_mod_ctx *
k5ev_ctx_default(void)76*7f2fe78bSCy Schubert k5ev_ctx_default(void)
77*7f2fe78bSCy Schubert {
78*7f2fe78bSCy Schubert     return ev_default_loop(EVFLAG_AUTO);
79*7f2fe78bSCy Schubert }
80*7f2fe78bSCy Schubert 
81*7f2fe78bSCy Schubert static void
k5ev_ctx_free(verto_mod_ctx * ctx)82*7f2fe78bSCy Schubert k5ev_ctx_free(verto_mod_ctx *ctx)
83*7f2fe78bSCy Schubert {
84*7f2fe78bSCy Schubert     if (ctx != EV_DEFAULT)
85*7f2fe78bSCy Schubert         ev_loop_destroy(ctx);
86*7f2fe78bSCy Schubert }
87*7f2fe78bSCy Schubert 
88*7f2fe78bSCy Schubert static void
k5ev_ctx_run(verto_mod_ctx * ctx)89*7f2fe78bSCy Schubert k5ev_ctx_run(verto_mod_ctx *ctx)
90*7f2fe78bSCy Schubert {
91*7f2fe78bSCy Schubert     ev_run(ctx, 0);
92*7f2fe78bSCy Schubert }
93*7f2fe78bSCy Schubert 
94*7f2fe78bSCy Schubert static void
k5ev_ctx_run_once(verto_mod_ctx * ctx)95*7f2fe78bSCy Schubert k5ev_ctx_run_once(verto_mod_ctx *ctx)
96*7f2fe78bSCy Schubert {
97*7f2fe78bSCy Schubert     ev_run(ctx, EVRUN_ONCE);
98*7f2fe78bSCy Schubert }
99*7f2fe78bSCy Schubert 
100*7f2fe78bSCy Schubert static void
k5ev_ctx_break(verto_mod_ctx * ctx)101*7f2fe78bSCy Schubert k5ev_ctx_break(verto_mod_ctx *ctx)
102*7f2fe78bSCy Schubert {
103*7f2fe78bSCy Schubert     ev_break(ctx, EVBREAK_ONE);
104*7f2fe78bSCy Schubert }
105*7f2fe78bSCy Schubert 
106*7f2fe78bSCy Schubert static void
k5ev_ctx_reinitialize(verto_mod_ctx * ctx)107*7f2fe78bSCy Schubert k5ev_ctx_reinitialize(verto_mod_ctx *ctx)
108*7f2fe78bSCy Schubert {
109*7f2fe78bSCy Schubert     ev_loop_fork(ctx);
110*7f2fe78bSCy Schubert }
111*7f2fe78bSCy Schubert 
112*7f2fe78bSCy Schubert static void
libev_callback(EV_P_ ev_watcher * w,int revents)113*7f2fe78bSCy Schubert libev_callback(EV_P_ ev_watcher *w, int revents)
114*7f2fe78bSCy Schubert {
115*7f2fe78bSCy Schubert     verto_ev_flag state = VERTO_EV_FLAG_NONE;
116*7f2fe78bSCy Schubert 
117*7f2fe78bSCy Schubert #if EV_MULTIPLICITY
118*7f2fe78bSCy Schubert     /* Match the check in ev.h, which doesn't mark this unused */
119*7f2fe78bSCy Schubert     (void) EV_A;
120*7f2fe78bSCy Schubert #endif
121*7f2fe78bSCy Schubert 
122*7f2fe78bSCy Schubert     if (verto_get_type(w->data)== VERTO_EV_TYPE_CHILD)
123*7f2fe78bSCy Schubert         verto_set_proc_status(w->data, ((ev_child*) w)->rstatus);
124*7f2fe78bSCy Schubert 
125*7f2fe78bSCy Schubert     if (revents & EV_READ)
126*7f2fe78bSCy Schubert         state |= VERTO_EV_FLAG_IO_READ;
127*7f2fe78bSCy Schubert     if (revents & EV_WRITE)
128*7f2fe78bSCy Schubert         state |= VERTO_EV_FLAG_IO_WRITE;
129*7f2fe78bSCy Schubert     if (revents & EV_ERROR)
130*7f2fe78bSCy Schubert         state |= VERTO_EV_FLAG_IO_ERROR;
131*7f2fe78bSCy Schubert 
132*7f2fe78bSCy Schubert     verto_set_fd_state(w->data, state);
133*7f2fe78bSCy Schubert     verto_fire(w->data);
134*7f2fe78bSCy Schubert }
135*7f2fe78bSCy Schubert 
136*7f2fe78bSCy Schubert static void
k5ev_ctx_set_flags(verto_mod_ctx * ctx,const verto_ev * ev,verto_mod_ev * evpriv)137*7f2fe78bSCy Schubert k5ev_ctx_set_flags(verto_mod_ctx *ctx, const verto_ev *ev,
138*7f2fe78bSCy Schubert 		   verto_mod_ev *evpriv)
139*7f2fe78bSCy Schubert {
140*7f2fe78bSCy Schubert     if (verto_get_type(ev) == VERTO_EV_TYPE_IO) {
141*7f2fe78bSCy Schubert         int events = EV_NONE;
142*7f2fe78bSCy Schubert 
143*7f2fe78bSCy Schubert         if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_READ)
144*7f2fe78bSCy Schubert             events |= EV_READ;
145*7f2fe78bSCy Schubert         if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_WRITE)
146*7f2fe78bSCy Schubert             events |= EV_WRITE;
147*7f2fe78bSCy Schubert 
148*7f2fe78bSCy Schubert         ev_io_stop(ctx, (ev_io*) evpriv);
149*7f2fe78bSCy Schubert         ev_io_set(((ev_io*) evpriv), verto_get_fd(ev), events);
150*7f2fe78bSCy Schubert         ev_io_start(ctx, (ev_io*) evpriv);
151*7f2fe78bSCy Schubert     }
152*7f2fe78bSCy Schubert }
153*7f2fe78bSCy Schubert 
154*7f2fe78bSCy Schubert #define setuptype(type, ...) \
155*7f2fe78bSCy Schubert     w.type = malloc(sizeof(ev_ ## type)); \
156*7f2fe78bSCy Schubert     if (w.type) { \
157*7f2fe78bSCy Schubert     	ev_ ## type ## _init(w.type, (EV_CB(type, (*))) __VA_ARGS__); \
158*7f2fe78bSCy Schubert     	ev_ ## type ## _start(ctx, w.type); \
159*7f2fe78bSCy Schubert     } \
160*7f2fe78bSCy Schubert     break
161*7f2fe78bSCy Schubert 
162*7f2fe78bSCy Schubert static verto_mod_ev *
k5ev_ctx_add(verto_mod_ctx * ctx,const verto_ev * ev,verto_ev_flag * flags)163*7f2fe78bSCy Schubert k5ev_ctx_add(verto_mod_ctx *ctx, const verto_ev *ev, verto_ev_flag *flags)
164*7f2fe78bSCy Schubert {
165*7f2fe78bSCy Schubert     union {
166*7f2fe78bSCy Schubert        ev_watcher *watcher;
167*7f2fe78bSCy Schubert        ev_io *io;
168*7f2fe78bSCy Schubert        ev_timer *timer;
169*7f2fe78bSCy Schubert        ev_idle *idle;
170*7f2fe78bSCy Schubert        ev_signal *signal;
171*7f2fe78bSCy Schubert        ev_child *child;
172*7f2fe78bSCy Schubert     } w;
173*7f2fe78bSCy Schubert     ev_tstamp interval;
174*7f2fe78bSCy Schubert 
175*7f2fe78bSCy Schubert     w.watcher = NULL;
176*7f2fe78bSCy Schubert     *flags |= VERTO_EV_FLAG_PERSIST;
177*7f2fe78bSCy Schubert     switch (verto_get_type(ev)) {
178*7f2fe78bSCy Schubert         case VERTO_EV_TYPE_IO:
179*7f2fe78bSCy Schubert             setuptype(io, libev_callback, verto_get_fd(ev), EV_NONE);
180*7f2fe78bSCy Schubert         case VERTO_EV_TYPE_TIMEOUT:
181*7f2fe78bSCy Schubert             interval = ((ev_tstamp) verto_get_interval(ev)) / 1000.0;
182*7f2fe78bSCy Schubert             setuptype(timer, libev_callback, interval, interval);
183*7f2fe78bSCy Schubert         case VERTO_EV_TYPE_IDLE:
184*7f2fe78bSCy Schubert             setuptype(idle, libev_callback);
185*7f2fe78bSCy Schubert         case VERTO_EV_TYPE_SIGNAL:
186*7f2fe78bSCy Schubert             setuptype(signal, libev_callback, verto_get_signal(ev));
187*7f2fe78bSCy Schubert         case VERTO_EV_TYPE_CHILD:
188*7f2fe78bSCy Schubert             *flags &= ~VERTO_EV_FLAG_PERSIST; /* Child events don't persist */
189*7f2fe78bSCy Schubert             setuptype(child, libev_callback, verto_get_proc(ev), 0);
190*7f2fe78bSCy Schubert         default:
191*7f2fe78bSCy Schubert             break; /* Not supported */
192*7f2fe78bSCy Schubert     }
193*7f2fe78bSCy Schubert 
194*7f2fe78bSCy Schubert     if (w.watcher) {
195*7f2fe78bSCy Schubert         w.watcher->data = (void*) ev;
196*7f2fe78bSCy Schubert         k5ev_ctx_set_flags(ctx, ev, w.watcher);
197*7f2fe78bSCy Schubert     }
198*7f2fe78bSCy Schubert     return w.watcher;
199*7f2fe78bSCy Schubert }
200*7f2fe78bSCy Schubert 
201*7f2fe78bSCy Schubert static void
k5ev_ctx_del(verto_mod_ctx * ctx,const verto_ev * ev,verto_mod_ev * evpriv)202*7f2fe78bSCy Schubert k5ev_ctx_del(verto_mod_ctx *ctx, const verto_ev *ev, verto_mod_ev *evpriv)
203*7f2fe78bSCy Schubert {
204*7f2fe78bSCy Schubert     switch (verto_get_type(ev)) {
205*7f2fe78bSCy Schubert         case VERTO_EV_TYPE_IO:
206*7f2fe78bSCy Schubert             ev_io_stop(ctx, (ev_io*) evpriv);
207*7f2fe78bSCy Schubert             break;
208*7f2fe78bSCy Schubert         case VERTO_EV_TYPE_TIMEOUT:
209*7f2fe78bSCy Schubert             ev_timer_stop(ctx, (ev_timer*) evpriv);
210*7f2fe78bSCy Schubert             break;
211*7f2fe78bSCy Schubert         case VERTO_EV_TYPE_IDLE:
212*7f2fe78bSCy Schubert             ev_idle_stop(ctx, (ev_idle*) evpriv);
213*7f2fe78bSCy Schubert             break;
214*7f2fe78bSCy Schubert         case VERTO_EV_TYPE_SIGNAL:
215*7f2fe78bSCy Schubert             ev_signal_stop(ctx, (ev_signal*) evpriv);
216*7f2fe78bSCy Schubert             break;
217*7f2fe78bSCy Schubert         case VERTO_EV_TYPE_CHILD:
218*7f2fe78bSCy Schubert             ev_child_stop(ctx, (ev_child*) evpriv);
219*7f2fe78bSCy Schubert             break;
220*7f2fe78bSCy Schubert         default:
221*7f2fe78bSCy Schubert             break;
222*7f2fe78bSCy Schubert     }
223*7f2fe78bSCy Schubert 
224*7f2fe78bSCy Schubert     free(evpriv);
225*7f2fe78bSCy Schubert }
226*7f2fe78bSCy Schubert 
227*7f2fe78bSCy Schubert verto_ctx *verto_new_k5ev(void);
228*7f2fe78bSCy Schubert verto_ctx *verto_default_k5ev(void);
229*7f2fe78bSCy Schubert 
230*7f2fe78bSCy Schubert VERTO_MODULE(k5ev, NULL,
231*7f2fe78bSCy Schubert              VERTO_EV_TYPE_IO |
232*7f2fe78bSCy Schubert              VERTO_EV_TYPE_TIMEOUT |
233*7f2fe78bSCy Schubert              VERTO_EV_TYPE_IDLE |
234*7f2fe78bSCy Schubert              VERTO_EV_TYPE_SIGNAL |
235*7f2fe78bSCy Schubert              VERTO_EV_TYPE_CHILD);
236