Exemple #1
0
static inline int _mk_event_channel_create(struct mk_event_ctx *ctx,
                                           int *r_fd, int *w_fd, void *data)
{
    int ret;
    int fd[2];
    struct mk_event *event;

    ret = pipe(fd);
    if (ret < 0) {
        mk_libc_error("pipe");
        return ret;
    }

    event = data;
    event->fd = fd[0];
    event->type = MK_EVENT_NOTIFICATION;
    event->mask = MK_EVENT_EMPTY;

    ret = _mk_event_add(ctx, fd[0],
                        MK_EVENT_NOTIFICATION, MK_EVENT_READ, event);
    if (ret != 0) {
        close(fd[0]);
        close(fd[1]);
        return ret;
    }

    *r_fd = fd[0];
    *w_fd = fd[1];

    return 0;
}
Exemple #2
0
/* Register a timeout file descriptor */
static inline int _mk_event_timeout_create(mk_event_ctx_t *ctx, int expire)
{
    int ret;
    int timer_fd;
    struct itimerspec its;

    /* expiration interval */
    its.it_interval.tv_sec  = expire;
    its.it_interval.tv_nsec = 0;

    /* initial expiration */
    its.it_value.tv_sec  = time(NULL) + expire;
    its.it_value.tv_nsec = 0;

    timer_fd = timerfd_create(CLOCK_REALTIME, 0);
    if (timer_fd == -1) {
        mk_libc_error("timerfd");
        return -1;
    }

    ret = timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &its, NULL);
    if (ret < 0) {
        mk_libc_error("timerfd_settime");
        return -1;
    }

    /* register the timer into the epoll queue */
    ret = _mk_event_add(ctx, timer_fd, MK_EVENT_READ);
    if (ret != 0) {
        close(timer_fd);
        return ret;
    }

    return timer_fd;
}
Exemple #3
0
/* Register or modify an event */
int mk_event_add(struct mk_event_loop *loop, int fd,
                 int type, uint32_t mask, void *data)
{
    int ret;
    struct mk_event_ctx *ctx;

    mk_bug(!data);

    ctx = loop->data;
    ret = _mk_event_add(ctx, fd, type, mask, data);
    if (ret == -1) {
        return -1;
    }

    return 0;
}
Exemple #4
0
/*
 * This routine creates a timer, since this select(2) backend aims to be used
 * in very old systems to be compatible, we cannot trust timerfd_create(2)
 * will be available (e.g: Cygwin), so our workaround is to create a pipe(2)
 * and a thread, this thread writes a byte upon the expiration time is reached.
 */
static inline int _mk_event_timeout_create(struct mk_event_ctx *ctx,
                                           time_t sec, long nsec, void *data)
{
    int ret;
    int fd[2];
    struct mk_event *event;
    struct fd_timer *timer;

    timer = mk_mem_alloc(sizeof(struct fd_timer));
    if (!timer) {
        return -1;
    }

    ret = pipe(fd);
    if (ret < 0) {
        mk_mem_free(timer);
        mk_libc_error("pipe");
        return ret;
    }

    event = (struct mk_event *) data;
    event->fd = fd[0];
    event->type = MK_EVENT_NOTIFICATION;
    event->mask = MK_EVENT_EMPTY;

    _mk_event_add(ctx, fd[0], MK_EVENT_NOTIFICATION, MK_EVENT_READ, data);
    event->mask = MK_EVENT_READ;

    /* Compose the timer context, this is released inside the worker thread */
    timer->fd   = fd[1];
    timer->sec  = sec;
    timer->nsec = nsec;
    timer->run  = MK_TRUE;

    event->data = timer;

    /* Now the dirty workaround, create a thread */
    ret = mk_utils_worker_spawn(_timeout_worker, timer, &timer->tid);
    if (ret < 0) {
        close(fd[0]);
        close(fd[1]);
        mk_mem_free(timer);
        return -1;
    }

    return fd[0];
}
Exemple #5
0
/* Register a timeout file descriptor */
static inline int _mk_event_timeout_create(struct mk_event_ctx *ctx,
                                           time_t sec, long nsec, void *data)
{
    int ret;
    int timer_fd;
    struct itimerspec its;
    struct mk_event *event;

    mk_bug(!data);
    memset(&its, '\0', sizeof(struct itimerspec));

    /* expiration interval */
    its.it_interval.tv_sec  = sec;
    its.it_interval.tv_nsec = nsec;

    /* initial expiration */
    its.it_value.tv_sec  = time(NULL) + sec;
    its.it_value.tv_nsec = 0;

    timer_fd = timerfd_create(CLOCK_REALTIME, 0);
    if (timer_fd == -1) {
        mk_libc_error("timerfd");
        return -1;
    }

    ret = timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &its, NULL);
    if (ret < 0) {
        mk_libc_error("timerfd_settime");
        return -1;
    }

    event = data;
    event->fd   = timer_fd;
    event->type = MK_EVENT_NOTIFICATION;
    event->mask = MK_EVENT_EMPTY;

    /* register the timer into the epoll queue */
    ret = _mk_event_add(ctx, timer_fd,
                        MK_EVENT_NOTIFICATION, MK_EVENT_READ, data);
    if (ret != 0) {
        close(timer_fd);
        return ret;
    }

    return timer_fd;
}
Exemple #6
0
/* Register or modify an event */
int mk_event_add(mk_event_loop_t *loop, int fd, int mask, void *data)
{
    int ret;
    mk_event_ctx_t *ctx;
    struct mk_event_fd_state *fds;

    ctx = loop->data;
    ret = _mk_event_add(ctx, fd, mask);
    if (ret == -1) {
        return -1;
    }

    fds = mk_event_get_state(fd);
    fds->mask = mask;
    fds->data = data;

    return 0;
}
Exemple #7
0
static inline int _mk_event_channel_create(mk_event_ctx_t *ctx, int *r_fd, int *w_fd)
{
    int fd;
    int ret;

    fd = eventfd(0, EFD_CLOEXEC);
    if (fd == -1) {
        mk_libc_error("eventfd");
        return -1;
    }

    ret = _mk_event_add(ctx, fd, MK_EVENT_READ);
    if (ret != 0) {
        close(fd);
        return ret;
    }

    *w_fd = *r_fd = fd;
    return 0;
}
/*
 * This routine creates a timer, since this select(2) backend aims to be used
 * in very old systems to be compatible, we cannot trust timerfd_create(2)
 * will be available (e.g: Cygwin), so our workaround is to create a pipe(2)
 * and a thread, this thread writes a byte upon the expiration time is reached.
 */
static inline int _mk_event_timeout_create(struct mk_event_ctx *ctx,
                                           int expire, void *data)
{
    int ret;
    int fd[2];
    pid_t tid;
    struct mk_event *event;
    struct fd_timer *timer;

    timer = mk_mem_malloc(sizeof(struct fd_timer));
    if (!timer) {
        return -1;
    }

    ret = pipe(fd);
    if (ret < 0) {
        mk_mem_free(timer);
        mk_libc_error("pipe");
        return ret;
    }

    event = (struct mk_event *) data;
    event->fd = fd[0];
    event->type = MK_EVENT_NOTIFICATION;
    event->mask = MK_EVENT_EMPTY;

    _mk_event_add(ctx, fd[0], MK_EVENT_NOTIFICATION, MK_EVENT_READ, data);
    event->mask = MK_EVENT_READ;

    /* Compose the timer context, this is released inside the worker thread */
    timer->fd = fd[1];
    timer->expiration = expire;

    /* Now the dirty workaround, create a thread */
    mk_utils_worker_spawn(_timeout_worker, timer);
    return fd[0];
}