示例#1
0
/**
 * \brief Create a periodic event
 *
 * A periodic event will repeatedly run a closure at a fixed rate until cancelled.
 *
 * \param event Storage for event state
 * \param ws Waitset
 * \param period Period, in microseconds
 * \param closure Closure to run
 */
errval_t periodic_event_create(struct periodic_event *event, struct waitset *ws,
                               delayus_t period, struct event_closure closure)
{
    assert(event != NULL);
    deferred_event_init(&event->de);
    event->cl = closure;
    event->waitset = ws;
    event->period = period;
    return deferred_event_register(&event->de, ws, period,
                                   MKCLOSURE(periodic_event_handler, event));
}
示例#2
0
文件: main.c 项目: 8l/barrelfish
static void mon_heartbeat(void *arg) {
    assert(arg != NULL);
    errval_t err;
    debug_printf("my_core_id = %d; curr_core_id = %d\n", my_core_id,
            disp_get_current_core_id());
    struct deferred_event *ev = arg;
    deferred_event_init(ev);
    // 1 s == 1000 ms == 1e6 us
    delayus_t one_sec = 15ULL*1000*1000;
    err = deferred_event_register(ev, get_default_waitset(), one_sec, MKCLOSURE(mon_heartbeat, arg));
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "heartbeat");
    }
    assert(err_is_ok(err));
}
示例#3
0
文件: epoll.c 项目: huiweics/arrakis
int epoll_wait(int epfd, struct epoll_event *events,
               int maxevents, int timeout)
{
    struct fdtab_entry *mye = fdtab_get(epfd);
    assert(mye->type == FDTAB_TYPE_EPOLL_INSTANCE);
    struct _epoll_fd *efd = mye->handle;
    struct monitor_binding *mb = get_monitor_binding();
    errval_t err;

    /* waitset_init(&efd->ws); */
    assert(maxevents >= 1);

    for(struct _epoll_events_list *i = efd->events; i != NULL; i = i->next) {
        struct fdtab_entry *e = fdtab_get(i->fd);
        struct epoll_event *event = &i->event;

        switch (e->type) {
        case FDTAB_TYPE_LWIP_SOCKET:
        {
            int retval;

            lwip_mutex_lock();
            if(event->events & EPOLLIN) {
                retval = lwip_sock_waitset_register_read(e->fd, &efd->ws);
                assert(retval == 0);
            }
            if(event->events & EPOLLOUT) {
                retval = lwip_sock_waitset_register_write(e->fd, &efd->ws);
                assert(retval == 0);
            }
            lwip_mutex_unlock();
        }
        break;

        case FDTAB_TYPE_UNIX_SOCKET:
        {
            struct _unix_socket *us = e->handle;

            if(event->events & EPOLLIN) {
                if (us->passive) { /* passive side */
                    int j;

                    /* Check for pending connection requests. */
                    for (j = 0; j < us->u.passive.max_backlog; j++)
                    {
                        if (us->u.passive.backlog[j] != NULL) {
                            break;
                        }
                    }

                    /*
                     * If there are not pending connection request
                     * wait on monitor binding.
                     */
                    if (j == us->u.passive.max_backlog) {
                        /* wait on monitor */
                        err = mb->change_waitset(mb, &efd->ws);
                        if (err_is_fail(err)) {
                            USER_PANIC_ERR(err, "change_waitset");
                        }
                    }
                }
            }

            if(event->events & EPOLLOUT) {
                assert(!us->passive);

                if(us->u.active.mode == _UNIX_SOCKET_MODE_CONNECTING) {
                    /* wait on monitor */
                    err = mb->change_waitset(mb, &efd->ws);
                    if (err_is_fail(err)) {
                        USER_PANIC_ERR(err, "change_waitset");
                    }
                }
            }

            assert(event->events & (EPOLLIN | EPOLLOUT));

            // Change waitset
            err = us->u.active.binding->change_waitset
                  (us->u.active.binding, &efd->ws);
            if (err_is_fail(err)) {
                USER_PANIC_ERR(err, "change waitset");
            }

        }
        break;

        default:
        {
            fprintf(stderr, "change waitset on FD type %d NYI.\n",
                    e->type);
            assert(!"NYI");
            errno = EBADF;
            return -1;
        }
        }
    }

    // Timeout handling
    struct timeout_event toe = {
        .fired = false
    };
    struct deferred_event timeout_event;
    if (timeout > 0) {
        deferred_event_init(&timeout_event);
        err = deferred_event_register(&timeout_event, &efd->ws, timeout,
                                      MKCLOSURE(timeout_fired, &toe));
        if (err_is_fail(err)) {
            errno = EINVAL;
            return -1;
        }
    }

    int retevents = 0;
    while(!toe.fired && retevents == 0) {
        if(timeout == 0) {
            // Just poll once, don't block
            err = event_dispatch_non_block(&efd->ws);
            assert(err_is_ok(err) || err_no(err) == LIB_ERR_NO_EVENT);
            toe.fired = true;
        } else {
            err = event_dispatch(&efd->ws);
            if (err_is_fail(err)) {
                USER_PANIC_ERR(err, "Error in event_dispatch.");
            }
        }

        // Return ready file descriptors
        for(struct _epoll_events_list *i = efd->events; i != NULL; i = i->next) {
            struct epoll_event *event = &i->event;
            struct fdtab_entry *e = fdtab_get(i->fd);

            assert(retevents < maxevents);
            events[retevents] = *event;
            events[retevents].events = 0;

            // Check errors (hangup)
            {
                switch (e->type) {
                case FDTAB_TYPE_LWIP_SOCKET:
                {
                    lwip_mutex_lock();
                    if (!lwip_sock_is_open(e->fd)) {
                        events[retevents].events |= EPOLLHUP;
                    }
                    lwip_mutex_unlock();
                }
                break;

                default:
                    // No-Op
                    break;
                }
            }

            // Check readable FDs
            if(event->events & EPOLLIN) {
                switch (e->type) {
                case FDTAB_TYPE_LWIP_SOCKET:
                {
                    lwip_mutex_lock();
                    if (lwip_sock_ready_read(e->fd)) {
                        events[retevents].events |= EPOLLIN;
                    }
                    lwip_mutex_unlock();
                }
                break;

                case FDTAB_TYPE_UNIX_SOCKET:
                {
                    struct _unix_socket *us = e->handle;

                    if (us->passive) { /* passive side */
                        /* Check for pending connection requests. */
                        for (int j = 0; j < us->u.passive.max_backlog; j++)
                        {
                            if (us->u.passive.backlog[j] != NULL) {
                                events[retevents].events |= EPOLLIN;
                                break;
                            }
                        }
                    } else { /* active side */
                        /* Check for incoming data. */
                        if (us->recv_buf_valid > 0) {
                            events[retevents].events |= EPOLLIN;
                        }
                    }
                }
                break;

                default:
                {
                    fprintf(stderr, "epoll_wait() on FD type %d NYI.\n",
                            e->type);
                    assert(!"NYI");
                    errno = EBADF;
                    return -1;
                }
                }
            }

            // Check writeable FDs
            if(event->events & EPOLLOUT) {
                switch (e->type) {
                case FDTAB_TYPE_LWIP_SOCKET:
                {
                    lwip_mutex_lock();
                    if (lwip_sock_ready_write(e->fd)) {
                        events[retevents].events |= EPOLLOUT;
                    }
                    lwip_mutex_unlock();
                }
                break;

                case FDTAB_TYPE_UNIX_SOCKET:
                {
                    struct _unix_socket *us = e->handle;
                    assert(!us->passive);

                    switch (us->u.active.mode) {
                    case _UNIX_SOCKET_MODE_CONNECTING:
                        break;

                    case _UNIX_SOCKET_MODE_CONNECTED:
                        if (us->send_buf == NULL) {
                            events[retevents].events |= EPOLLOUT;
                        }
                        break;
                    }
                }
                break;

                default:
                {
                    fprintf(stderr, "epoll_wait() on FD type %d NYI.\n",
                            e->type);
                    assert(!"NYI");
                    errno = EBADF;
                    return -1;
                }
                }
            }

            // If any events were returned, go to next entry in array
            if(events[retevents].events != 0) {
                retevents++;
            }
        }
    }

    // Remove timeout from waitset if it was set and not fired
    if(timeout > 0 && !toe.fired) {
        deferred_event_cancel(&timeout_event);
    }

    // Restore old waitsets
    for(struct _epoll_events_list *i = efd->events; i != NULL; i = i->next) {
        struct fdtab_entry *e = fdtab_get(i->fd);
        struct epoll_event *event = &i->event;

        switch (e->type) {
        case FDTAB_TYPE_LWIP_SOCKET:
        {
            lwip_mutex_lock();
            if(event->events & EPOLLIN) {
                err = lwip_sock_waitset_deregister_read(e->fd);
                if (err_is_fail(err) &&
                        err_no(err) != LIB_ERR_CHAN_NOT_REGISTERED) {
                    USER_PANIC_ERR(err, "error deregister read channel for "
                                   "lwip socket");
                }
            }
            if(event->events & EPOLLOUT) {
                err = lwip_sock_waitset_deregister_write(e->fd);
                if (err_is_fail(err) &&
                        err_no(err) != LIB_ERR_CHAN_NOT_REGISTERED) {
                    USER_PANIC_ERR(err, "error deregister write channel for "
                                   "lwip socket");
                }
            }
            lwip_mutex_unlock();
        }
        break;

        case FDTAB_TYPE_UNIX_SOCKET:
        {
            // NYI
        }
        break;

        default:
        {
            fprintf(stderr, "change waitset on FD type %d NYI.\n",
                    e->type);
            assert(!"NYI");
            errno = EBADF;
            return -1;
        }
        }
    }

    return retevents;
}

int epoll_pwait(int epfd, struct epoll_event *events,
                int maxevents, int timeout,
                const sigset_t *sigmask)
{
    assert(!"NYI");
}