int main(int argc, char* argv[]) { int cxn_id; int idx; ind_soc_config_t config; /* Currently ignored */ INDIGO_MEM_CLEAR(&config, sizeof(config)); OK(ind_soc_init(&config)); OK(ind_cxn_init(&cm_config)); OK(indigo_cxn_status_change_register(cxn_status_change, NULL)); OK(ind_cxn_enable_set(1)); INDIGO_ASSERT((cxn_id = setup_cxn()) >= 0); for (idx = 1; idx < 5; idx++) { printf("run %d\n", idx); OK(ind_soc_select_and_run(2000)); } /* Now remove and add the cxn a few times */ for (idx = 1; idx < 5; idx++) { OK(indigo_cxn_connection_remove(cxn_id)); INDIGO_ASSERT((cxn_id = setup_cxn()) >= 0); } OK(indigo_cxn_connection_remove(cxn_id)); OK(ind_cxn_enable_set(0)); OK(ind_cxn_finish()); return 0; }
static void socket_callback( int socket_id, void *cookie, int read_ready, int write_ready, int error_seen) { struct sock_counters *counters = cookie; printf("Socket callback called: id %d. rd %d. wr %d. er %d\n", socket_id, read_ready, write_ready, error_seen); INDIGO_ASSERT(!error_seen); if (write_ready) { counters->write++; if (write(socket_id, "x", 1) != 1) { perror("write"); abort(); } ind_soc_data_out_clear(socket_id); } if (read_ready) { char buf; counters->read++; if (read(socket_id, &buf, 1) != 1) { perror("read"); abort(); } INDIGO_ASSERT(buf == 'x'); } }
indigo_error_t ft_hash_flow_delete(ft_instance_t ft, ft_entry_t *entry, int make_callback) { INDIGO_ASSERT(ft->magic == FT_HASH_MAGIC_NUMBER); LOG_TRACE("Delete rsn %d flow " INDIGO_FLOW_ID_PRINTF_FORMAT, entry->removed_reason, entry->id); if (entry->id == INDIGO_FLOW_ID_INVALID) { LOG_ERROR("Deleting invalid flow table entry"); return INDIGO_ERROR_UNKNOWN; } if (make_callback && ft->config.entry_deleted_cb) { ft->config.entry_deleted_cb(ft, entry, ft->config.deleted_cookie); } /* Unlink from hash lists; clear entry; put it on the free list */ ft_entry_unlink(ft, entry); ft_entry_clear(ft, entry); INDIGO_ASSERT(entry->state == FT_FLOW_STATE_FREE); list_push(&ft->free_list, &entry->table_links); ft->status.current_count -= 1; ft->status.deletes += 1; return INDIGO_ERROR_NONE; }
static void process_flow_removal(ft_entry_t *entry, indigo_fi_flow_stats_t *final_stats, indigo_fi_flow_removed_t reason) { indigo_error_t rv; if (entry->flags & OF_FLOW_MOD_FLAG_SEND_FLOW_REM) { /* See OF spec 1.0.1, section 3.5, page 6 */ if (reason != INDIGO_FLOW_REMOVED_OVERWRITE) { if (final_stats != NULL) { INDIGO_ASSERT(final_stats->flow_id == entry->id); entry->packets = final_stats->packets; entry->bytes = final_stats->bytes; } else { entry->packets = (uint64_t)-1; entry->bytes = (uint64_t)-1; } send_flow_removed_message(entry, reason); } } rv = ft_delete(ind_core_ft, entry); if (rv != INDIGO_ERROR_NONE) { LOG_ERROR("Error deleting flow from state mgr. id: " INDIGO_FLOW_ID_PRINTF_FORMAT, INDIGO_FLOW_ID_PRINTF_ARG(entry->id)); } LOG_TRACE("Flow table now has %d entries", FT_STATUS(ind_core_ft)->current_count); }
static void socket_callback( int socket_id, void *cookie, int read_ready, int write_ready, int error_seen) { char buf[2048]; int bytes_read; printf("Socket callback called: id %d. rd %d. wr %d. er %d\n", socket_id, read_ready, write_ready, error_seen); socket_called = 1; if (write_ready) { sock_write_seen = 1; send(socket_id, "x", 1, MSG_DONTWAIT); ind_soc_data_out_clear(socket_id); } if (read_ready) { printf("Reading from socket %d\n", socket_id); bytes_read = read(socket_id, buf, 2048); printf("Read in %d bytes\n", bytes_read); sock_read_seen = 1; ind_soc_data_out_ready(socket_id); } INDIGO_ASSERT(!error_seen); }
int main(int argc, char* argv[]) { INDIGO_ASSERT(1==1); AIM_LOG_INFO("Okay."); return 0; }
static void test_timer_mgmt(void) { /* Should be able to register a timer */ INDIGO_ASSERT(ind_soc_timer_event_register( timer_callback, (void*)1, 10) == 0); /* Should be able to re-register a timer */ INDIGO_ASSERT(ind_soc_timer_event_register( timer_callback, (void*)1, 100) == 0); /* Should be able to unregister a timer */ INDIGO_ASSERT(ind_soc_timer_event_unregister( timer_callback, (void*)1) == 0); /* Should not be able to unregister a timer twice */ INDIGO_ASSERT(ind_soc_timer_event_unregister( timer_callback, (void*)1) < 0); /* Should not be able to unregister a NULL callback */ INDIGO_ASSERT(ind_soc_timer_event_unregister( NULL, (void*)1) < 0); /* Should be able to register and unregister a bunch of timers */ { int i, j; for (i = 0; 1; i++) { indigo_error_t err = ind_soc_timer_event_register( timer_callback, (void *)(uintptr_t)i, 100); if (err < 0) { INDIGO_ASSERT(err == INDIGO_ERROR_RESOURCE); break; } } for (j = 0; 1; j++) { indigo_error_t err = ind_soc_timer_event_unregister( timer_callback, (void *)(uintptr_t)j); if (err < 0) { INDIGO_ASSERT(err == INDIGO_ERROR_NOT_FOUND); break; } } INDIGO_ASSERT(i == j); INDIGO_ASSERT(i >= 16); } }
static void test_immediate_timer(void) { int count = 0; INDIGO_ASSERT(ind_soc_timer_event_register( timer_callback, &count, IND_SOC_TIMER_IMMEDIATE) == 0); /* Should run immediately */ ind_soc_select_and_run(0); INDIGO_ASSERT(count == 1); /* Should be unregistered after firing */ count = 0; ind_soc_select_and_run(100); INDIGO_ASSERT(count == 0); /* Should be unregistered after firing */ INDIGO_ASSERT(ind_soc_timer_event_unregister(timer_callback, &count) < 0); }
int main(int argc, char* argv[]) { ind_soc_config_t config = {0}; int fds[2]; printf("Init returned %d\n", ind_soc_init(&config)); /* Should be called once */ ind_soc_timer_event_register(timer_callback, NULL, IND_SOC_TIMER_IMMEDIATE); ind_soc_select_and_run(10); INDIGO_ASSERT(timer_called); timer_called = 0; ind_soc_select_and_run(1000); INDIGO_ASSERT(!timer_called); ind_soc_timer_event_register(timer_callback, NULL, 100); ind_soc_select_and_run(1000); INDIGO_ASSERT(timer_called); timer_called = 0; ind_soc_timer_event_register(timer_callback_repeat, NULL, 100); ind_soc_select_and_run(1000); INDIGO_ASSERT(timer_called >= 9); ind_soc_timer_event_unregister(timer_callback_repeat, NULL); if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) { perror("socketpair"); abort(); } INDIGO_ASSERT(ind_soc_socket_register(fds[0], socket_callback, NULL) == 0); INDIGO_ASSERT(ind_soc_socket_register(fds[1], socket_callback, NULL) == 0); ind_soc_data_out_ready(fds[0]); ind_soc_data_out_ready(fds[1]); /* Do stuff for 3 seconds */ ind_soc_select_and_run(3000); INDIGO_ASSERT(socket_called > 0); INDIGO_ASSERT(sock_read_seen > 0); INDIGO_ASSERT(sock_write_seen > 0); return 0; }
static void test_periodic_timer(void) { int count; /* Should fire every 'repeat_time_ms' */ count = 0; ind_soc_timer_event_register(timer_callback, &count, 100); ind_soc_select_and_run(1000); INDIGO_ASSERT(count >= 9 && count <= 11); INDIGO_ASSERT(ind_soc_timer_event_unregister(timer_callback, &count) == 0); /* A timer may re-register itself with a different period during its callback */ count = 0; ind_soc_timer_event_register(timer_callback_reregister, &count, 100); ind_soc_select_and_run(1000); INDIGO_ASSERT(count > 50 && count < 100); INDIGO_ASSERT(ind_soc_timer_event_unregister(timer_callback_reregister, &count) == 0); /* A timer may unregister itself during its callback */ count = 0; ind_soc_timer_event_register(timer_callback_unregister, &count, 100); ind_soc_select_and_run(1000); INDIGO_ASSERT(count == 1); INDIGO_ASSERT(ind_soc_timer_event_unregister(timer_callback_unregister, &count) < 0); }
static void cxn_closing_timeout(void *cookie) { connection_t *cxn; cxn = (connection_t *) cookie; INDIGO_ASSERT(CONNECTION_STATE(cxn) == INDIGO_CXN_S_CLOSING); LOG_WARN(cxn, "Timeout in closing state"); cxn_state_set(cxn, INDIGO_CXN_S_DISCONNECTED); }
static void cxn_connecting_timeout(void *cookie) { connection_t *cxn; cxn = (connection_t *) cookie; INDIGO_ASSERT(CONNECTION_STATE(cxn) == INDIGO_CXN_S_CONNECTING); LOG_WARN(cxn, "Timeout in connecting state"); ind_cxn_disconnect(cxn); }
void ft_hash_delete(ft_instance_t ft) { ft_entry_t *entry; list_links_t *cur, *next; if (ft == NULL) { return; } INDIGO_ASSERT(ft->magic == FT_HASH_MAGIC_NUMBER); FT_ITER(ft, entry, cur, next) { ft_entry_unlink(ft, entry); ft_entry_clear(ft, entry); }
indigo_error_t ft_hash_flow_add(ft_instance_t ft, indigo_flow_id_t id, of_flow_add_t *flow_add, ft_entry_t **entry_p) { ft_entry_t *entry; list_links_t *links; indigo_error_t rv; INDIGO_ASSERT(ft->magic == FT_HASH_MAGIC_NUMBER); LOG_TRACE("Adding flow " INDIGO_FLOW_ID_PRINTF_FORMAT, id); if (flow_add->version != OF_VERSION_1_0) { /* @fixme */ LOG_ERROR("ERROR: bad version in ft_hash_flow_add"); return INDIGO_ERROR_VERSION; } /* If flow ID already exists, error. */ if (ft_id_lookup(ft, id) != NULL) { return INDIGO_ERROR_EXISTS; } /* Grab an entry from the free list */ if ((links = list_pop(&ft->free_list)) == NULL) { ++(ft->status.table_full_errors); return INDIGO_ERROR_RESOURCE; } entry = FT_ENTRY_CONTAINER(links, table); if ((rv = ft_entry_setup(entry, id, flow_add)) < 0) { return rv; } ft_entry_link(ft, entry); ft->status.adds += 1; ft->status.current_count += 1; if (entry_p != NULL) { *entry_p = entry; } return INDIGO_ERROR_NONE; }
static indigo_time_t calc_expiration_time(ft_entry_t *entry, int *reason) { indigo_time_t idle_expiration_time = -1, hard_expiration_time = -1; INDIGO_ASSERT(entry->hard_timeout || entry->idle_timeout); if (entry->hard_timeout > 0) { hard_expiration_time = entry->insert_time + entry->hard_timeout*1000; } if (entry->idle_timeout > 0) { idle_expiration_time = entry->last_counter_change + entry->idle_timeout*1000; } if (hard_expiration_time <= idle_expiration_time) { *reason = OF_FLOW_REMOVED_REASON_HARD_TIMEOUT; return hard_expiration_time; } else { *reason = OF_FLOW_REMOVED_REASON_IDLE_TIMEOUT; return idle_expiration_time; } }
/* Test add/remove of sockets */ static void test_socket_mgmt(void) { int fds[2]; struct sock_counters counters[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) { perror("socketpair"); abort(); } /* Unregistering a not-registered socket should fail */ INDIGO_ASSERT(ind_soc_socket_unregister(fds[0]) < 0); /* Adding and then unregistering a socket should succeed */ INDIGO_ASSERT(ind_soc_socket_register(fds[0], socket_callback, &counters[0]) == 0); INDIGO_ASSERT(ind_soc_socket_unregister(fds[0]) == 0); /* Trying to unregister twice should fail */ INDIGO_ASSERT(ind_soc_socket_unregister(fds[0]) < 0); /* Trying to register twice should fail */ INDIGO_ASSERT(ind_soc_socket_register(fds[0], socket_callback, &counters[0]) == 0); INDIGO_ASSERT(ind_soc_socket_register(fds[0], socket_callback, &counters[0]) < 0); /* Add another socket, then remove the first */ INDIGO_ASSERT(ind_soc_socket_register(fds[1], socket_callback, &counters[1]) == 0); INDIGO_ASSERT(ind_soc_socket_unregister(fds[0]) == 0); /* Write one byte to fds[1] */ ind_soc_data_out_ready(fds[1]); memset(counters, 0, sizeof(counters)); ind_soc_select_and_run(0); INDIGO_ASSERT(counters[0].read == 0); INDIGO_ASSERT(counters[0].write == 0); INDIGO_ASSERT(counters[1].read == 0); INDIGO_ASSERT(counters[1].write == 1); /* Expect no events from the not-registered fds[0] */ memset(counters, 0, sizeof(counters)); ind_soc_select_and_run(0); INDIGO_ASSERT(counters[0].read == 0); INDIGO_ASSERT(counters[0].write == 0); INDIGO_ASSERT(counters[1].read == 0); INDIGO_ASSERT(counters[1].write == 0); /* Register fds[0] and expect a read event */ INDIGO_ASSERT(ind_soc_socket_register(fds[0], socket_callback, &counters[0]) == 0); memset(counters, 0, sizeof(counters)); ind_soc_select_and_run(0); INDIGO_ASSERT(counters[0].read == 1); INDIGO_ASSERT(counters[0].write == 0); INDIGO_ASSERT(counters[1].read == 0); INDIGO_ASSERT(counters[1].write == 0); INDIGO_ASSERT(ind_soc_socket_unregister(fds[0]) == 0); INDIGO_ASSERT(ind_soc_socket_unregister(fds[1]) == 0); close(fds[0]); close(fds[1]); }
static void test_socket(void) { int fds[2]; struct sock_counters counters[2]; indigo_time_t start_time, end_time; struct itimerval itv; signal(SIGALRM, sigalrm); if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) { perror("socketpair"); abort(); } INDIGO_ASSERT(ind_soc_socket_register(fds[0], socket_callback, &counters[0]) == 0); INDIGO_ASSERT(ind_soc_socket_register(fds[1], socket_callback, &counters[1]) == 0); /* No events ready */ memset(counters, 0, sizeof(counters)); ind_soc_select_and_run(0); INDIGO_ASSERT(counters[0].read == 0); INDIGO_ASSERT(counters[0].write == 0); INDIGO_ASSERT(counters[1].read == 0); INDIGO_ASSERT(counters[1].write == 0); /* Write one byte to fds[0] */ ind_soc_data_out_ready(fds[0]); memset(counters, 0, sizeof(counters)); ind_soc_select_and_run(0); INDIGO_ASSERT(counters[0].read == 0); INDIGO_ASSERT(counters[0].write == 1); INDIGO_ASSERT(counters[1].read == 0); INDIGO_ASSERT(counters[1].write == 0); /* Read one byte from fds[1] */ memset(counters, 0, sizeof(counters)); ind_soc_select_and_run(0); INDIGO_ASSERT(counters[0].read == 0); INDIGO_ASSERT(counters[0].write == 0); INDIGO_ASSERT(counters[1].read == 1); INDIGO_ASSERT(counters[1].write == 0); /* Write one byte to each of fds[0] and fds[1] */ ind_soc_data_out_ready(fds[0]); ind_soc_data_out_ready(fds[1]); memset(counters, 0, sizeof(counters)); ind_soc_select_and_run(0); INDIGO_ASSERT(counters[0].read == 0); INDIGO_ASSERT(counters[0].write == 1); INDIGO_ASSERT(counters[1].read == 0); INDIGO_ASSERT(counters[1].write == 1); /* Read one byte from each of fds[0] and fds[1] */ memset(counters, 0, sizeof(counters)); ind_soc_select_and_run(0); INDIGO_ASSERT(counters[0].read == 1); INDIGO_ASSERT(counters[0].write == 0); INDIGO_ASSERT(counters[1].read == 1); INDIGO_ASSERT(counters[1].write == 0); /* Write one byte to fds[0] */ ind_soc_data_out_ready(fds[0]); memset(counters, 0, sizeof(counters)); ind_soc_select_and_run(0); INDIGO_ASSERT(counters[0].read == 0); INDIGO_ASSERT(counters[0].write == 1); INDIGO_ASSERT(counters[1].read == 0); INDIGO_ASSERT(counters[1].write == 0); /* Pause data in from fds[1], expect no reads */ ind_soc_data_in_pause(fds[1]); memset(counters, 0, sizeof(counters)); ind_soc_select_and_run(0); INDIGO_ASSERT(counters[0].read == 0); INDIGO_ASSERT(counters[0].write == 0); INDIGO_ASSERT(counters[1].read == 0); INDIGO_ASSERT(counters[1].write == 0); /* Resume data in from fds[1] */ ind_soc_data_in_resume(fds[1]); memset(counters, 0, sizeof(counters)); ind_soc_select_and_run(0); INDIGO_ASSERT(counters[0].read == 0); INDIGO_ASSERT(counters[0].write == 0); INDIGO_ASSERT(counters[1].read == 1); INDIGO_ASSERT(counters[1].write == 0); /* Block for some time with no events */ memset(counters, 0, sizeof(counters)); start_time = INDIGO_CURRENT_TIME; ind_soc_select_and_run(100); end_time = INDIGO_CURRENT_TIME; INDIGO_ASSERT(counters[0].read == 0); INDIGO_ASSERT(counters[0].write == 0); INDIGO_ASSERT(counters[1].read == 0); INDIGO_ASSERT(counters[1].write == 0); INDIGO_ASSERT((end_time - start_time) >= 100 && (end_time - start_time) < 200); /* Block for some time until SIGALRM, which causes read ready on fd[1] */ memset(counters, 0, sizeof(counters)); memset(&itv, 0, sizeof(itv)); sigalrm_write_fd = fds[0]; itv.it_value.tv_usec = 100*1000; setitimer(ITIMER_REAL, &itv, NULL); ind_soc_select_and_run(200); INDIGO_ASSERT(counters[0].read == 0); INDIGO_ASSERT(counters[0].write == 0); INDIGO_ASSERT(counters[1].read == 1); INDIGO_ASSERT(counters[1].write == 0); INDIGO_ASSERT(ind_soc_socket_unregister(fds[0]) == 0); INDIGO_ASSERT(ind_soc_socket_unregister(fds[1]) == 0); close(fds[0]); close(fds[1]); }
static void test_task(void) { int counters[2]; int i; task_counter_limit = 3; INDIGO_ASSERT(ind_soc_task_register(task_callback, &counters[0], 0) == INDIGO_ERROR_NONE); /* Task should immediately run */ memset(counters, 0, sizeof(counters)); ind_soc_select_and_run(0); INDIGO_ASSERT(counters[0] == 1); /* Task should keep running */ memset(counters, 0, sizeof(counters)); ind_soc_select_and_run(0); INDIGO_ASSERT(counters[0] == 1); INDIGO_ASSERT(ind_soc_task_register(task_callback, &counters[1], 0) == INDIGO_ERROR_NONE); /* Both tasks should run until the counter == 3 */ memset(counters, 0, sizeof(counters)); for (i = 1; i <= 3; i++) { ind_soc_select_and_run(0); INDIGO_ASSERT(counters[0] == i); INDIGO_ASSERT(counters[1] == i); } /* No tasks should run after finishing */ memset(counters, 0, sizeof(counters)); ind_soc_select_and_run(0); INDIGO_ASSERT(counters[0] == 0); INDIGO_ASSERT(counters[1] == 0); /* Task should yield after 10 ms */ INDIGO_ASSERT(ind_soc_task_register(task_callback_yield, &counters[0], 0) == INDIGO_ERROR_NONE); memset(counters, 0, sizeof(counters)); i = 0; while (counters[0] < 100) { int tmp; tmp = counters[0]; ind_soc_select_and_run(0); tmp = counters[0] - tmp; INDIGO_ASSERT(tmp <= 10); /* 10 ms/timeslice / 1+ ms/unit <= 10 units/timeslice */ i++; } INDIGO_ASSERT(i >= 10); /* (100 units * 1+ ms/unit) / 10 ms/timeslice >= 10 timeslices */ INDIGO_ASSERT(100 / i >= 5); /* average at least 5 units per timeslice */ /* Excessively long callback should trigger a warning (not checked) */ INDIGO_ASSERT(ind_soc_task_register(task_callback_long, &counters[0], 0) == INDIGO_ERROR_NONE); memset(counters, 0, sizeof(counters)); ind_soc_select_and_run(0); INDIGO_ASSERT(counters[0] == 1); /* Task should be repeatedly rescheduled in the same call to ind_soc_select_and_run */ INDIGO_ASSERT(ind_soc_task_register(task_callback_yield, &counters[0], 0) == INDIGO_ERROR_NONE); memset(counters, 0, sizeof(counters)); ind_soc_select_and_run(500); INDIGO_ASSERT(counters[0] == 100); }
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]); } }