예제 #1
0
파일: verto-libev.c 프로젝트: tlyu/libverto
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 */
    }
}
예제 #2
0
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;
}
예제 #3
0
파일: verto-glib.c 프로젝트: tlyu/libverto
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;
}