void* comm_recv_thread_start( void* data ) { recv_thread_t* my_info = reinterpret_cast<recv_thread_t*>(data); char incoming_buf[1500]; msg_t* incoming; // Receive loop // Communication hasn't been stopped while ( my_info->state == T_STATE_ACTIVE ) { int bytes = ::recv( my_info->sockfd, incoming_buf, sizeof(incoming_buf), 0 ); if ( bytes != sizeof(msg_t) ) { cout << "DIDNOT RECEIVE ENTIRE MESSAGE" << endl; } // Normal receive if ( bytes > 0 ) { incoming = reinterpret_cast<msg_t*>(incoming_buf); comm_recv_q.push( *incoming ); } // Connection closed else if ( bytes <= 0 ) { cout << "comm_recv_thread_start Terminating receive thread" << endl; comm_close_connection( incoming->send_ID ); my_info->state = T_STATE_STOP; break; } } ::close( my_info->sockfd ); return NULL; }
int comm_stop() { comm_tcp_recv_threads.mutex.lock(); // Mark all threads STOP comm_tcp_listen_thread.state = T_STATE_STOP; comm_udp_recv_thread.state = T_STATE_STOP; comm_recv_parse_thread.state = T_STATE_STOP; comm_send_thread.state = T_STATE_STOP; for ( list<recv_thread_t>::iterator it = comm_tcp_recv_threads.thread_list.begin(); it != comm_tcp_recv_threads.thread_list.end(); it++ ) { it->state = T_STATE_STOP; } // Close sockets threads are working with. // This gets the receiver threads and the listener thread off the blocking // accept() and recv() calls ::close( comm_tcp_listen_thread.sockfd ); ::close( comm_udp_recv_thread.sockfd ); for ( contact_list_t::iterator it = comm_contacts.begin(); it != comm_contacts.end(); it++ ) { comm_close_connection( it->second ); } for ( list<recv_thread_t>::iterator it = comm_tcp_recv_threads.thread_list.begin(); it != comm_tcp_recv_threads.thread_list.end(); it++ ) { ::close( it->sockfd ); } comm_tcp_recv_threads.mutex.unlock(); // Push an execution STOP message into the send and recv queues // This gets the receiver parser thread and the sending thread off the blocked // wait_and_pop() calls // msg_t terminate = create_msg( MSG_T_FINAL, 0, 0, 0, "" ); msg_t terminate; terminate.header = MSG_T_HALT; comm_recv_q.push( terminate ); comm_send_q.push( terminate ); return 0; }
void* comm_tcp_recv_thread_fun( void* data ) { list<recv_thread_t>::iterator my_info; char incoming_buf[512]; msg_t* incoming; wait_ms_duration( 100 ); // Locate this recv thread's info in the list bool found = false; do { comm_tcp_recv_threads.mutex.lock(); for ( my_info = comm_tcp_recv_threads.thread_list.begin(); my_info != comm_tcp_recv_threads.thread_list.end(); my_info++ ) { if ( pthread_equal( my_info->id, pthread_self() ) ) { found = true; break; } } comm_tcp_recv_threads.mutex.unlock(); } while ( !found ); // Receive loop // Communication hasn't been stopped while ( my_info->state == T_STATE_ACTIVE ) { int bytes = ::recv( my_info->sockfd, incoming_buf, sizeof(incoming_buf), 0 ); if ( bytes != sizeof(msg_t) ) { cout << "comm_tcp_recv_thread_fun DID NOT RECEIVE ENTIRE MESSAGE" << endl; } // Normal receive if ( bytes > 0 ) { incoming = reinterpret_cast<msg_t*>(incoming_buf); comm_recv_q.push( *incoming ); } // Connection closed from remote end else { cout << "comm_tcp_recv_thread_fun Terminating receive thread" << endl; ::close( my_info->sockfd ); comm_close_connection( comm_contacts[incoming->send_id] ); my_info->state = T_STATE_STOP; } } // Remove this thread from the recv_thread_ids comm_tcp_recv_threads.mutex.lock(); comm_tcp_recv_threads.thread_list.erase( my_info ); comm_tcp_recv_threads.mutex.unlock(); return NULL; }
int comm_stop() { // Mark all threads STOP comm_listen_thread_id.state = T_STATE_STOP; comm_recv_parse_thread_id.state = T_STATE_STOP; comm_send_thread_id.state = T_STATE_STOP; for ( unsigned int i = 0; i < comm_recv_thread_ids.size(); i++ ) { comm_recv_thread_ids[i].state = T_STATE_STOP; } // Close sockets threads are working with. // This gets the receiver threads and the listener thread off the blocking // accept() and recv() calls ::close( comm_listen_thread_id.sockfd ); for ( unsigned int i = 0; i < comm_recv_thread_ids.size(); i++ ) { ::close( comm_recv_thread_ids[i].sockfd ); } for ( contact_list_t::iterator it = comm_contacts.begin(); it != comm_contacts.end(); it++ ) { comm_close_connection( it->first ); } // Push an execution STOP message into the send and recv queues // This gets the receiver parser thread and the sending thread off the blocked // wait_and_pop() calls msg_t terminate; terminate.msg_type = MSG_T_TERMINATE; comm_recv_q.push( terminate ); comm_send_q.push( terminate ); // Join all threads pthread_join( comm_listen_thread_id.id, NULL ); pthread_join( comm_recv_parse_thread_id.id, NULL ); pthread_join( comm_send_thread_id.id, NULL ); for ( unsigned int i = 0; i < comm_recv_thread_ids.size(); i++ ) { pthread_join( comm_recv_thread_ids[i].id, NULL ); } return 0; }
void thread_recv() { while (connected.load()) { spmsg_t msg = std::make_shared<msg_t>(sizeof(uint32_t)); if (!_do_recv(msg->data(), sizeof(uint32_t))) return; uint32_t msg_len = *(uint32_t*)msg->data(); msg->resize(msg_len + sizeof(uint32_t)); *(uint32_t*)msg->data() = msg_len; if (!_do_recv(msg->data() + sizeof(uint32_t), msg_len)) return; recv_queue.push(std::move(msg)); } }
void* comm_udp_recv_thread_fun( void* data ) { int newfd = -1, error = 0; struct sockaddr remote_addr; socklen_t sin_size = sizeof(remote_addr); char incoming_buf[512]; msg_t* incoming; comm_udp_recv_thread.sockfd = comm_bind_once( comm_port, SOCK_DGRAM ); if ( comm_udp_recv_thread.sockfd < 0 ) { cout << "comm_udp_recv_thread_fun Couldn't bind to port " << comm_port << endl; return NULL; } // Recvfrom loop // Communication hasn't been stopped while ( comm_udp_recv_thread.state == T_STATE_ACTIVE ) { int bytes = ::recvfrom( comm_udp_recv_thread.sockfd, incoming_buf, sizeof(incoming_buf), 0, &remote_addr, &sin_size ); if ( bytes != sizeof(msg_t) ) { cout << "comm_udp_recv_thread_fun DID NOT RECEIVE ENTIRE MESSAGE" << endl; } // Normal receive if ( bytes > 0 ) { incoming = reinterpret_cast<msg_t*>(incoming_buf); comm_recv_q.push( *incoming ); } // Connection closed from remote end else { cout << "comm_udp_recv_thread_fun Terminating receive thread" << endl; ::close( comm_udp_recv_thread.sockfd ); comm_udp_recv_thread.state = T_STATE_STOP; } } return NULL; }
// Server interaction functions int comm_send( msg_t msg ) { msg.send_ID = NODE_INFO.id; comm_send_q.push( msg ); return 0; }
bool send(spmsg_t msg_) { send_queue.push(std::move(msg_)); return true; }