Path: blob/main/crypto/krb5/src/util/verto/verto-libev.c
34907 views
/*1* Copyright 2011 Red Hat, Inc.2*3* Permission is hereby granted, free of charge, to any person4* obtaining a copy of this software and associated documentation files5* (the "Software"), to deal in the Software without restriction,6* including without limitation the rights to use, copy, modify, merge,7* publish, distribute, sublicense, and/or sell copies of the Software,8* and to permit persons to whom the Software is furnished to do so,9* subject to the following conditions:10*11* The above copyright notice and this permission notice shall be12* included in all copies or substantial portions of the Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND17* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS18* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN19* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN20* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*/2324#include <stdlib.h>25#include <string.h>26#include <errno.h>2728#include <verto-libev.h>29#define VERTO_MODULE_TYPES30typedef struct ev_loop verto_mod_ctx;31typedef ev_watcher verto_mod_ev;32#include <verto-module.h>3334static verto_mod_ctx *35libev_ctx_new(void)36{37return ev_loop_new(EVFLAG_AUTO);38}3940static verto_mod_ctx *41libev_ctx_default(void)42{43return ev_default_loop(EVFLAG_AUTO);44}4546static void47libev_ctx_free(verto_mod_ctx *ctx)48{49if (ctx != EV_DEFAULT)50ev_loop_destroy(ctx);51}5253static void54libev_ctx_run(verto_mod_ctx *ctx)55{56ev_run(ctx, 0);57}5859static void60libev_ctx_run_once(verto_mod_ctx *ctx)61{62ev_run(ctx, EVRUN_ONCE);63}6465static void66libev_ctx_break(verto_mod_ctx *ctx)67{68ev_break(ctx, EVBREAK_ONE);69}7071static void72libev_ctx_reinitialize(verto_mod_ctx *ctx)73{74ev_loop_fork(ctx);75}7677static void78libev_callback(EV_P_ ev_watcher *w, int revents)79{80verto_ev_flag state = VERTO_EV_FLAG_NONE;8182#if EV_MULTIPLICITY83/* Match the check in ev.h, which doesn't mark this unused */84(void) EV_A;85#endif8687if (verto_get_type(w->data)== VERTO_EV_TYPE_CHILD)88verto_set_proc_status(w->data, ((ev_child*) w)->rstatus);8990if (revents & EV_READ)91state |= VERTO_EV_FLAG_IO_READ;92if (revents & EV_WRITE)93state |= VERTO_EV_FLAG_IO_WRITE;94if (revents & EV_ERROR)95state |= VERTO_EV_FLAG_IO_ERROR;9697verto_set_fd_state(w->data, state);98verto_fire(w->data);99}100101static void102libev_ctx_set_flags(verto_mod_ctx *ctx, const verto_ev *ev,103verto_mod_ev *evpriv)104{105if (verto_get_type(ev) == VERTO_EV_TYPE_IO) {106int events = EV_NONE;107108if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_READ)109events |= EV_READ;110if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_WRITE)111events |= EV_WRITE;112113ev_io_stop(ctx, (ev_io*) evpriv);114ev_io_set(((ev_io*) evpriv), verto_get_fd(ev), events);115ev_io_start(ctx, (ev_io*) evpriv);116}117}118119#define setuptype(type, ...) \120w.type = malloc(sizeof(ev_ ## type)); \121if (w.type) { \122ev_ ## type ## _init(w.type, (EV_CB(type, (*))) __VA_ARGS__); \123ev_ ## type ## _start(ctx, w.type); \124} \125break126127static verto_mod_ev *128libev_ctx_add(verto_mod_ctx *ctx, const verto_ev *ev, verto_ev_flag *flags)129{130union {131ev_watcher *watcher;132ev_io *io;133ev_timer *timer;134ev_idle *idle;135ev_signal *signal;136ev_child *child;137} w;138ev_tstamp interval;139140w.watcher = NULL;141*flags |= VERTO_EV_FLAG_PERSIST;142switch (verto_get_type(ev)) {143case VERTO_EV_TYPE_IO:144setuptype(io, libev_callback, verto_get_fd(ev), EV_NONE);145case VERTO_EV_TYPE_TIMEOUT:146interval = ((ev_tstamp) verto_get_interval(ev)) / 1000.0;147setuptype(timer, libev_callback, interval, interval);148case VERTO_EV_TYPE_IDLE:149setuptype(idle, libev_callback);150case VERTO_EV_TYPE_SIGNAL:151setuptype(signal, libev_callback, verto_get_signal(ev));152case VERTO_EV_TYPE_CHILD:153*flags &= ~VERTO_EV_FLAG_PERSIST; /* Child events don't persist */154setuptype(child, libev_callback, verto_get_proc(ev), 0);155default:156break; /* Not supported */157}158159if (w.watcher) {160w.watcher->data = (void*) ev;161libev_ctx_set_flags(ctx, ev, w.watcher);162}163return w.watcher;164}165166static void167libev_ctx_del(verto_mod_ctx *ctx, const verto_ev *ev, verto_mod_ev *evpriv)168{169switch (verto_get_type(ev)) {170case VERTO_EV_TYPE_IO:171ev_io_stop(ctx, (ev_io*) evpriv);172break;173case VERTO_EV_TYPE_TIMEOUT:174ev_timer_stop(ctx, (ev_timer*) evpriv);175break;176case VERTO_EV_TYPE_IDLE:177ev_idle_stop(ctx, (ev_idle*) evpriv);178break;179case VERTO_EV_TYPE_SIGNAL:180ev_signal_stop(ctx, (ev_signal*) evpriv);181break;182case VERTO_EV_TYPE_CHILD:183ev_child_stop(ctx, (ev_child*) evpriv);184break;185default:186break;187}188189free(evpriv);190}191192VERTO_MODULE(libev, ev_loop_new,193VERTO_EV_TYPE_IO |194VERTO_EV_TYPE_TIMEOUT |195VERTO_EV_TYPE_IDLE |196VERTO_EV_TYPE_SIGNAL |197VERTO_EV_TYPE_CHILD);198199verto_ctx *200verto_convert_libev(struct ev_loop* loop)201{202return verto_convert(libev, 0, loop);203}204205206