Beispiel #1
0
void* serve_client(void* vars)
{
	DIME_MSG* server_msg = (DIME_MSG*)malloc(sizeof(DIME_MSG));
	DIME_MSG* client_msg  = (DIME_MSG*)malloc(sizeof(DIME_MSG));
	THREAD* t_vars = vars;	


	static int thread_id = 0;
	thread_id++;
	
	int new_socketfd = t_vars->socket;
	char* ip = inet_ntoa(t_vars->client_addr.sin_addr);
	int state = STATE_READY;
	
	while(true)
	{
		if(!read_msg(client_msg, new_socketfd)) { printf("Client %s disconnected\n", ip); break; }

		if(state == STATE_READY)
		{
			if(client_msg->msg_type == HANDSHAKE_MSG)
			{
				state = STATE_CONNECTED;
				if(!create_msg(server_msg, HANDSHAKE_ACK, NULL, 0)) { error("Server failed to create proper response"); } //dont know how else to handle this
				printf("Handshake received from %s\n", ip);
				send_msg(server_msg, new_socketfd);
			}
			else
			{
				//trying to concat msg->payload which is 504 bytes is bad idea
				char message[] = "Error: Awaiting handshake before accepting requests";
				if(!create_msg(server_msg, ERROR_MSG, message, strlen(message))) { error("Server failed to create proper response");  }
				printf("Error Msg (%s) sent to %s\n", message, ip);
				printf("Closing connection with %s\n", ip);
				send_msg(server_msg, new_socketfd);
				break;
			}
		}
		else if(state == STATE_CONNECTED)
		{

			if(client_msg->msg_type == EXECUTE_MSG)
			{
				printf("%s requested execution of (%s)\n", ip, client_msg->payload);			

				if(!execute_targets(server_msg, new_socketfd, client_msg->payload, list))
				{
					printf("Closing connection with %s\n", ip);		
					break; 
				}
				create_msg(server_msg, EXECUTE_END, NULL, 0);
				send_msg(server_msg, new_socketfd);
			}
			else
			{
			
				char* message = "Error: Server only accepting execution messages";
				if(!create_msg(server_msg, ERROR_MSG, message, strlen(message))) { error("Server failed to create proper response"); }
				send_msg(server_msg, new_socketfd);
				printf("Error Msg (%s) sent to %s\n", message, ip);
				printf("Closing connection with %s\n", ip);
				break;
			}
		}
		else { error("Server in unknown state"); }
	}

	close_socket(new_socketfd);
	free(server_msg);
	free(client_msg);
	free(vars);
	return;
}
Beispiel #2
0
int main(int argc, char* argv[]) {
	// Declarations for getopt
	extern int optind;
	extern char* optarg;
	int ch;
	char* format = "f:hq:t:";
	
	// Variables you'll want to use
	char* filename = "Dimefile";
	
	int num_threads = 3;
	char* queue_size = "5";

	// Part 2.2.1: Use getopt code to take input appropriately.
	while((ch = getopt(argc, argv, format)) != -1) {
		switch(ch) {
			case 'f':
				filename = strdup(optarg);
				break;
			case 'h':
				dime_usage(argv[0]);
				break;
	        case 't':
	            num_threads = atoi(optarg);
	            if (num_threads < 1)
	            {
	                error("The number of helper threads must be at least 1.");
	            }
	            break;
	        case 'q':
	            queue_size = optarg;
	            if (atoi(queue_size) < 1)
	            {
	                error("The queue size must be at least 1.");
	            }
	            break;
		}
	}
	argc -= optind;
	argv += optind;
	
	//Set up queue for targets
	rule_node_t* rule_queue = (rule_node_t*)(malloc(sizeof(rule_node_t)));
	rule_node_t* output_queue = (rule_node_t*)(malloc(sizeof(rule_node_t)));
	//The first "real" entry of rule_queue is the second, so we can change it
	//while keeping the address of rule_queue constant
	rule_queue->rule = NULL;
	rule_queue->next = NULL;
	
	ARG_HOLDER argholder;
	argholder.rule_queue = rule_queue;
	argholder.output_queue = output_queue;
	argholder.max_queue_length = atoi(queue_size);
	argholder.threads_not_done = 0;
	argholder.finished_adding = 0;
	argholder.done = 0;
	
	pthread_mutex_init(&mutex, NULL);
	sem_init(&sem_lock, 0, 1);
	pthread_cond_init(&queue_full, NULL);
	pthread_cond_init(&queue_empty, NULL);
	pthread_cond_init(&finished_execution, NULL);
	
	//Set up threads
	PTHREAD_NODE* threads = NULL;
	int i;
	for (i = 0; i < num_threads; i++)
	{
	    pthread_t* thread = (pthread_t*)(malloc(sizeof(pthread_t)));
	    if (pthread_create(thread, NULL, helper_thread, (void*)(&argholder)) != 0)
	    {
	        error("Failed to create helper thread.");
	    }
	    else
	    {
	        PTHREAD_NODE* cur_node = (PTHREAD_NODE*)(malloc(sizeof(PTHREAD_NODE)));
	        cur_node->thread = thread;
	        cur_node->next = threads;
	        threads = cur_node;
	    }
	}

	// parse the given file, then execute targets
	rule_node_t* list = parse_file(filename);
	execute_targets(argc, argv, list, &argholder);
	rule_node_free(list);
	rule_queue_free(rule_queue);
	rule_queue_free(output_queue);
	
	//Rejoin threads
	PTHREAD_NODE* pthread_ptr = threads;
	while (pthread_ptr != NULL)
	{
        if (pthread_join(*(pthread_ptr->thread),NULL) != 0)
        {
            error("Couldn't join helper thread.");
        }
        else
        {
            printf("Joined helper thread.\n");
        }
        PTHREAD_NODE* temp = pthread_ptr;
        pthread_ptr = pthread_ptr->next;
        free(temp->thread);
        free(temp);
	}
	
	pthread_mutex_destroy(&mutex);
	sem_destroy(&sem_lock);
	pthread_cond_destroy(&queue_full);
	pthread_cond_destroy(&queue_empty);
	pthread_cond_destroy(&finished_execution);
	
	return 0;
}