Пример #1
0
/* The signal handler, called on every SIGXCPU */
static void signal_handler(int sig) {
    int saved_errno;

    saved_errno = errno;
    pa_assert(sig == SIGXCPU);

    if (phase == PHASE_IDLE) {
        pa_usec_t now, elapsed;

#ifdef PRINT_CPU_LOAD
        char t[256];
#endif

        now = pa_rtclock_now();
        elapsed = now - last_time;

#ifdef PRINT_CPU_LOAD
        pa_snprintf(t, sizeof(t), "Using %0.1f%% CPU\n", ((double) CPUTIME_INTERVAL_SOFT * (double) PA_USEC_PER_SEC) / (double) elapsed * 100.0);
        write_err(t);
#endif

        if (((double) CPUTIME_INTERVAL_SOFT * (double) PA_USEC_PER_SEC) >= ((double) elapsed * (double) CPUTIME_PERCENT / 100.0)) {
            static const char c = 'X';

            write_err("Soft CPU time limit exhausted, terminating.\n");

            /* Try a soft cleanup */
            (void) write(the_pipe[1], &c, sizeof(c));
            phase = PHASE_SOFT;
            reset_cpu_time(CPUTIME_INTERVAL_HARD);

        } else {

            /* Everything's fine */
            reset_cpu_time(CPUTIME_INTERVAL_SOFT);
            last_time = now;
        }

    } else if (phase == PHASE_SOFT) {
        write_err("Hard CPU time limit exhausted, terminating forcibly.\n");
        abort(); /* Forced exit */
    }

    errno = saved_errno;
}
Пример #2
0
/* Initializes CPU load limiter */
int pa_cpu_limit_init(pa_mainloop_api *m) {
    struct sigaction sa;

    pa_assert(m);
    pa_assert(!api);
    pa_assert(!io_event);
    pa_assert(the_pipe[0] == -1);
    pa_assert(the_pipe[1] == -1);
    pa_assert(!installed);

    time(&last_time);

    /* Prepare the main loop pipe */
    if (pipe(the_pipe) < 0) {
        pa_log("pipe() failed: %s", pa_cstrerror(errno));
        return -1;
    }

    pa_make_fd_nonblock(the_pipe[0]);
    pa_make_fd_nonblock(the_pipe[1]);
    pa_make_fd_cloexec(the_pipe[0]);
    pa_make_fd_cloexec(the_pipe[1]);

    api = m;
    io_event = api->io_new(m, the_pipe[0], PA_IO_EVENT_INPUT, callback, NULL);

    phase = PHASE_IDLE;

    /* Install signal handler for SIGXCPU */
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = signal_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;

    if (sigaction(SIGXCPU, &sa, &sigaction_prev) < 0) {
        pa_cpu_limit_done();
        return -1;
    }

    installed = 1;

    reset_cpu_time(CPUTIME_INTERVAL_SOFT);

    return 0;
}