Beispiel #1
0
/**
 * Work.
 *
 */
void
worker_start(worker_type* worker)
{
    time_t now, timeout = 1;
    task_type *task_that_was_worked_on;

    ods_log_assert(worker);

    while (worker->need_to_exit == 0) {
        ods_log_debug("[worker[%i]]: report for duty", worker->thread_num);

        lock_basic_lock(&worker->engine->taskq->schedule_lock);
        /* [LOCK] schedule */

        worker->task = schedule_pop_task(worker->engine->taskq);
        if (worker->task) {

            /* [UNLOCK] schedule */
            lock_basic_unlock(&worker->engine->taskq->schedule_lock);

            ods_log_debug("[worker[%i]] start working", worker->thread_num);

            worker->clock_in = time(NULL);
            worker_perform_task(worker);

            task_that_was_worked_on = worker->task;
            worker->task = NULL;
            
            ods_log_debug("[worker[%i]] finished working", worker->thread_num);
            
            if (task_that_was_worked_on)
                (void) lock_and_schedule_task(worker->engine->taskq,
                                                 task_that_was_worked_on, 1);
            
            timeout = 1;
        } else {
            ods_log_debug("[worker[%i]] nothing to do", worker->thread_num);

            worker->task = schedule_get_first_task(worker->engine->taskq);

            /* [UNLOCK] schedule */
            lock_basic_unlock(&worker->engine->taskq->schedule_lock);

            now = time_now();
            if (worker->task && !worker->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;
}
/**
 * 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;
}