Exemplo n.º 1
0
inline void courtesy_yield(void) {
    if (0 == epoll_wait(ribs_epoll_fd, &last_epollev, 1, 0))
        return;
    queue_current_ctx();
    ribs_swapcurcontext(epoll_worker_get_last_context());
}
Exemplo n.º 2
0
static void _handle_sig_child(void) {
    struct signalfd_siginfo sfd_info;
    for (;;yield()) {
        for (;;) {
            ssize_t res = read(sigfd, &sfd_info, sizeof(struct signalfd_siginfo));
            if (0 > res) {
                if (errno != EAGAIN)
                    LOGGER_PERROR("read from signal fd");
                break;
            }
            if (sizeof(struct signalfd_siginfo) != res) {
                LOGGER_ERROR("failed to read from signal fd, incorrect size");
                continue;
            }
            memset(&last_sig_info, 0, sizeof(last_sig_info));
            epoll_worker_ignore_events(sigfd);
            for (;;) {
                last_sig_info.si_pid = 0;
                if (0 > waitid(P_ALL, 0, &last_sig_info, WEXITED | WNOHANG) && ECHILD != errno) {
                    LOGGER_PERROR("waitid");
                    break;
                }
                pid_t pid = last_sig_info.si_pid;
                if (0 == pid)
                    break; /* no more events */
                if (logger_pid == pid) {
                    char fname[256];
                    snprintf(fname, sizeof(fname), "%s-%d.crash.log", program_invocation_short_name, getpid());
                    fname[sizeof(fname)-1] = 0;
                    int fd = creat(fname, 0644);
                    if (0 <= fd) {
                        dup2(fd, STDOUT_FILENO);
                        dup2(fd, STDERR_FILENO);
                        close(fd);
                        LOGGER_ERROR("logger [%d] terminated unexpectedly: %s, status=%d", pid, _get_exit_reason(&last_sig_info), last_sig_info.si_status);
                    }
                    epoll_worker_exit();
                }
                int i;
                for (i = 0; i < num_instances-1; ++i) {
                    /* check if it is our pid */
                    if (children_pids[i] == pid) {
                        children_pids[i] = 0; /* mark pid as handled */
                        LOGGER_ERROR("child process [%d] terminated unexpectedly: %s, status=%d", pid, _get_exit_reason(&last_sig_info), last_sig_info.si_status);
                        epoll_worker_exit();
                    }
                }
                uint32_t loc = hashtable_lookup(&ht_pid_to_ctx, &pid, sizeof(pid));
                if (0 == loc) {
                    LOGGER_ERROR("unhandled SIGCHLD detected, exiting...");
                    epoll_worker_exit();
                } else {
                    if (0 > queue_current_ctx()) {
                        LOGGER_ERROR("failed to queue current context, exiting...");
                        return epoll_worker_exit();
                    }
                    struct ribs_context *ctx = *(struct ribs_context **)hashtable_get_val(&ht_pid_to_ctx, loc);
                    hashtable_remove(&ht_pid_to_ctx, &pid, sizeof(pid));
                    ribs_swapcurcontext(ctx);
                }
            }
            epoll_worker_resume_events(sigfd);
        }
    }
}