コード例 #1
0
ファイル: schedule.c プロジェクト: eest/opendnssec
void
schedule_purge(schedule_type* schedule)
{
    ldns_rbnode_t* node;
    
    if (!schedule || !schedule->tasks) return;

    pthread_mutex_lock(&schedule->schedule_lock);
        /* don't attempt to free payload, still referenced by other tree*/
        while ((node = ldns_rbtree_first(schedule->tasks)) !=
            LDNS_RBTREE_NULL)
        {
            node = ldns_rbtree_delete(schedule->tasks, node->data);
            if (node == 0) break;
            free(node);
        }
        /* also clean up name tree */
        while ((node = ldns_rbtree_first(schedule->tasks_by_name)) !=
            LDNS_RBTREE_NULL)
        {
            node = ldns_rbtree_delete(schedule->tasks_by_name, node->data);
            if (node == 0) break;
            task_cleanup((task_type*) node->data);
            free(node);
        }
    pthread_mutex_unlock(&schedule->schedule_lock);
}
コード例 #2
0
static task_type * 
keystate_ds_retract_task_perform(task_type *task)
{
    perform_keystate_ds_retract(-1,(engineconfig_type *)task->context,NULL,NULL,
                               1);
    task_cleanup(task);
    return NULL;
}
コード例 #3
0
void Scheduler::operator()(){
    //get the bit patterns and sort by node id (like the available algos)
    std::vector<state_type> bits = compute_dependencies();   
    // some book keeping vectors
    size_t size = algos_->size();
    std::vector<EventState*> event_states(0); //TODO - has to move to init 
    do {        
        // BEGIN TODO: replace by thread safe code in start event
        // loop through all events that need to be started
        bool queue_full(false);
        do {
            unsigned int event_number(0);
            queue_full = new_events_queue_.try_pop(event_number);
            if (queue_full){
                Context* context(0);
                bool whiteboard_available = wb_.get_context(context);
                if (whiteboard_available){
                    EventState* event_state = new EventState(size);
                    event_states.push_back(event_state);
                    event_state->context = context;
                    context->write(event_number, "event","event");
                } 
            }
        } while(queue_full);
        
        for (unsigned int algo = 0; algo < size; ++algo) {
            // loop through all currently active events
            for (unsigned int event_id = 0; event_id < event_states.size() ; ++event_id) {
                EventState*& event_state = event_states[event_id];
                // extract event_id specific quantities
                state_type& current_event_bits = event_state->state;
                // check whether all dependencies for the algorithm are fulfilled...
                state_type tmp = (current_event_bits & bits[algo]) ^ bits[algo];
                /// ...whether all required products are there...
                
                // ... and whether the algo was previously started
                std::vector<AlgoState>& algo_states = event_state->algo_states;
                if ((tmp==0) && (algo_states[algo] == NOT_RUN)) {
                	tryRunAlgo ( event_state, algo_states, algo );
                }
            }
        }        
        task_cleanup();
        // check for finished events and clean up
        for (std::vector<EventState*>::iterator i = event_states.begin(), end = event_states.end(); i != end; ++i){
            if ((*i)->state == termination_requirement_) {
                Context*& context = (*i)->context;
                wb_.release_context(context);
                loop_manager_->finished_event();
                delete (*i);
                i = event_states.erase(i);
            }
        }
        std::this_thread::yield();  
    } while (not has_to_stop_);
    return;
};
コード例 #4
0
ファイル: enforce_task.c プロジェクト: eest/opendnssec
static task_type *
enforce_task_perform(task_type *task)
{
	engine_type *engine = ((struct enf_task_ctx *)task->context)->engine;
	int enforce_all = ((struct enf_task_ctx *)task->context)->enforce_all;
	int return_time = perform_enforce_lock(-1, engine, enforce_all,
		task, task->dbconn);
	enforcer_context.enforce_all = 0;
	if (return_time != -1) return task;
	task_cleanup(task);
	return NULL;
}
コード例 #5
0
ファイル: schedule.c プロジェクト: eest/opendnssec
/**
 * Internal task cleanup function.
 *
 */
static void
task_delfunc(ldns_rbnode_t* elem, int del_payload)
{
    task_type* task;

    if (elem && elem != LDNS_RBTREE_NULL) {
        task = (task_type*) elem->data;
        task_delfunc(elem->left, del_payload);
        task_delfunc(elem->right, del_payload);
        if (del_payload)
            task_cleanup(task);
        free((void*)elem);
    }
}
コード例 #6
0
ファイル: kernel.c プロジェクト: dasadahanayaka/Akalon
/*---------------------------------------------------------------------------*/
void     task_idle (void)
{
    tcb_t *task ;

    printf ("Akalon: In Idle Task\n") ;

    /* We are in the Idle Task. Now let the BSP create the rest of  */
    /* the System's resources (tasks, sems, init routines, etc) by  */
    /* calling bsp_post_init(). However, interrupts should never be */
    /* enabled in bsp_post_init(). Also, note that any new task     */
    /* that's created in bsp_post_init() will not switch out the    */
    /* Idle Task because it is running at the highest priority.     */

    bsp_post_init () ;

    kernel.int_mode = NO ; /* Remove this HACK !!! <--- DO */

    /* All System Resources have now been created. Lower the Idle   */
    /* Task's priority to the lowest.                               */

    task_rm_from_q (kernel.task_idle) ;
    kernel.task_idle->priority = -1   ;
    task_add_to_q  (kernel.task_idle) ;

    /* Get the highest priority task and run it. Interrupts will be */
    /* enabled when the task is run by task_start().                */

    task = task_ready_get() ;

    if (task != kernel.task_idle)
    {
       kernel.task_idle->state = TASK_READY ;
       task_run_next (kernel.task_idle) ;
    }

    /* Interrupts were never enabled when the idle task was run. So */
    /* enable interrupts and start spinning until another task gets */
    /* into the ready state, which can happen becuase an interrupt. */
    /* If an interrupt never happens (for what ever reason), then   */
    /* to code will be stuck in the following while(1) loop.        */   

    cpu_enable_ints() ;
    while (1) 
    {
       /* Check if any task needs to be deleted */
       task_cleanup() ;
    }
    
} /* End of function task_idle() */
コード例 #7
0
ファイル: schedule.c プロジェクト: eest/opendnssec
ods_status
schedule_task(schedule_type* schedule, task_type* task)
{
    ldns_rbnode_t *node1, *node2;
    ods_status status;
    task_type* task2;

    if (!task) {
        ods_log_error("[%s] unable to schedule task: no task", schedule_str);
        return ODS_STATUS_ERR;
    }
    task->flush = 0;
    if (!schedule || !schedule->tasks) {
        ods_log_error("[%s] unable to schedule task: no schedule",
            schedule_str);
        return ODS_STATUS_ERR;
    }

    ods_log_debug("[%s] schedule task [%s] for %s", schedule_str,
        task_what2str(task->what), task_who2str(task->who));

    pthread_mutex_lock(&schedule->schedule_lock);
        status = ODS_STATUS_ERR;
        if ((node1 = task2node(task))) {
            if (ldns_rbtree_insert(schedule->tasks_by_name, node1)) {
                if ((node2 = task2node(task))) {
                    if(ldns_rbtree_insert(schedule->tasks, node2)) {
                        /* success inserting in two trees */
                        set_alarm(schedule);
                        status = ODS_STATUS_OK;
                    } else { /* insert in tasks tree failed */
                        ods_log_error("[%s] unable to schedule task [%s] for %s: "
                            " already present", schedule_str, task_what2str(task->what),
                            task_who2str(task->who));
                        /* this will free node1 */
                        free(ldns_rbtree_delete(schedule->tasks_by_name, node1));
                        free(node2);
                    }
                } else { /* could not alloc node2 */
                    /* this will free node1 */
                    free(ldns_rbtree_delete(schedule->tasks_by_name, node1));
                }

            } else {/* insert in name tree failed */
                free(node1);
                /**
                 * Task is already in tasks_by_name queue, so we must
                 * update it in tasks queue
                 */
                /* still in lock guaranteed to succeed. */
                node1 = ldns_rbtree_search(schedule->tasks_by_name, task);
                /* This copy of 'task' is referenced by both trees */
                task2 = (task_type*)node1->key;
                node1 = ldns_rbtree_delete(schedule->tasks, task2);
                if (task->when < task2->when)
                    task2->when = task->when;
                if (task2->context && task2->clean_context) {
                    task2->clean_context(task2);
                }
                task2->context = task->context;
                task2->clean_context = task->clean_context;
                task->context = NULL;
                task_cleanup(task);
                (void) ldns_rbtree_insert(schedule->tasks, node1);
                /* node1 now owned by tree */
                node1 = NULL;
                set_alarm(schedule);
                status = ODS_STATUS_OK;
            }
        } /* else {failure) */
    pthread_mutex_unlock(&schedule->schedule_lock);
    return status;
}
コード例 #8
0
/**
 * Try to recover from the backup files.
 *
 */
static ods_status
engine_recover(engine_type* engine)
{
    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
    zone_type* zone = NULL;
    ods_status status = ODS_STATUS_OK;
    ods_status result = ODS_STATUS_UNCHANGED;

    if (!engine || !engine->zonelist || !engine->zonelist->zones) {
        ods_log_error("[%s] cannot recover zones: no engine or zonelist",
            engine_str);
        return ODS_STATUS_ERR; /* no need to update zones */
    }
    ods_log_assert(engine);
    ods_log_assert(engine->zonelist);
    ods_log_assert(engine->zonelist->zones);

    lock_basic_lock(&engine->zonelist->zl_lock);
    /* [LOCK] zonelist */
    node = ldns_rbtree_first(engine->zonelist->zones);
    while (node && node != LDNS_RBTREE_NULL) {
        zone = (zone_type*) node->data;

        ods_log_assert(zone->zl_status == ZONE_ZL_ADDED);
        status = zone_recover2(zone);
        if (status == ODS_STATUS_OK) {
            ods_log_assert(zone->task);
            ods_log_assert(zone->db);
            ods_log_assert(zone->signconf);
            /* notify nameserver */
            if (engine->config->notify_command && !zone->notify_ns) {
                set_notify_ns(zone, engine->config->notify_command);
            }
            /* schedule task */
            lock_basic_lock(&engine->taskq->schedule_lock);
            /* [LOCK] schedule */
            status = schedule_task(engine->taskq, (task_type*) zone->task, 0);
            /* [UNLOCK] schedule */
            lock_basic_unlock(&engine->taskq->schedule_lock);

            if (status != ODS_STATUS_OK) {
                ods_log_crit("[%s] unable to schedule task for zone %s: %s",
                    engine_str, zone->name, ods_status2str(status));
                task_cleanup((task_type*) zone->task);
                zone->task = NULL;
                result = ODS_STATUS_OK; /* will trigger update zones */
            } else {
                ods_log_debug("[%s] recovered zone %s", engine_str,
                    zone->name);
                /* recovery done */
                zone->zl_status = ZONE_ZL_OK;
            }
        } else {
            if (status != ODS_STATUS_UNCHANGED) {
                ods_log_warning("[%s] unable to recover zone %s from backup,"
                " performing full sign", engine_str, zone->name);
            }
            result = ODS_STATUS_OK; /* will trigger update zones */
        }
        node = ldns_rbtree_next(node);
    }
    /* [UNLOCK] zonelist */
    lock_basic_unlock(&engine->zonelist->zl_lock);
    return result;
}
コード例 #9
0
/**
 * Update zones.
 *
 */
void
engine_update_zones(engine_type* engine, ods_status zl_changed)
{
    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
    zone_type* zone = NULL;
    zone_type* delzone = NULL;
    task_type* task = NULL;
    ods_status status = ODS_STATUS_OK;
    unsigned wake_up = 0;
    int warnings = 0;
    time_t now = 0;

    if (!engine || !engine->zonelist || !engine->zonelist->zones) {
        return;
    }
    now = time_now();

    ods_log_debug("[%s] commit zone list changes", engine_str);
    lock_basic_lock(&engine->zonelist->zl_lock);
    node = ldns_rbtree_first(engine->zonelist->zones);
    while (node && node != LDNS_RBTREE_NULL) {
        zone = (zone_type*) node->data;
        task = NULL; /* reset task */

        if (zone->zl_status == ZONE_ZL_REMOVED) {
            node = ldns_rbtree_next(node);
            lock_basic_lock(&zone->zone_lock);
            delzone = zonelist_del_zone(engine->zonelist, zone);
            if (delzone) {
                lock_basic_lock(&engine->taskq->schedule_lock);
                task = unschedule_task(engine->taskq,
                    (task_type*) zone->task);
                lock_basic_unlock(&engine->taskq->schedule_lock);
            }
            task_cleanup(task);
            task = NULL;
            lock_basic_unlock(&zone->zone_lock);
            netio_remove_handler(engine->xfrhandler->netio,
                &zone->xfrd->handler);
            zone_cleanup(zone);
            zone = NULL;
            continue;
        } else if (zone->zl_status == ZONE_ZL_ADDED) {
            lock_basic_lock(&zone->zone_lock);
            ods_log_assert(!zone->task);
            /* set notify nameserver command */
            if (engine->config->notify_command && !zone->notify_ns) {
                set_notify_ns(zone, engine->config->notify_command);
            }
            /* create task */
            task = task_create(TASK_SIGNCONF, now, zone);
            lock_basic_unlock(&zone->zone_lock);
            if (!task) {
                ods_log_crit("[%s] unable to create task for zone %s: "
                    "task_create() failed", engine_str, zone->name);
                node = ldns_rbtree_next(node);
                continue;
            }
        }
        /* load adapter config */
        status = adapter_load_config(zone->adinbound);
        if (status != ODS_STATUS_OK) {
            ods_log_error("[%s] unable to load config for inbound adapter "
                "for zone %s: %s", engine_str, zone->name,
                ods_status2str(status));
        }
        status = adapter_load_config(zone->adoutbound);
        if (status != ODS_STATUS_OK) {
            ods_log_error("[%s] unable to load config for outbound adapter "
                "for zone %s: %s", engine_str, zone->name,
                ods_status2str(status));
        }
        /* for dns adapters */
        warnings += dnsconfig_zone(engine, zone);

        if (zone->zl_status == ZONE_ZL_ADDED) {
            ods_log_assert(task);
            lock_basic_lock(&zone->zone_lock);
            zone->task = task;
            lock_basic_unlock(&zone->zone_lock);
            lock_basic_lock(&engine->taskq->schedule_lock);
            status = schedule_task(engine->taskq, task, 0);
            lock_basic_unlock(&engine->taskq->schedule_lock);
        } else if (zl_changed == ODS_STATUS_OK) {
            /* always try to update signconf */
            lock_basic_lock(&zone->zone_lock);
            status = zone_reschedule_task(zone, engine->taskq, TASK_SIGNCONF);
            lock_basic_unlock(&zone->zone_lock);
        }
        if (status != ODS_STATUS_OK) {
            ods_log_crit("[%s] unable to schedule task for zone %s: %s",
                engine_str, zone->name, ods_status2str(status));
        } else {
            wake_up = 1;
            zone->zl_status = ZONE_ZL_OK;
        }
        node = ldns_rbtree_next(node);
    }
    lock_basic_unlock(&engine->zonelist->zl_lock);
    if (engine->dnshandler) {
        dnshandler_fwd_notify(engine->dnshandler,
            (uint8_t*) ODS_SE_NOTIFY_CMD, strlen(ODS_SE_NOTIFY_CMD));
    } else if (warnings) {
        ods_log_warning("[%s] no dnshandler/listener configured, but zones "
         "are configured with dns adapters: notify and zone transfer "
         "requests will not work properly", engine_str);
    }
    if (wake_up) {
        engine_wakeup_workers(engine);
    }
    return;
}