Beispiel #1
0
/**
 * Handle signals.
 *
 */
void *
signal_handler(sig_atomic_t sig)
{
    switch (sig) {
        case SIGHUP:
            ods_log_debug("[%s] SIGHUP received", signal_str);
            signal_hup_recvd++;
            if (signal_engine) {
                lock_basic_lock(&signal_engine->signal_lock);
                /* [LOCK] signal */
                lock_basic_alarm(&signal_engine->signal_cond);
                /* [UNLOCK] signal */
                lock_basic_unlock(&signal_engine->signal_lock);
            }
            break;
        case SIGINT:
        case SIGTERM:
            ods_log_debug("[%s] SIGTERM received", signal_str);
            signal_term_recvd++;
            if (signal_engine) {
                lock_basic_lock(&signal_engine->signal_lock);
                /* [LOCK] signal */
                lock_basic_alarm(&signal_engine->signal_cond);
                /* [UNLOCK] signal */
                lock_basic_unlock(&signal_engine->signal_lock);
            }
            break;
        default:
            break;
    }
    return NULL;
}
/**
 * Notify a worker.
 *
 */
void
worker_notify(lock_basic_type* lock, cond_basic_type* condition)
{
    lock_basic_lock(lock);
    lock_basic_alarm(condition);
    lock_basic_unlock(lock);
    return;
}
Beispiel #3
0
/**
 * Notify a worker.
 *
 */
void
worker_notify(lock_basic_type* lock, cond_basic_type* condition)
{
    lock_basic_lock(lock);
    /* [LOCK] lock */
    lock_basic_alarm(condition);
    /* [UNLOCK] lock */
    lock_basic_unlock(lock);
    return;
}
/**
 * Wake up worker.
 *
 */
void
worker_wakeup(worker_type* worker)
{
    ods_log_assert(worker);
    if (worker && worker->sleeping && !worker->waiting) {
        ods_log_debug("[%s[%i]] wake up", worker2str(worker->type),
           worker->thread_num);
        lock_basic_lock(&worker->worker_lock);
        lock_basic_alarm(&worker->worker_alarm);
        worker->sleeping = 0;
        lock_basic_unlock(&worker->worker_lock);
    }
    return;
}
Beispiel #5
0
/**
 * Wake up worker.
 *
 */
void
worker_wakeup(worker_type* worker)
{
    ods_log_assert(worker);
    if (worker && worker->sleeping && !worker->waiting) {
        ods_log_debug("[worker[%i]] wake up", worker->thread_num);
        lock_basic_lock(&worker->worker_lock);
        /* [LOCK] worker */
        lock_basic_alarm(&worker->worker_alarm);
        worker->sleeping = 0;
        /* [UNLOCK] worker */
        lock_basic_unlock(&worker->worker_lock);
    }
    return;
}
/**
 * Work.
 *
 */
static void
worker_work(worker_type* worker)
{
    time_t now = 0;
    time_t timeout = 1;
    engine_type* engine = NULL;
    zone_type* zone = NULL;
    ods_status status = ODS_STATUS_OK;

    ods_log_assert(worker);
    ods_log_assert(worker->type == WORKER_WORKER);

    engine = (engine_type*) worker->engine;
    while (worker->need_to_exit == 0) {
        ods_log_debug("[%s[%i]] report for duty", worker2str(worker->type),
            worker->thread_num);
        now = time_now();
        lock_basic_lock(&engine->taskq->schedule_lock);
        worker->task = schedule_pop_task(engine->taskq);
        if (worker->task) {
            worker->working_with = worker->task->what;
            lock_basic_unlock(&engine->taskq->schedule_lock);
            zone = (zone_type*) worker->task->zone;

            lock_basic_lock(&zone->zone_lock);
            ods_log_debug("[%s[%i]] start working on zone %s",
                worker2str(worker->type), worker->thread_num, zone->name);
            worker->clock_in = time(NULL);
            worker_perform_task(worker);
            zone->task = worker->task;
            ods_log_debug("[%s[%i]] finished working on zone %s",
                worker2str(worker->type), worker->thread_num, zone->name);

            lock_basic_lock(&engine->taskq->schedule_lock);
            worker->task = NULL;
            worker->working_with = TASK_NONE;
            status = schedule_task(engine->taskq, zone->task, 1);
            if (status != ODS_STATUS_OK) {
                ods_log_error("[%s[%i]] unable to schedule task for zone %s: "
                "%s", worker2str(worker->type), worker->thread_num,
                zone->name, ods_status2str(status));
            }
            lock_basic_unlock(&engine->taskq->schedule_lock);
            lock_basic_unlock(&zone->zone_lock);
            timeout = 1;
            /** Do we need to tell the engine that we require a reload? */
            lock_basic_lock(&engine->signal_lock);
            if (engine->need_to_reload) {
                lock_basic_alarm(&engine->signal_cond);
            }
            lock_basic_unlock(&engine->signal_lock);

        } else {
            ods_log_debug("[%s[%i]] nothing to do", worker2str(worker->type),
                worker->thread_num);
            worker->task = schedule_get_first_task(engine->taskq);
            lock_basic_unlock(&engine->taskq->schedule_lock);
            if (worker->task && !engine->taskq->loading) {
                timeout = (worker->task->when - now);
            } else {
                timeout *= 2;
            }
            if (timeout > ODS_SE_MAX_BACKOFF) {
                timeout = ODS_SE_MAX_BACKOFF;
            }
            worker->task = NULL;
            worker_sleep(worker, timeout);
        }
    }
    return;
}