/** * Work. * */ void worker_start(worker_type* worker) { ods_log_assert(worker); while (worker->need_to_exit == 0) { ods_log_debug("[worker[%i]]: report for duty", worker->thread_num); /* When no task available this call blocks and waits for event. * Then it will return NULL; */ worker->task = schedule_pop_task(worker->engine->taskq); if (worker->task) { ods_log_debug("[worker[%i]] start working", worker->thread_num); worker_perform_task(worker); ods_log_debug("[worker[%i]] finished working", worker->thread_num); if (worker->task) { if (schedule_task(worker->engine->taskq, worker->task) != ODS_STATUS_OK) { ods_log_error("[worker[%i]] unable to schedule task", worker->thread_num); } worker->task = NULL; } } } }
/** * 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; }