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; }
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; }
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]); } }