Database/server.c
void *run_client(void *arg) {
    // TODO:
    // Step 1: Make sure that the server is still accepting clients.
    client_t* new_client = (client_t*)arg;
    new_client->thread = pthread_self();
    
	pthread_mutex_lock (&thread_list_mutex);
    // Step 2: Add client to the client list and push thread_cleanup to remove
    //       it if the thread is canceled.
	new_client->thread = pthread_self();
    	if(thread_list_head == NULL) {
		thread_list_head = new_client;
		new_client->prev = NULL;
		new_client->next = NULL;
	}
	else {
		new_client->next = thread_list_head;
		thread_list_head->prev = new_client;
		new_client->prev = NULL;
		thread_list_head = new_client;
	}
    pthread_cleanup_push(thread_cleanup, new_client);

	pthread_mutex_unlock (&thread_list_mutex);
	// Increase the number of client threads.
	pthread_mutex_lock (&(sct.server_mutex));
	sct.num_client_threads++;
	pthread_mutex_unlock (&(sct.server_mutex));
    // Step 3: Loop comm_serve (in comm.c) to receive commands and output
    //       responses. Note that the client may terminate the connection at
    //       any moment, in which case reading/writing to the connection stream
    //       on the server side will send this process a SIGPIPE. You must
    //       ensure that the server doesn't crash when this happens!
	signal(SIGPIPE, SIG_IGN);
  
    char response[1024];
	char command[1024];
  
	while(1) {
		client_control_wait();
		if(comm_serve(new_client->cxstr, response, command) == 0) {
			// got a command.
			interpret_command(command, response, 1024);
		}
		else {
			break;
		}
	}
	return NULL;

    // Step 4: When the client is done sending commands, exit the thread
    //       cleanly.
	client_destructor(new_client);
    // Keep the signal handler thread in mind when writing this function!
	pthread_cleanup_pop(1);
    return NULL;
}
// Code executed by a client thread
Code executed by a client thread
Code executed by a client thread
void *run_client(void *arg) {
    client_t* new_client = (client_t*)arg;
    new_client->thread = pthread_self();
	pthread_mutex_lock (&thread_list_mutex);
	new_client->thread = pthread_self();
    	if(thread_list_head == NULL) {
		thread_list_head = new_client;
		new_client->prev = NULL;
		new_client->next = NULL;
	}
	else {
		new_client->next = thread_list_head;
		thread_list_head->prev = new_client;
		new_client->prev = NULL;
		thread_list_head = new_client;
	}
    pthread_cleanup_push(thread_cleanup, new_client);
	pthread_mutex_unlock (&thread_list_mutex);
	pthread_mutex_lock (&(sct.server_mutex));
	sct.num_client_threads++;
	pthread_mutex_unlock (&(sct.server_mutex));
	signal(SIGPIPE, SIG_IGN);
    char response[1024];
	char command[1024];
	while(1) {
		client_control_wait();
		if(comm_serve(new_client->cxstr, response, command) == 0) {
			interpret_command(command, response, 1024);
		}
		else {
			break;
		}
	}
	return NULL;
	client_destructor(new_client);
	pthread_cleanup_pop(1);
    return NULL;
}
void * run_client ( void * arg ) { client_t * new_client = ( client_t * ) arg ; new_client -> thread = pthread_self ( ) ; pthread_mutex_lock ( & thread_list_mutex ) ; new_client -> thread = pthread_self ( ) ; if ( thread_list_head == NULL ) { thread_list_head = new_client ; new_client -> prev = NULL ; new_client -> next = NULL ; } else { new_client -> next = thread_list_head ; thread_list_head -> prev = new_client ; new_client -> prev = NULL ; thread_list_head = new_client ; } pthread_cleanup_push ( thread_cleanup , new_client ) ; pthread_mutex_unlock ( & thread_list_mutex ) ; pthread_mutex_lock ( & ( sct . server_mutex ) ) ; sct . num_client_threads ++ ; pthread_mutex_unlock ( & ( sct . server_mutex ) ) ; signal ( SIGPIPE , SIG_IGN ) ; char response [ 1024 ] ; char command [ 1024 ] ; while ( 1 ) { client_control_wait ( ) ; if ( comm_serve ( new_client -> cxstr , response , command ) == 0 ) { interpret_command ( command , response , 1024 ) ; } else { break ; } } return NULL ; client_destructor ( new_client ) ; pthread_cleanup_pop ( 1 ) ; return NULL ; }
Code executed by a client thread
Code executed by a client thread
// TODO: // Step 1: Make sure that the server is still accepting clients. // Step 2: Add client to the client list and push thread_cleanup to remove //       it if the thread is canceled. // Increase the number of client threads. // Step 3: Loop comm_serve (in comm.c) to receive commands and output //       responses. Note that the client may terminate the connection at //       any moment, in which case reading/writing to the connection stream //       on the server side will send this process a SIGPIPE. You must //       ensure that the server doesn't crash when this happens! // got a command. // Step 4: When the client is done sending commands, exit the thread //       cleanly. // Keep the signal handler thread in mind when writing this function!