/** * Put worker to sleep unless worker has measured up to all appointed jobs. * */ void worker_sleep_unless(worker_type* worker, time_t timeout) { ods_log_assert(worker); lock_basic_lock(&worker->worker_lock); /* [LOCK] worker */ if (!worker->need_to_exit && !worker_fulfilled(worker)) { worker->sleeping = 1; lock_basic_sleep(&worker->worker_alarm, &worker->worker_lock, timeout); } /* [UNLOCK] worker */ lock_basic_unlock(&worker->worker_lock); return; }
/** * Put worker to sleep unless worker has measured up to all appointed jobs. * */ void worker_sleep_unless(worker_type* worker, time_t timeout) { ods_log_assert(worker); lock_basic_lock(&worker->worker_lock); while (!worker->need_to_exit && !worker_fulfilled(worker)) { worker->sleeping = 1; lock_basic_sleep(&worker->worker_alarm, &worker->worker_lock, timeout); ods_log_debug("[%s[%i]] somebody poked me, check completed jobs %u " "appointed, %u completed, %u failed", worker2str(worker->type), worker->thread_num, worker->jobs_appointed, worker->jobs_completed, worker->jobs_failed); } lock_basic_unlock(&worker->worker_lock); return; }
/** * Drudge. * */ static void worker_drudge(worker_type* worker) { engine_type* engine = NULL; zone_type* zone = NULL; task_type* task = NULL; rrset_type* rrset = NULL; ods_status status = ODS_STATUS_OK; worker_type* superior = NULL; hsm_ctx_t* ctx = NULL; ods_log_assert(worker); ods_log_assert(worker->engine); ods_log_assert(worker->type == WORKER_DRUDGER); engine = (engine_type*) worker->engine; while (worker->need_to_exit == 0) { ods_log_deeebug("[%s[%i]] report for duty", worker2str(worker->type), worker->thread_num); /* initialize */ superior = NULL; zone = NULL; task = NULL; /* get item */ lock_basic_lock(&engine->signq->q_lock); rrset = (rrset_type*) fifoq_pop(engine->signq, &superior); if (!rrset) { ods_log_deeebug("[%s[%i]] nothing to do, wait", worker2str(worker->type), worker->thread_num); /** * Apparently the queue is empty. Wait until new work is queued. * The drudger will release the signq lock while sleeping and * will automatically grab the lock when the threshold is reached. * Threshold is at 1 and MAX (after a number of tries). */ lock_basic_sleep(&engine->signq->q_threshold, &engine->signq->q_lock, 0); rrset = (rrset_type*) fifoq_pop(engine->signq, &superior); } lock_basic_unlock(&engine->signq->q_lock); /* do some work */ if (rrset) { ods_log_assert(superior); if (!ctx) { ods_log_debug("[%s[%i]] create hsm context", worker2str(worker->type), worker->thread_num); ctx = hsm_create_context(); } if (!ctx) { ods_log_crit("[%s[%i]] error creating libhsm context", worker2str(worker->type), worker->thread_num); engine->need_to_reload = 1; lock_basic_lock(&superior->worker_lock); superior->jobs_failed++; lock_basic_unlock(&superior->worker_lock); } else { ods_log_assert(ctx); lock_basic_lock(&superior->worker_lock); task = superior->task; ods_log_assert(task); zone = task->zone; lock_basic_unlock(&superior->worker_lock); ods_log_assert(zone); ods_log_assert(zone->apex); ods_log_assert(zone->signconf); worker->clock_in = time(NULL); status = rrset_sign(ctx, rrset, superior->clock_in); lock_basic_lock(&superior->worker_lock); if (status == ODS_STATUS_OK) { superior->jobs_completed++; } else { superior->jobs_failed++; } lock_basic_unlock(&superior->worker_lock); } if (worker_fulfilled(superior) && superior->sleeping) { ods_log_deeebug("[%s[%i]] wake up superior[%u], work is " "done", worker2str(worker->type), worker->thread_num, superior->thread_num); worker_wakeup(superior); } superior = NULL; rrset = NULL; } /* done work */ } /* wake up superior */ if (superior && superior->sleeping) { ods_log_deeebug("[%s[%i]] wake up superior[%u], i am exiting", worker2str(worker->type), worker->thread_num, superior->thread_num); worker_wakeup(superior); } /* cleanup open HSM sessions */ if (ctx) { hsm_destroy_context(ctx); } return; }