// Sets data for calling thread void pebil_set_data(pthread_key_t image_key, void* data){ pthread_t thread_id = pthread_self(); int err = pthread_setspecific(image_key, data); if( err ) { perror("pthread_set_specific:"); } struct thread_list * threadinfo = get_thread_data(thread_id); if( threadinfo == NULL ) { threadinfo = create_new_thread(thread_id); } struct data_list * curdata = threadinfo->datas; while(curdata != NULL){ if(curdata->image_id == image_key){ curdata->data = data; return; } } curdata = threadinfo->datas; threadinfo->datas = malloc(sizeof(struct data_list)); threadinfo->datas->image_id = image_key; threadinfo->datas->data = data; threadinfo->datas->next = curdata; }
void listen_to_connections() { /* Print status message */ pstatus("Start of the listen"); /* Start listen for connections */ listen(sock_fd, 5); /* Launch the main loop */ while(1) { /* Get the address length */ addr_size = sizeof(cli_addr); /* Accept connection */ client_fd = accept(sock_fd, (struct sockaddr*) &cli_addr, &addr_size); pstatus("New connection arrived"); /* Check if everything is correct */ if (client_fd < 0) { error("Error on socket accept"); } create_new_thread(client_fd); } terminate_connection(); }
/** * Initializes new thread, adds it to a list and starts serving connected clients. * @param targs Pointer to a structure containing arguments that will be used by the thread. * @param threads_list Pointer to a list holding threads. * @param threads_list_mutex Pointer to a mutex guarding threads list. * \sa thread_data_s threads_list_s */ void initialize_thread(thread_data_s *targs, threads_list_s *threads_list, pthread_mutex_t *threads_list_mutex) { pthread_t thread; pthread_attr_t attr; thread_s *threads = NULL; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if (pthread_create(&thread, &attr, thread_work, targs) != 0) { ERR("pthread_create"); } create_new_thread(&threads, thread, targs->game->id); pthread_mutex_lock(threads_list_mutex); add_thread_to_list(threads_list, threads); pthread_mutex_unlock(threads_list_mutex); pthread_attr_destroy(&attr); }
static int start_new_thread(struct thread *td, struct fmaster_thr_new_args *uap, const char *token, uint64_t token_size) { lwpid_t tid; int error; fmaster_start_thread_creating(td); error = create_new_thread(td, uap, &tid); fmaster_end_thread_creating(td); if (error != 0) return (error); error = fmaster_add_thread(td, tid, token, token_size); if (error != 0) return (error); return (0); }
void linker:: link ( connection& a, connection& b ) { // make sure requires clause is not broken DLIB_CASSERT( this->is_running() == false , "\tvoid linker::link" << "\n\tis_running() == " << this->is_running() << "\n\tthis: " << this ); running_mutex.lock(); running = true; running_mutex.unlock(); cons_mutex.lock(); A = &a; B = &b; cons_mutex.unlock(); service_connection_running_mutex.lock(); service_connection_running = true; service_connection_running_mutex.unlock(); service_connection_error_mutex.lock(); service_connection_error = false; service_connection_error_mutex.unlock(); // if we fail to make the thread if (!create_new_thread(service_connection,this)) { a.shutdown(); b.shutdown(); service_connection_running_mutex.lock(); service_connection_running = false; service_connection_running_mutex.unlock(); cons_mutex.lock(); A = 0; B = 0; cons_mutex.unlock(); running_mutex.lock(); running = false; running_mutex.unlock(); throw dlib::thread_error ( ECREATE_THREAD, "failed to make new thread in linker::link()" ); } // forward data from a to b char buf[200]; int status; bool error = false; // becomes true if one of the connections returns an error while (true) { status = a.read(buf,sizeof(buf)); // if there was an error reading from the socket if (status == OTHER_ERROR) { error = true; break; } else if (status == SHUTDOWN) { b.shutdown(); } if (status <= 0) { // if a has closed normally if (status == 0) b.shutdown_outgoing(); break; } status = b.write(buf,status); // if there was an error writing to the socket then break if (status == OTHER_ERROR) { error = true; break; } if (status <= 0) break; } // if there was an error then shutdown both connections if (error) { a.shutdown(); b.shutdown(); } // wait for the other thread to end service_connection_running_mutex.lock(); while(service_connection_running) { service_connection_running_signaler.wait(); } service_connection_running_mutex.unlock(); // make sure connections are shutdown a.shutdown(); b.shutdown(); // both threads have ended so the connections are no longer needed cons_mutex.lock(); A = 0; B = 0; cons_mutex.unlock(); // if service_connection terminated due to an error then set error to true service_connection_error_mutex.lock(); if (service_connection_error) error = true; service_connection_error_mutex.unlock(); // if we are ending because of an error if (error) { // signal that the link() function is ending running_mutex.lock(); running = false; running_signaler.broadcast(); running_mutex.unlock(); // throw the exception for this error throw dlib::socket_error ( ECONNECTION, "a connection returned an error in linker::link()" ); } // signal that the link() function is ending running_mutex.lock(); running = false; running_signaler.broadcast(); running_mutex.unlock(); }
int main( int argc, char *argv[] ) { hthread_t d_id[ MAIN_LOOP_ITERATIONS ]; Huint d_ctr[ MAIN_LOOP_ITERATIONS ]; hthread_t j_id[ CONCURRENT_THREADS ]; Huint j_ctr[ CONCURRENT_THREADS ]; Huint cmd_status; uint i, j, ctr, rejoin_index; ctr = 0; for( i = 0; i < MAIN_LOOP_ITERATIONS; i++ ) { d_ctr[i] = ctr; d_id[i] = create_new_thread(ctr, Htrue); printf("Created detached thread: "); printf("(TID= %u) (CTR= %u)\n", d_id[i], d_ctr[i]); ctr++; for( j = 0; j < CONCURRENT_THREADS; j++ ) { j_id[j] = create_new_thread(ctr, Hfalse); j_ctr[j] = ctr; printf("Created joinable thread: "); printf("(TID= %u) (CTR= %u)\n", j_id[j], j_ctr[j]); ctr++; } // Attempt to join, a detached thread. // EXPECT an error. cmd_status = hthread_join( d_id[j], NULL ); if (cmd_status == 0) { printf("??? Successfully joined DETACHED thread: "); printf("(TID= %u) (CTR= %u)\n", d_id[i], d_ctr[i]); } else { printf("EXPECTED error: %x, when joining DETACHED thread:", cmd_status); printf("(TID= %u) (CTR= %u)\n", d_id[i], d_ctr[i]); } for( j = 0; j < CONCURRENT_THREADS; j++ ) { cmd_status = hthread_join( j_id[j], NULL ); printf("Joined Thread: "); printf("(TID= %u) (CTR= %u)\n", j_id[j], j_ctr[j]); } // Attempt to join a thread a second time. // EXPECT an error. rejoin_index = 0; cmd_status = hthread_join( j_id[rejoin_index], NULL ); if (cmd_status == 0) { printf("??? Successfully joined a SECOND TIME thread: "); printf("(TID= %u) (CTR= %u)\n", j_id[rejoin_index], j_ctr[rejoin_index]); } else { printf("EXPECTED error: %u, when RE-joining thread:", cmd_status); printf("(TID= %u) (CTR= %u)\n", j_id[rejoin_index], j_ctr[rejoin_index]); } } return 1; }
void server:: start_accepting_connections ( ) { open_listening_socket(); // determine the listening port bool port_assigned = false; listening_port_mutex.lock(); if (listening_port == 0) { port_assigned = true; listening_port = sock->get_listening_port(); } listening_port_mutex.unlock(); if (port_assigned) on_listening_port_assigned(); int status = 0; connection* client; bool exit = false; while ( true ) { // accept the next connection status = sock->accept(client,1000); // if there was an error then quit the loop if (status == OTHER_ERROR) { break; } shutting_down_mutex.lock(); // if we are shutting down then signal that we should quit the loop exit = shutting_down; shutting_down_mutex.unlock(); // if we should be shutting down if (exit) { // if a connection was opened then close it if (status == 0) delete client; break; } // if the accept timed out if (status == TIMEOUT) { continue; } // add this new connection to cons cons_mutex.lock(); connection* client_temp = client; try{cons.add(client_temp);} catch(...) { sock.reset(); delete client; cons_mutex.unlock(); // signal that we are not running start() anymore running_mutex.lock(); running = false; running_signaler.broadcast(); running_mutex.unlock(); clear(); throw; } cons_mutex.unlock(); // make a param structure param* temp = 0; try{ temp = new param ( *this, *client, get_graceful_close_timeout() ); } catch (...) { sock.reset(); delete client; running_mutex.lock(); running = false; running_signaler.broadcast(); running_mutex.unlock(); clear(); throw; } // if create_new_thread failed if (!create_new_thread(service_connection,temp)) { delete temp; // close the listening socket sock.reset(); // close the new connection and remove it from cons cons_mutex.lock(); connection* ctemp; if (cons.is_member(client)) { cons.remove(client,ctemp); } delete client; cons_mutex.unlock(); // signal that the listener has closed running_mutex.lock(); running = false; running_signaler.broadcast(); running_mutex.unlock(); // make sure the object is cleared clear(); // throw the exception throw dlib::thread_error( ECREATE_THREAD, "error occurred in server::start()\nunable to start thread" ); } // if we made the new thread then update thread_count else { // increment the thread count thread_count_mutex.lock(); ++thread_count; if (thread_count == 0) thread_count_zero.broadcast(); thread_count_mutex.unlock(); } // check if we have hit the maximum allowed number of connections max_connections_mutex.lock(); // if max_connections is zero or the loop is ending then skip this if (max_connections != 0) { // wait for thread_count to be less than max_connections thread_count_mutex.lock(); while (thread_count >= max_connections) { max_connections_mutex.unlock(); thread_count_signaler.wait(); max_connections_mutex.lock(); // if we are shutting down the quit the loop shutting_down_mutex.lock(); exit = shutting_down; shutting_down_mutex.unlock(); if (exit) break; } thread_count_mutex.unlock(); } max_connections_mutex.unlock(); if (exit) { break; } } //while ( true ) // close the socket sock.reset(); // signal that the listener has closed running_mutex.lock(); running = false; running_signaler.broadcast(); running_mutex.unlock(); // if there was an error with accept then throw an exception if (status == OTHER_ERROR) { // make sure the object is cleared clear(); // throw the exception throw dlib::socket_error( "error occurred in server::start()\nlistening socket returned error" ); } }