/*************************************************************************************** function: int read_one_packet(u_int8_t **packet_addr, u_int32_t *packet_size) input: packet_addr: pointer to the address of the packet for read packet_size: pointer to the size of the packet for read return value: 0: successful, -1: failed remarks: value-result arguments are used ***************************************************************************************/ int read_one_packet(u_int8_t **packet_addr, u_int32_t *packet_size) { #if defined( __linux__ ) u_int32_t entry_index_for_this_read; free_last_read_packet(); pthread_mutex_lock(&fifo_core.mutex); // wait on the condition variable if fifo is empty while (fifo_core.used_entry_num == 0) { // printf("fifo empty, waiting...\n"); //jay pthread_cond_wait(&fifo_core.cond, &fifo_core.mutex); } entry_index_for_this_read = fifo_core.entry_index_for_next_read; // advertise the packet *packet_addr = myFIFO.packet_info_entries[entry_index_for_this_read].packet_addr; *packet_size = myFIFO.packet_info_entries[entry_index_for_this_read].packet_size; // update entry index for next read fifo_core.entry_index_for_next_read++; wraparound_entry_index_if_necessary(&fifo_core.entry_index_for_next_read); // update related info fifo_core.entry_index_being_used = entry_index_for_this_read; pthread_mutex_unlock(&fifo_core.mutex); #elif defined( _WIN32 ) u_int32_t entry_index_for_this_read; free_last_read_packet(); DWORD Error = ::WaitForSingleObject( fifo_core.mutex, INFINITE ); // wait on the condition variable if fifo is empty while (fifo_core.used_entry_num == 0) { // printf("fifo empty, waiting...\n"); //jay WaitForSingleObject( fifo_core.cond, INFINITE ); } entry_index_for_this_read = fifo_core.entry_index_for_next_read; // advertise the packet *packet_addr = myFIFO.packet_info_entries[entry_index_for_this_read].packet_addr; *packet_size = myFIFO.packet_info_entries[entry_index_for_this_read].packet_size; // update entry index for next read fifo_core.entry_index_for_next_read++; wraparound_entry_index_if_necessary(&fifo_core.entry_index_for_next_read); // update related info fifo_core.entry_index_being_used = entry_index_for_this_read; ::ReleaseMutex( fifo_core.mutex ); #endif return 0; }
/* ***************************************************************************/ int fifo_read_one_packet(fifo_t *fifo, u8 *header, u8 **packet_addr, u32 *packet_size) { int entry_index_for_this_read; // printf("lock, read\n"); pthread_mutex_lock(&fifo->mutex); // printf("locked, read\n"); free_last_read_packet(fifo); // wait on the condition variable if fifo is empty while (fifo->used_entry_num == 0) { // printf("unlock, waiting...\n"); //jay pthread_cleanup_push(cancel_read_wait, (void *) &fifo->mutex); pthread_cond_wait(&fifo->cond, &fifo->mutex); // printf("lock, awake\n"); pthread_cleanup_pop(0); } entry_index_for_this_read = fifo->entry_index_for_next_read; while (fifo->packet_info_entries[entry_index_for_this_read].entry_state == ENTRY_INVALID) { fifo_printf("\t\t\t\tskip entry %d\n", entry_index_for_this_read); entry_index_for_this_read++; wraparound_entry_index_if_necessary(fifo, &entry_index_for_this_read); } fifo_printf("\t\t\t\t\t[%x]read %d, entry %d\n", (u32)fifo&0xf, entry_index_for_this_read, fifo->used_entry_num); // advertise the packet *packet_addr = fifo->packet_info_entries[entry_index_for_this_read].packet_addr; *packet_size = fifo->packet_info_entries[entry_index_for_this_read].packet_size; memcpy(header, &fifo->header_entries[entry_index_for_this_read*(fifo->header_size)], fifo->header_size); // update entry index for next read fifo->entry_index_for_next_read = entry_index_for_this_read + 1; wraparound_entry_index_if_necessary(fifo, &fifo->entry_index_for_next_read); // update related info fifo->entry_index_being_used = entry_index_for_this_read; // printf("unlock, read\n"); pthread_mutex_unlock(&fifo->mutex); return 0; }