// 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;
}
Esempio n. 2
0
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();
	
}
Esempio n. 3
0
/**
 * 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);
}
Esempio n. 4
0
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);
}
Esempio n. 5
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();
    }
Esempio n. 6
0
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;
}
Esempio n. 7
0
    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"
                );            
        }
    }