|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Copyright 2011 Red Hat, Inc.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* Permission is hereby granted, free of charge, to any person
|
|
Packit |
fd8b60 |
* obtaining a copy of this software and associated documentation files
|
|
Packit |
fd8b60 |
* (the "Software"), to deal in the Software without restriction,
|
|
Packit |
fd8b60 |
* including without limitation the rights to use, copy, modify, merge,
|
|
Packit |
fd8b60 |
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
Packit |
fd8b60 |
* and to permit persons to whom the Software is furnished to do so,
|
|
Packit |
fd8b60 |
* subject to the following conditions:
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* The above copyright notice and this permission notice shall be
|
|
Packit |
fd8b60 |
* included in all copies or substantial portions of the Software.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
fd8b60 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
fd8b60 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
fd8b60 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit |
fd8b60 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit |
fd8b60 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit |
fd8b60 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit |
fd8b60 |
* SOFTWARE.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#include <stdlib.h>
|
|
Packit |
fd8b60 |
#include <string.h>
|
|
Packit |
fd8b60 |
#include <errno.h>
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#include <verto-libev.h>
|
|
Packit |
fd8b60 |
#define VERTO_MODULE_TYPES
|
|
Packit |
fd8b60 |
typedef struct ev_loop verto_mod_ctx;
|
|
Packit |
fd8b60 |
typedef ev_watcher verto_mod_ev;
|
|
Packit |
fd8b60 |
#include <verto-module.h>
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static verto_mod_ctx *
|
|
Packit |
fd8b60 |
libev_ctx_new(void)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
return ev_loop_new(EVFLAG_AUTO);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static verto_mod_ctx *
|
|
Packit |
fd8b60 |
libev_ctx_default(void)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
return ev_default_loop(EVFLAG_AUTO);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static void
|
|
Packit |
fd8b60 |
libev_ctx_free(verto_mod_ctx *ctx)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if (ctx != EV_DEFAULT)
|
|
Packit |
fd8b60 |
ev_loop_destroy(ctx);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static void
|
|
Packit |
fd8b60 |
libev_ctx_run(verto_mod_ctx *ctx)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
ev_run(ctx, 0);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static void
|
|
Packit |
fd8b60 |
libev_ctx_run_once(verto_mod_ctx *ctx)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
ev_run(ctx, EVRUN_ONCE);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static void
|
|
Packit |
fd8b60 |
libev_ctx_break(verto_mod_ctx *ctx)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
ev_break(ctx, EVBREAK_ONE);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static void
|
|
Packit |
fd8b60 |
libev_ctx_reinitialize(verto_mod_ctx *ctx)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
ev_loop_fork(ctx);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static void
|
|
Packit |
fd8b60 |
libev_callback(EV_P_ ev_watcher *w, int revents)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
verto_ev_flag state = VERTO_EV_FLAG_NONE;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#if EV_MULTIPLICITY
|
|
Packit |
fd8b60 |
/* Match the check in ev.h, which doesn't mark this unused */
|
|
Packit |
fd8b60 |
(void) EV_A;
|
|
Packit |
fd8b60 |
#endif
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (verto_get_type(w->data)== VERTO_EV_TYPE_CHILD)
|
|
Packit |
fd8b60 |
verto_set_proc_status(w->data, ((ev_child*) w)->rstatus);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (revents & EV_READ)
|
|
Packit |
fd8b60 |
state |= VERTO_EV_FLAG_IO_READ;
|
|
Packit |
fd8b60 |
if (revents & EV_WRITE)
|
|
Packit |
fd8b60 |
state |= VERTO_EV_FLAG_IO_WRITE;
|
|
Packit |
fd8b60 |
if (revents & EV_ERROR)
|
|
Packit |
fd8b60 |
state |= VERTO_EV_FLAG_IO_ERROR;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
verto_set_fd_state(w->data, state);
|
|
Packit |
fd8b60 |
verto_fire(w->data);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static void
|
|
Packit |
fd8b60 |
libev_ctx_set_flags(verto_mod_ctx *ctx, const verto_ev *ev,
|
|
Packit |
fd8b60 |
verto_mod_ev *evpriv)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if (verto_get_type(ev) == VERTO_EV_TYPE_IO) {
|
|
Packit |
fd8b60 |
int events = EV_NONE;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_READ)
|
|
Packit |
fd8b60 |
events |= EV_READ;
|
|
Packit |
fd8b60 |
if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_WRITE)
|
|
Packit |
fd8b60 |
events |= EV_WRITE;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ev_io_stop(ctx, (ev_io*) evpriv);
|
|
Packit |
fd8b60 |
ev_io_set(((ev_io*) evpriv), verto_get_fd(ev), events);
|
|
Packit |
fd8b60 |
ev_io_start(ctx, (ev_io*) evpriv);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#define setuptype(type, ...) \
|
|
Packit |
fd8b60 |
w.type = malloc(sizeof(ev_ ## type)); \
|
|
Packit |
fd8b60 |
if (w.type) { \
|
|
Packit |
fd8b60 |
ev_ ## type ## _init(w.type, (EV_CB(type, (*))) __VA_ARGS__); \
|
|
Packit |
fd8b60 |
ev_ ## type ## _start(ctx, w.type); \
|
|
Packit |
fd8b60 |
} \
|
|
Packit |
fd8b60 |
break
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static verto_mod_ev *
|
|
Packit |
fd8b60 |
libev_ctx_add(verto_mod_ctx *ctx, const verto_ev *ev, verto_ev_flag *flags)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
union {
|
|
Packit |
fd8b60 |
ev_watcher *watcher;
|
|
Packit |
fd8b60 |
ev_io *io;
|
|
Packit |
fd8b60 |
ev_timer *timer;
|
|
Packit |
fd8b60 |
ev_idle *idle;
|
|
Packit |
fd8b60 |
ev_signal *signal;
|
|
Packit |
fd8b60 |
ev_child *child;
|
|
Packit |
fd8b60 |
} w;
|
|
Packit |
fd8b60 |
ev_tstamp interval;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
w.watcher = NULL;
|
|
Packit |
fd8b60 |
*flags |= VERTO_EV_FLAG_PERSIST;
|
|
Packit |
fd8b60 |
switch (verto_get_type(ev)) {
|
|
Packit |
fd8b60 |
case VERTO_EV_TYPE_IO:
|
|
Packit |
fd8b60 |
setuptype(io, libev_callback, verto_get_fd(ev), EV_NONE);
|
|
Packit |
fd8b60 |
case VERTO_EV_TYPE_TIMEOUT:
|
|
Packit |
fd8b60 |
interval = ((ev_tstamp) verto_get_interval(ev)) / 1000.0;
|
|
Packit |
fd8b60 |
setuptype(timer, libev_callback, interval, interval);
|
|
Packit |
fd8b60 |
case VERTO_EV_TYPE_IDLE:
|
|
Packit |
fd8b60 |
setuptype(idle, libev_callback);
|
|
Packit |
fd8b60 |
case VERTO_EV_TYPE_SIGNAL:
|
|
Packit |
fd8b60 |
setuptype(signal, libev_callback, verto_get_signal(ev));
|
|
Packit |
fd8b60 |
case VERTO_EV_TYPE_CHILD:
|
|
Packit |
fd8b60 |
*flags &= ~VERTO_EV_FLAG_PERSIST; /* Child events don't persist */
|
|
Packit |
fd8b60 |
setuptype(child, libev_callback, verto_get_proc(ev), 0);
|
|
Packit |
fd8b60 |
default:
|
|
Packit |
fd8b60 |
break; /* Not supported */
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (w.watcher) {
|
|
Packit |
fd8b60 |
w.watcher->data = (void*) ev;
|
|
Packit |
fd8b60 |
libev_ctx_set_flags(ctx, ev, w.watcher);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
return w.watcher;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static void
|
|
Packit |
fd8b60 |
libev_ctx_del(verto_mod_ctx *ctx, const verto_ev *ev, verto_mod_ev *evpriv)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
switch (verto_get_type(ev)) {
|
|
Packit |
fd8b60 |
case VERTO_EV_TYPE_IO:
|
|
Packit |
fd8b60 |
ev_io_stop(ctx, (ev_io*) evpriv);
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
case VERTO_EV_TYPE_TIMEOUT:
|
|
Packit |
fd8b60 |
ev_timer_stop(ctx, (ev_timer*) evpriv);
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
case VERTO_EV_TYPE_IDLE:
|
|
Packit |
fd8b60 |
ev_idle_stop(ctx, (ev_idle*) evpriv);
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
case VERTO_EV_TYPE_SIGNAL:
|
|
Packit |
fd8b60 |
ev_signal_stop(ctx, (ev_signal*) evpriv);
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
case VERTO_EV_TYPE_CHILD:
|
|
Packit |
fd8b60 |
ev_child_stop(ctx, (ev_child*) evpriv);
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
default:
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
free(evpriv);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
VERTO_MODULE(libev, ev_loop_new,
|
|
Packit |
fd8b60 |
VERTO_EV_TYPE_IO |
|
|
Packit |
fd8b60 |
VERTO_EV_TYPE_TIMEOUT |
|
|
Packit |
fd8b60 |
VERTO_EV_TYPE_IDLE |
|
|
Packit |
fd8b60 |
VERTO_EV_TYPE_SIGNAL |
|
|
Packit |
fd8b60 |
VERTO_EV_TYPE_CHILD);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
verto_ctx *
|
|
Packit |
fd8b60 |
verto_convert_libev(struct ev_loop* loop)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
return verto_convert(libev, 0, loop);
|
|
Packit |
fd8b60 |
}
|