Exemplo n.º 1
0
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();
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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);
}