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; }
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; }