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