void exampleQueue() { // Use pooling for efficiency, if you don't want to use pooling // then comment out this line. pool_queue(16); Queue* Q = newQueue(); // A queue with strings queue_offer(Q, "First"); queue_offer(Q, "In"); queue_offer(Q, "First"); queue_offer(Q, "Out."); // Peek at the head of the queue printf("%s\n", (char*)queue_peek(Q)); // Traverse through the queue polling each string while (!queue_isEmpty(Q)) printf("%s ", (char*)queue_poll(Q)); printf("\n"); // A queue with integers, primitive data types require some trickyness queue_clear(Q); int x[] = {1, 2}; int y = 3; queue_offer(Q, &x[0]); queue_offer(Q, &x[1]); queue_offer(Q, &y); while (!queue_isEmpty(Q)) // You first need to cast it using (int*) and since its a pointer to // an integer you need to get the value of the pointer using * // You could similarly use: // int* z = queue_poll(Q); // printf("%d ", *z); printf("%d ", *((int*)queue_poll(Q))); printf("\n"); // This will clear the queue of any nodes and pool them and then free // the queue itself from memory queue_free(Q); // If you're not using pooling this can be commented out. This will // free all pooled nodes from memory. Always call this at the end // of using any Queue. unpool_queue(); }
static void * handle_requests (struct daemon *daemon) { /* The message typed by the user */ char *message = NULL; struct daemon_request *r; struct pool *pool; void* (*handler) (void *); for (;;) { message = socket_getline (daemon->socket); if (!message) break; /* Only request we're allowed to treat no matter how many requests are * currently being treated */ if (strncmp (message, "quit", 4) == 0) break; sem_wait (&daemon->req_lock); if (daemon->nb_requests == prefs->max_requests_per_daemon) { sem_post (&daemon->req_lock); /* FIXME: this is copy-paste from client, should be different */ daemon_send (daemon, " < Too many requests, mister, plz calm down\n"); continue; } sem_post (&daemon->req_lock); /* Treating all the common requests */ /* FIXME : use the IS_CMD macro */ pool = fast_pool; #if 0 if (strncmp (message, "list", 4) == 0) { pool = slow_pool; handler = daemon_request_list; } else if (strncmp (message, "get", 3) == 0) handler = daemon_request_get; else if (strncmp (message, "file", 4) == 0) handler = daemon_request_file; else if (strncmp (message, "neighbourhood", 13) == 0) handler = daemon_request_neighbourhood; else if (strncmp (message, "neighbour", 9) == 0) handler = daemon_request_neighbour; else if (strncmp (message, "ready", 5) == 0) handler = daemon_request_ready; #endif if (IS_CMD (message, "list")) { pool = slow_pool; handler = &daemon_request_list; } else if (IS_CMD (message, "get")) handler = &daemon_request_get; else if (IS_CMD (message, "file")) handler = &daemon_request_file; else if (IS_CMD (message, "neighbourhood")) handler = &daemon_request_neighbourhood; else if (IS_CMD (message, "neighbour")) handler = &daemon_request_neighbour; else if (IS_CMD (message, "ready")) handler = &daemon_request_ready; else handler = daemon_request_unknown; r = daemon_request_new (message, daemon, pool, handler); if (!r) { daemon_send (daemon, " < Failed to create a new request\n"); continue; } sem_wait (&daemon->req_lock); daemon->requests = daemon_request_add (daemon->requests, r); if (!daemon->requests) { daemon_request_free (r); break; } sem_post (&daemon->req_lock); pool_queue (r->pool, daemon_request_handler, r); } if (message) free (message); return NULL; }
static void start_server (void) { int client_sd; int daemon_sd; int connected_sd; struct sockaddr_in client_sa; struct sockaddr_in daemon_sa; struct sockaddr_in connected_sa; socklen_t size; fd_set socket_set; int nfds; struct ifreq if_info; struct sockaddr_in *if_addr; char addr[INET_ADDRSTRLEN]; struct client *c; struct daemon *d; struct parsed_cmd *pcmd = NULL; char *ident_msg; int port; char *colon; /* Prepare all the threads */ slow_pool = NULL; fast_pool = NULL; clients_pool = NULL; daemons_pool = NULL; ABORT_IF (!(slow_pool = pool_create (prefs->nb_proc)), "Unable to create slow_pool") ABORT_IF (!(fast_pool = pool_create (prefs->nb_proc)), "Unable to create fast_pool") ABORT_IF (!(clients_pool = pool_create (prefs->max_clients)), "Unable to create clients_pool") ABORT_IF (!(daemons_pool = pool_create (prefs->max_daemons)), "Unable to create daemons_pool") /* Create the shared directory if it does not exist already */ ABORT_IF (create_dir (prefs->shared_folder, (mode_t)0755) < 0, "Unable to create shared directory") /* Initialize global pointers and their semaphores */ clients = NULL; ABORT_IF (sem_init (&clients_lock, 0, 1) < 0, "Unable to sem_init clients_lock") daemons = NULL; ABORT_IF (sem_init (&daemons_lock, 0, 1) < 0, "Unable to sem_init daemons_lock") file_cache = NULL; ABORT_IF (sem_init (&file_cache_lock, 0, 1) < 0, "Unable to sem_init file_cache_lock") list_client = NULL; ABORT_IF (sem_init (&list_lock, 0, 1) < 0, "Unable to sem_init list_lock") downloads = NULL; ABORT_IF (sem_init (&downloads_lock, 0, 1) < 0, "Unable to sem_init download_queue_lock") client_sa.sin_family = AF_INET; client_sa.sin_addr.s_addr = INADDR_ANY; client_sa.sin_port = htons (prefs->client_port); client_sd = socket_init (&client_sa); ABORT_IF (client_sd < 0, "Unable to socket_init client_sd") daemon_sa.sin_family = AF_INET; daemon_sa.sin_addr.s_addr = INADDR_ANY; daemon_sa.sin_port = htons (prefs->daemon_port); daemon_sd = socket_init (&daemon_sa); ABORT_IF (daemon_sd < 0, "Unable to socket_init daemon_sd") #if 1 /* We get our ip */ memcpy (if_info.ifr_name, prefs->interface, strlen (prefs->interface) + 1); if (ioctl (daemon_sd, SIOCGIFADDR, &if_info) == -1) { log_failure (log_file, "Can't get my ip from interface"); log_failure (log_file, "LOL ERRNO : %s\n", strerror (errno)); goto abort; } if_addr = (struct sockaddr_in *)&if_info.ifr_addr; inet_ntop (AF_INET, &if_addr->sin_addr, my_ip, INET_ADDRSTRLEN); log_success (log_file, "Found my IP : %s", my_ip); #endif /* socket_set contains both client_sd and daemon_sd */ FD_ZERO (&socket_set); size = sizeof (connected_sa); nfds = NFDS (client_sd, daemon_sd); for (;;) { /* * It is VERY important to FD_SET at each loop, because select * will FD_UNSET the socket descriptors */ FD_SET (client_sd, &socket_set); FD_SET (daemon_sd, &socket_set); /* Block until a socket is ready to accept */ if (select (nfds, &socket_set, NULL, NULL, NULL) < 0) { log_failure (log_file, "main () : select failed"); } if (FD_ISSET (client_sd, &socket_set)) { if ((connected_sd = (accept (client_sd, (struct sockaddr *) &connected_sa, &size))) < 0) { log_failure (log_file, "Failed to accept incoming connection."); break; } /* Can we handle this client? */ if (client_count () > prefs->max_clients) { socket_sendline (connected_sd, " < Too many clients\n"); goto close_socket; } /* Then, let's handle him */ if (!inet_ntop (AF_INET, &connected_sa.sin_addr, addr, INET_ADDRSTRLEN)) { socket_sendline (connected_sd, " < Oops\n"); goto close_socket; } if (!(c = client_new (connected_sd, addr))) { socket_sendline (connected_sd, " < Sorry pal :(\n"); } pool_queue (clients_pool, handle_client, c); } else if (FD_ISSET (daemon_sd, &socket_set)) { if ((connected_sd = (accept (daemon_sd, (struct sockaddr *) &connected_sa, &size))) < 0) { log_failure (log_file, "Failed to accept incoming connection."); break; } /* Can we handle this daemon? */ if (daemon_count () > prefs->max_daemons) { socket_sendline (connected_sd, " < Too many daemons\n"); goto close_socket; } /* Let's identify him first */ ident_msg = socket_try_getline (connected_sd, IDENTIFICATION_TIMEOUT); if (!ident_msg) { socket_sendline (connected_sd, "error: identification timed out\n"); goto close_socket; } if (cmd_parse_failed ((pcmd = cmd_parse (ident_msg, NULL)))) { pcmd = NULL; goto close_socket; } if (pcmd->argc < 2) goto close_socket; if (strcmp (pcmd->argv[0], "neighbour") != 0) goto close_socket; if (!(colon = strchr (pcmd->argv[1], ':'))) goto close_socket; port = atoi (colon + 1); free (ident_msg); cmd_parse_free (pcmd); pcmd = NULL; if (!inet_ntop (AF_INET, &connected_sa.sin_addr, addr, INET_ADDRSTRLEN)) { socket_sendline (connected_sd, " < Oops\n"); goto close_socket; } /* Now we've got his port, let him go in */ if (!(d = daemon_new (connected_sd, addr, port))) { socket_sendline (connected_sd, " < Sorry pal :(\n"); goto close_socket; } pool_queue (daemons_pool, handle_daemon, d); } else { /* This should never happen : neither client nor daemon!? */ log_failure (log_file, "Unknown connection"); } continue; close_socket: if (pcmd) { cmd_parse_free (pcmd); pcmd = NULL; } close (connected_sd); } abort: if (slow_pool) pool_destroy (slow_pool); if (fast_pool) pool_destroy (fast_pool); if (clients_pool) pool_destroy (clients_pool); if (daemons_pool) pool_destroy (daemons_pool); conf_free (prefs); exit (EXIT_FAILURE); }