static void * libev_ctx_add(void *ctx, const verto_ev *ev, verto_ev_flag *flags) { ev_io *iow = NULL; ev_timer *timerw = NULL; ev_idle *idlew = NULL; ev_signal *signalw = NULL; ev_child *childw = NULL; ev_tstamp interval; int events = EV_NONE; *flags |= VERTO_EV_FLAG_PERSIST; switch (verto_get_type(ev)) { case VERTO_EV_TYPE_IO: if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_READ) events |= EV_READ; if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_WRITE) events |= EV_WRITE; setuptype(io, ev, libev_callback, verto_get_fd(ev), events); case VERTO_EV_TYPE_TIMEOUT: interval = ((ev_tstamp) verto_get_interval(ev)) / 1000.0; setuptype(timer, ev, libev_callback, interval, interval); case VERTO_EV_TYPE_IDLE: setuptype(idle, ev, libev_callback); case VERTO_EV_TYPE_SIGNAL: setuptype(signal, ev, libev_callback, verto_get_signal(ev)); case VERTO_EV_TYPE_CHILD: *flags &= ~VERTO_EV_FLAG_PERSIST; /* Child events don't persist */ setuptype(child, ev, libev_callback, verto_get_proc(ev), 0); default: return NULL; /* Not supported */ } }
static void * libevent_ctx_add(void *ctx, const verto_ev *ev, verto_ev_flag *flags) { struct event *priv = NULL; struct timeval *timeout = NULL; struct timeval tv; int libeventflags = 0; if (*flags & VERTO_EV_FLAG_PERSIST) libeventflags |= EV_PERSIST; switch (verto_get_type(ev)) { case VERTO_EV_TYPE_IO: if (*flags & VERTO_EV_FLAG_IO_READ) libeventflags |= EV_READ; if (*flags & VERTO_EV_FLAG_IO_WRITE) libeventflags |= EV_WRITE; priv = event_new(ctx, verto_get_fd(ev), libeventflags, libevent_callback, (void *) ev); break; case VERTO_EV_TYPE_TIMEOUT: timeout = &tv; tv.tv_sec = verto_get_interval(ev) / 1000; tv.tv_usec = verto_get_interval(ev) % 1000 * 1000; priv = event_new(ctx, -1, EV_TIMEOUT | libeventflags, libevent_callback, (void *) ev); break; case VERTO_EV_TYPE_SIGNAL: priv = event_new(ctx, verto_get_signal(ev), EV_SIGNAL | libeventflags, libevent_callback, (void *) ev); break; case VERTO_EV_TYPE_IDLE: case VERTO_EV_TYPE_CHILD: default: return NULL; /* Not supported */ } if (!priv) return NULL; if (*flags & VERTO_EV_FLAG_PRIORITY_HIGH) event_priority_set(priv, 0); else if (*flags & VERTO_EV_FLAG_PRIORITY_MEDIUM) event_priority_set(priv, 1); else if (*flags & VERTO_EV_FLAG_PRIORITY_LOW) event_priority_set(priv, 2); event_add(priv, timeout); return priv; }
static verto_mod_ev * glib_ctx_add(verto_mod_ctx *ctx, const verto_ev *ev, verto_ev_flag *flags) { verto_mod_ev *evpriv = NULL; verto_ev_type type = verto_get_type(ev); *flags |= verto_get_flags(ev) & VERTO_EV_FLAG_PERSIST; *flags |= verto_get_flags(ev) & VERTO_EV_FLAG_IO_CLOSE_FD; switch (type) { case VERTO_EV_TYPE_IO: evpriv = g_source_new(&funcs, sizeof(GIOSource)); if (evpriv) { ((GIOSource*) evpriv)->fd.fd = verto_get_fd(ev); ((GIOSource*) evpriv)->autoclose = *flags & VERTO_EV_FLAG_IO_CLOSE_FD; g_source_add_poll(evpriv, &((GIOSource*) evpriv)->fd); } break; case VERTO_EV_TYPE_TIMEOUT: evpriv = g_timeout_source_new(verto_get_interval(ev)); break; case VERTO_EV_TYPE_IDLE: evpriv = g_idle_source_new(); break; case VERTO_EV_TYPE_CHILD: evpriv = g_child_watch_source_new(verto_get_proc(ev)); break; case VERTO_EV_TYPE_SIGNAL: /* While glib has signal support in >=2.29, it does not support many common signals (like USR*). Therefore, signal support is disabled until they support them (should be soonish) */ #if GLIB_MAJOR_VERSION >= 999 #if GLIB_MINOR_VERSION >= 29 #ifdef G_OS_UNIX /* Not supported on Windows */ evpriv = g_unix_signal_source_new(verto_get_signal(ev)); break; #endif #endif /* GLIB_MINOR_VERSION >= 29 */ #endif /* GLIB_MAJOR_VERSION >= 2 */ default: return NULL; /* Not supported */ } if (!evpriv) goto error; if (type == VERTO_EV_TYPE_IO) g_source_set_callback(evpriv, (GSourceFunc) glib_callback_io, (void *) ev, NULL); else if (type == VERTO_EV_TYPE_CHILD) g_source_set_callback(evpriv, (GSourceFunc) glib_callback_child, (void *) ev, NULL); else g_source_set_callback(evpriv, glib_callback, (void *) ev, NULL); glib_ctx_set_flags(ctx, ev, evpriv); g_source_set_can_recurse(evpriv, FALSE); if (g_source_attach(evpriv, ctx->context) == 0) goto error; return evpriv; error: if (evpriv) { g_source_destroy(evpriv); g_source_unref(evpriv); } return NULL; }
static void * glib_ctx_add(void *ctx, const verto_ev *ev, verto_ev_flag *flags) { glib_ev *gev = NULL; GIOCondition cond = 0; verto_ev_type type = verto_get_type(ev); gev = g_new0(glib_ev, 1); if (!gev) return NULL; switch (type) { case VERTO_EV_TYPE_IO: #ifdef WIN32 gev->chan = g_io_channel_win32_new_socket(verto_get_fd(ev)); #else gev->chan = g_io_channel_unix_new(verto_get_fd(ev)); #endif if (!gev->chan) goto error; g_io_channel_set_close_on_unref(gev->chan, FALSE); if (*flags & VERTO_EV_FLAG_IO_READ) cond |= G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP | G_IO_NVAL; if (*flags & VERTO_EV_FLAG_IO_WRITE) cond |= G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL; gev->src = g_io_create_watch(gev->chan, cond); break; case VERTO_EV_TYPE_TIMEOUT: gev->src = g_timeout_source_new(verto_get_interval(ev)); break; case VERTO_EV_TYPE_IDLE: gev->src = g_idle_source_new(); break; case VERTO_EV_TYPE_CHILD: gev->src = g_child_watch_source_new(verto_get_proc(ev)); *flags &= ~VERTO_EV_FLAG_PERSIST; /* Child events don't persist */ break; case VERTO_EV_TYPE_SIGNAL: #if GLIB_MAJOR_VERSION >= 2 #if GLIB_MINOR_VERSION >= 29 #ifdef G_OS_UNIX /* Not supported on Windows */ gev->src = g_unix_signal_source_new(verto_get_signal(ev)); break; #endif #endif /* GLIB_MINOR_VERSION >= 29 */ #endif /* GLIB_MAJOR_VERSION >= 2 */ default: return NULL; /* Not supported */ } if (!gev->src) goto error; if (type == VERTO_EV_TYPE_IO) g_source_set_callback(gev->src, (GSourceFunc) glib_callback_io, (void *) ev, NULL); else if (type == VERTO_EV_TYPE_CHILD) g_source_set_callback(gev->src, (GSourceFunc) glib_callback_child, (void *) ev, NULL); else g_source_set_callback(gev->src, glib_callback, (void *) ev, NULL); if (*flags & VERTO_EV_FLAG_PRIORITY_HIGH) g_source_set_priority(gev->src, G_PRIORITY_HIGH); else if (*flags & VERTO_EV_FLAG_PRIORITY_MEDIUM) g_source_set_priority(gev->src, G_PRIORITY_DEFAULT_IDLE); else if (*flags & VERTO_EV_FLAG_PRIORITY_LOW) g_source_set_priority(gev->src, G_PRIORITY_LOW); g_source_set_can_recurse(gev->src, FALSE); if (g_source_attach(gev->src, ((glib_ev_ctx*) ctx)->context) == 0) goto error; return gev; error: if (gev) { if (gev->chan) g_io_channel_unref(gev->chan); if (gev->src) { g_source_destroy(gev->src); g_source_unref(gev->src); } g_free(gev); } return NULL; }