Exemple #1
0
/**
 * 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;
}