示例#1
0
indigo_error_t
ind_core_enable_set(int enable)
{
    LOG_TRACE("OF state mgr enable called");

    INIT_CHECK;

    if (enable && !ind_core_module_enabled) {
        LOG_INFO("Enabling OF state mgr");
        if (CORE_EXPIRES_FLOWS(&ind_core_config)) {
            ind_soc_timer_event_register_with_priority(
                flow_expiration_timer, NULL,
                ind_core_config.stats_check_ms, -10);
        }
        ind_core_module_enabled = 1;
    } else if (!enable && ind_core_module_enabled) {
        LOG_INFO("Disabling OF state mgr");
        if (CORE_EXPIRES_FLOWS(&ind_core_config)) {
            ind_soc_timer_event_unregister(flow_expiration_timer, NULL);
        }
        ind_core_module_enabled = 0;
    } else {
        LOG_VERBOSE("Redundant enable call.  Currently %s",
                    ind_core_module_enabled ? "enabled" : "disabled");
    }

    return INDIGO_ERROR_NONE;
}
示例#2
0
static inline void
cxn_state_set(connection_t *cxn, indigo_cxn_state_t new_state)
{
    indigo_cxn_state_t old_state;

    old_state = CONNECTION_STATE(cxn);

    if (old_state == new_state) {
        LOG_TRACE(cxn, "Non-state change in %s", CXN_STATE_NAME(new_state));
        return;
    }

    LOG_INFO(cxn, "%s->%s", CXN_STATE_NAME(old_state),
             CXN_STATE_NAME(new_state));

    /****************************************************************
     *
     * Verify pre-conditions
     *
     * @fixme Check here for illegal state transitions
     *
     ****************************************************************/

    switch (new_state) {
    case INDIGO_CXN_S_DISCONNECTED:
        /* If moving to disconnected, must be closing (or disconnected) */
        if ((old_state != INDIGO_CXN_S_CLOSING)) {
            LOG_ERROR(cxn, "Error in cxn SM: disconnected from %s",
                      CXN_STATE_NAME(old_state));
            /* Clean up and hope for the best */
        }
        break;

    default:
        break;
    }


    /****************************************************************
     *
     * Exit conditions for old state
     *
     ****************************************************************/

    switch (old_state) {
    case INDIGO_CXN_S_CLOSING:
        ind_soc_timer_event_unregister(cxn_closing_timeout, (void *)cxn);
        break;
    case INDIGO_CXN_S_CONNECTING:
        if (!CXN_LOCAL(cxn)) {
            ind_soc_timer_event_unregister(cxn_connecting_timeout,
                                           (void *)cxn);
        }
        break;

    default:
        break;
    }

    /****************************************************************
     *
     * Process change to new state
     *
     ****************************************************************/

    /* Change state of connection */
    cxn->status.state = new_state;

    /* External notification of state change before processing */
    ind_cxn_status_change(cxn);

    /* Post-processing of state transition. */
    switch (new_state) {
    case INDIGO_CXN_S_DISCONNECTED:
        if (cxn->flags & CXN_TO_BE_REMOVED) {
            LOG_VERBOSE(cxn, "Completing cxn removal");
            cxn->active = 0;
        } else if (CXN_LOCAL(cxn)) {
            cxn->active = 0;
        } else {
            /* Disconnected but still active - start connecting again */
            ind_soc_timer_event_register_with_priority(
                ind_cxn_connection_retry_timer, cxn,
                IND_SOC_TIMER_IMMEDIATE, IND_CXN_EVENT_PRIORITY);
        }
        ind_cxn_disconnected_init(cxn);
        break;

    case INDIGO_CXN_S_CONNECTING:
        /* Register with socket manager */
        ind_soc_socket_register_with_priority(
            cxn->sd, indigo_cxn_socket_ready_callback,
            cxn, IND_CXN_EVENT_PRIORITY);
        ind_cxn_send_hello(cxn);
        if (CXN_LOCAL(cxn)) {
            /* Recursive call; transition to connected */
            cxn_state_set(cxn, INDIGO_CXN_S_HANDSHAKE_COMPLETE);
        } else {
            ind_soc_timer_event_register_with_priority(
                cxn_connecting_timeout, (void *)cxn,
                CXN_STATE_TIMEOUT(new_state), IND_CXN_EVENT_PRIORITY);
        }
        break;

    case INDIGO_CXN_S_CLOSING:
#if defined(OF_OBJECT_TRACKING)
#define VERBOSE_LOG_ENABLED 1    /* @FIXME Check log level */
        if ((cxn->outstanding_ops) && VERBOSE_LOG_ENABLED) {
            biglist_t *elt;
            of_object_t *obj;

            LOG_VERBOSE(cxn, "Closing connnection with outstanding ops");
            BIGLIST_FOREACH_DATA(elt, cxn->outstanding_ops,
                                 of_object_t *, obj) {
                of_object_track_output(obj, (loci_writer_f)aim_printf, AIM_LOG_STRUCT_POINTER->pvs);
            }
        }
#endif
        ind_soc_timer_event_unregister(periodic_keepalive, (void *)cxn);
        ind_soc_timer_event_register_with_priority(
            cxn_closing_timeout, (void *)cxn,
            CXN_STATE_TIMEOUT(new_state), IND_CXN_EVENT_PRIORITY);
        cleanup_disconnect(cxn);
        break;
    case INDIGO_CXN_S_HANDSHAKE_COMPLETE:
        if (cxn->keepalive.period_ms > 0) {
            /* Set up periodic echo request */
            ind_soc_timer_event_register_with_priority(
                periodic_keepalive, (void *)cxn,
                cxn->keepalive.period_ms, IND_CXN_EVENT_PRIORITY);
        }

        break;

    default:
        break;
    }
示例#3
0
static void
test_priority(void)
{
    int read_fds[3], write_fds[3];
    struct sock_counters counters[3];
    int timer_counters[3];
    int task_counters[3];
    int i;

    task_counter_limit = 1;

    for (i = 0; i < 3; i++) {
        int fds[2];
        if (pipe(fds) < 0) {
            perror("pipe");
            abort();
        }
        read_fds[i] = fds[0];
        write_fds[i] = fds[1];
    }

    /* High priority */
    INDIGO_ASSERT(ind_soc_socket_register_with_priority(
                      read_fds[0], socket_callback, &counters[0], IND_SOC_HIGH_PRIORITY) == 0);

    INDIGO_ASSERT(ind_soc_timer_event_register_with_priority(
                      timer_callback, &timer_counters[0], IND_SOC_TIMER_IMMEDIATE, IND_SOC_HIGH_PRIORITY) == 0);

    INDIGO_ASSERT(ind_soc_task_register(
                      task_callback, &task_counters[0], IND_SOC_HIGH_PRIORITY) == 0);

    /* Medium priority */
    INDIGO_ASSERT(ind_soc_socket_register_with_priority(
                      read_fds[1], socket_callback, &counters[1], IND_SOC_NORMAL_PRIORITY) == 0);

    INDIGO_ASSERT(ind_soc_timer_event_register_with_priority(
                      timer_callback, &timer_counters[1], IND_SOC_TIMER_IMMEDIATE, IND_SOC_NORMAL_PRIORITY) == 0);

    INDIGO_ASSERT(ind_soc_task_register(
                      task_callback, &task_counters[1], IND_SOC_NORMAL_PRIORITY) == 0);

    /* Low priority */
    INDIGO_ASSERT(ind_soc_socket_register_with_priority(
                      read_fds[2], socket_callback, &counters[2], IND_SOC_LOW_PRIORITY) == 0);

    INDIGO_ASSERT(ind_soc_timer_event_register_with_priority(
                      timer_callback, &timer_counters[2], IND_SOC_TIMER_IMMEDIATE, IND_SOC_LOW_PRIORITY) == 0);

    INDIGO_ASSERT(ind_soc_task_register(
                      task_callback, &task_counters[2], IND_SOC_LOW_PRIORITY) == 0);

    /* Make all sockets ready */
    for (i = 0; i < 3; i++) {
        write(write_fds[i], "x", 1);
    }

    /* Higher priority events should run first */
    memset(counters, 0, sizeof(counters));
    memset(timer_counters, 0, sizeof(timer_counters));
    memset(task_counters, 0, sizeof(task_counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 1);
    INDIGO_ASSERT(counters[1].read == 0);
    INDIGO_ASSERT(counters[2].read == 0);
    INDIGO_ASSERT(timer_counters[0] == 1);
    INDIGO_ASSERT(timer_counters[1] == 0);
    INDIGO_ASSERT(timer_counters[2] == 0);
    INDIGO_ASSERT(task_counters[0] == 1);
    INDIGO_ASSERT(task_counters[1] == 0);
    INDIGO_ASSERT(task_counters[2] == 0);

    /* Medium priority events should run next */
    memset(counters, 0, sizeof(counters));
    memset(timer_counters, 0, sizeof(timer_counters));
    memset(task_counters, 0, sizeof(task_counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 0);
    INDIGO_ASSERT(counters[1].read == 1);
    INDIGO_ASSERT(counters[2].read == 0);
    INDIGO_ASSERT(timer_counters[0] == 0);
    INDIGO_ASSERT(timer_counters[1] == 1);
    INDIGO_ASSERT(timer_counters[2] == 0);
    INDIGO_ASSERT(task_counters[0] == 0);
    INDIGO_ASSERT(task_counters[1] == 1);
    INDIGO_ASSERT(task_counters[2] == 0);

    /* New high priority events should run next */
    write(write_fds[0], "x", 1);
    INDIGO_ASSERT(ind_soc_task_register(
                      task_callback, &task_counters[0], IND_SOC_HIGH_PRIORITY) == 0);
    memset(counters, 0, sizeof(counters));
    memset(timer_counters, 0, sizeof(timer_counters));
    memset(task_counters, 0, sizeof(task_counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 1);
    INDIGO_ASSERT(counters[1].read == 0);
    INDIGO_ASSERT(counters[2].read == 0);
    INDIGO_ASSERT(timer_counters[0] == 0);
    INDIGO_ASSERT(timer_counters[1] == 0);
    INDIGO_ASSERT(timer_counters[2] == 0);
    INDIGO_ASSERT(task_counters[0] == 1);
    INDIGO_ASSERT(task_counters[1] == 0);
    INDIGO_ASSERT(task_counters[2] == 0);

    /* Low priority events should run last */
    memset(counters, 0, sizeof(counters));
    memset(timer_counters, 0, sizeof(timer_counters));
    memset(task_counters, 0, sizeof(task_counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 0);
    INDIGO_ASSERT(counters[1].read == 0);
    INDIGO_ASSERT(counters[2].read == 1);
    INDIGO_ASSERT(timer_counters[0] == 0);
    INDIGO_ASSERT(timer_counters[1] == 0);
    INDIGO_ASSERT(timer_counters[2] == 1);
    INDIGO_ASSERT(task_counters[0] == 0);
    INDIGO_ASSERT(task_counters[1] == 0);
    INDIGO_ASSERT(task_counters[2] == 1);

    INDIGO_ASSERT(ind_soc_socket_unregister(read_fds[0]) == 0);
    INDIGO_ASSERT(ind_soc_socket_unregister(read_fds[1]) == 0);
    INDIGO_ASSERT(ind_soc_socket_unregister(read_fds[2]) == 0);

    /* One-shot timers, already unregistered */
    INDIGO_ASSERT(ind_soc_timer_event_unregister(
                      timer_callback, &timer_counters[0]) < 0);
    INDIGO_ASSERT(ind_soc_timer_event_unregister(
                      timer_callback, &timer_counters[1]) < 0);
    INDIGO_ASSERT(ind_soc_timer_event_unregister(
                      timer_callback, &timer_counters[3]) < 0);

    for (i = 0; i < 3; i++) {
        close(read_fds[i]);
        close(write_fds[i]);
    }
}