Example #1
0
struct queue_item *
queueitem_make_byquery(struct query_params *qp)
{
  struct db_media_file_info dbmfi;
  struct queue_item *item_head;
  struct queue_item *item_tail;
  struct queue_item *item_temp;
  int ret;

  ret = db_query_start(qp);
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_PLAYER, "Could not start query\n");
      return NULL;
    }

  DPRINTF(E_DBG, L_PLAYER, "Player queue query returned %d items\n", qp->results);

  item_head = NULL;
  item_tail = NULL;
  while (((ret = db_query_fetch_file(qp, &dbmfi)) == 0) && (dbmfi.id))
    {
      item_temp = queue_item_new(&dbmfi);
      if (!item_temp)
	{
	  DPRINTF(E_LOG, L_PLAYER, "Error creating new queue_item for id '%s'\n", dbmfi.id);
	  continue;
	}

      if (!item_head)
	item_head = item_temp;

      if (item_tail)
	{
	  item_tail->next = item_temp;
	  item_temp->prev = item_tail;
	  item_tail->shuffle_next = item_temp;
	  item_temp->shuffle_prev = item_tail;
	}

      item_tail = item_temp;

      DPRINTF(E_DBG, L_PLAYER, "Added song id %s (%s)\n", dbmfi.id, dbmfi.title);
    }

  db_query_end(qp);

  if (ret < 0)
    {
      DPRINTF(E_LOG, L_PLAYER, "Error fetching results\n");
      return NULL;
    }

  item_head->prev = item_tail;
  item_tail->next = item_head;
  item_head->shuffle_prev = item_tail;
  item_tail->shuffle_next = item_head;

  return item_head;
}
Example #2
0
int
main(int argc, char **argv)
{
    int i;

    /* Read input arguments */
    read_input_args(argc, argv);

    if (g_verbose > 1) {
        fprintf(stdout, "g_daemon = %d\n", g_daemon);
        fprintf(stdout, "g_udp_port = %d\n", g_udp_port);
        fprintf(stdout, "g_nr_working_threads = %d\n", g_nr_working_threads);
        fprintf(stdout, "g_queue_size = %d\n", g_queue_size);

        fprintf(stdout, "g_tcp_port = %d\n", g_tcp_port);
        fprintf(stdout, "g_tcp_ipv4_addr = %s\n", g_tcp_ipv4_addr);
        fprintf(stdout, "g_tcp_answer_timeout = %d\n", g_tcp_answer_timeout);
        fprintf(stdout, "g_tcp_conn_retry = %d\n", g_tcp_conn_retry);

        fprintf(stdout, "g_verbose = %d\n", g_verbose);
    }

    /* Daemonize server */
    if (g_daemon)
    {
        umask(0);

        int pid = fork();
        if (pid < 0)
            error_exit("%s", strerror(errno));
        else if (pid != 0)
            return 0;

        g_verbose = 0;
        setsid();
        chdir("/");

        close(0);
        close(1);
        close(2);

        open("/dev/null", O_RDWR);
        dup(0);
        dup(0);
    }

    /* Number of read bytes */
    int rb;

    /* UDP client IP, port, size and frame requested */
    struct sockaddr_in * from;
    socklen_t * fromlen;

    /* UDP server socket descriptor, local to the main thread  */
    int ussd = open_udp_server_socket();

    /* UDP server socket poll'ed */
    struct pollfd pfds[1];
    pfds[0].fd = ussd;
    pfds[0].events = POLLIN; /* Input event */

    /* Queue for each thread */
    struct queue * queues;
    queues = (struct queue *) malloc(g_nr_working_threads * sizeof(struct queue));
    if (queues == NULL)
        error_exit("Memory allocation failed!\n");

    for (i = 0; i < g_nr_working_threads; i++)
        queue_new(&queues[i], g_queue_size);

    /* Index of the next queue used to store the data of a new connection */
    int sel_queue = 0;

    /* Set of threads */
    pthread_t * consumers;
    consumers = (pthread_t *) malloc(g_nr_working_threads * sizeof(pthread_t));
    if (consumers == NULL)
        error_exit("Memory allocation failed!\n");

    for (i = 0; i < g_nr_working_threads; i++)
        pthread_create(&consumers[i], NULL, consumer_main, &queues[i]);


    // TODO it would be nice to manage some signal to break out this while
    while (1)
    {
        int rv = poll(pfds, 1, g_udp_timeout);

        /* poll error */
        if (rv == -1) {
            error_exit("syscall poll %s", strerror(errno));
        }

       /* poll timeout */
        else if (rv == 0) {
            if (g_verbose > 1)
                fprintf(stdout, "timeout expired\n");

        /* poll data ready */
        } else {

            if (pfds[0].revents & POLLIN) {
                if (g_verbose > 0)
                    fprintf(stdout, "MAIN: client request received\n");

                /* allocate resources for the client request */
                if (g_verbose > 1)
                    fprintf(stdout, "MAIN: allocating resources for the new request\n");

                char * req = (char *) malloc(UDP_FRAME_SIZE * sizeof(char));
                if (req == NULL)
                    error_exit("Memory allocation failed!\n");
                bzero(req, UDP_FRAME_SIZE * sizeof(char));

                from = (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in));
                if (from == NULL)
                    error_exit("Memory allocation failed!\n");
                bzero(from, sizeof(struct sockaddr));

                fromlen = (socklen_t *) malloc(sizeof(socklen_t));
                if (fromlen == NULL)
                    error_exit("Memory allocation failed!\n");
                bzero(fromlen, sizeof(socklen_t));
                *fromlen = sizeof(struct sockaddr_in); /* must be initialized again */

                /* receive incoming data */
                rb = recvfrom(ussd, /* udp socket descriptor */
                              &req[0], UDP_FRAME_SIZE-1, /* frame received and its size */
                              0, (struct sockaddr *)from, fromlen);

                if (g_verbose > 1)
                    fprintf(stdout, "MAIN: %s:%d --> recvfrom %d bytes\n",
                        inet_ntoa(from->sin_addr),
                        ntohs(from->sin_port),
                        rb);

                struct queue_item * item = (struct queue_item *) malloc(sizeof(struct queue_item));
                if (item == NULL)
                    error_exit("Memory allocation failed!\n");

                queue_item_new(item, req, rb, from, fromlen);

                /* Enqueue the new item in the proper queue */
                queue_head_add(&queues[sel_queue], item);

                /* Easier lock-free queue balancing */
                sel_queue = (sel_queue + 1) % g_nr_working_threads;

                if (g_verbose > 1) {
                    for (i = 0; i < g_nr_working_threads; i++) {
                        fprintf(stdout, "MAIN: == Thread number %d queue dumped ==\n", i);
                        queue_debug(&queues[i]);
                    }
                }
            }
        }
    }

    /* Wait all the threads before continuing */
    for (i = 0; i < g_nr_working_threads; i++)
        pthread_join(consumers[i], NULL);

    free(queues);
    free(consumers);
}