Cleanup poll handling events
[lttng-tools.git] / ltt-sessiond / main.c
index c9522d697f5cc698217b94dc495312af7ee9c7d2..77497d570b68e3e10aaf2a2386321ac66bd55d8c 100644 (file)
@@ -567,6 +567,8 @@ static int update_kernel_pollfd(void)
 
        /* Adding the quit pipe */
        kernel_pollfd[nb_fd - 1].fd = thread_quit_pipe[0];
+       kernel_pollfd[nb_fd - 1].events =
+               POLLHUP | POLLNVAL | POLLERR | POLLIN | POLLRDHUP | POLLPRI;
 
        return nb_fd;
 
@@ -667,6 +669,8 @@ static void *thread_manage_kernel(void *data)
                        goto error;
                } else if (ret == 0) {
                        /* Should not happen since timeout is infinite */
+                       ERR("Return value of poll is 0 with an infinite timeout.\n"
+                               "This should not have happened! Continuing...");
                        continue;
                }
 
@@ -860,6 +864,9 @@ static int update_apps_cmd_pollfd(unsigned int nb_fd, unsigned int old_nb_fd,
 
        /* First fd is always the quit pipe */
        (*pollfd)[0].fd = thread_quit_pipe[0];
+       (*pollfd)[0].events =
+               POLLHUP | POLLNVAL | POLLERR | POLLIN | POLLRDHUP | POLLPRI;
+
        /* Apps command pipe */
        (*pollfd)[1].fd = apps_cmd_pipe[0];
        (*pollfd)[1].events = POLLIN;
@@ -880,6 +887,16 @@ static int update_apps_cmd_pollfd(unsigned int nb_fd, unsigned int old_nb_fd,
                }
        }
 
+       if (nb_fd < 2) {
+               /*
+                * There should *always* be at least two fds in the pollfd. This safety
+                * check make sure the poll() will actually try on those two pipes at
+                * best which are the thread_quit_pipe and apps_cmd_pipe.
+                */
+               nb_fd = 2;
+               MSG("nb_fd < 2 --> Not good! Continuing...");
+       }
+
        /* Destroy old pollfd */
        free(old_pollfd);
 
@@ -1096,6 +1113,8 @@ static void *thread_registration_apps(void *data)
 
        /* First fd is always the quit pipe */
        pollfd[0].fd = thread_quit_pipe[0];
+       pollfd[0].events =
+               POLLHUP | POLLNVAL | POLLERR | POLLIN | POLLRDHUP | POLLPRI;
 
        /* Apps socket */
        pollfd[1].fd = apps_sock;
@@ -1122,59 +1141,66 @@ static void *thread_registration_apps(void *data)
                /* Thread quit pipe has been closed. Killing thread. */
                if (pollfd[0].revents == POLLNVAL) {
                        goto error;
-               } else if (pollfd[1].revents == POLLERR) {
-                       ERR("Register apps socket poll error");
-                       goto error;
                }
 
-               sock = lttcomm_accept_unix_sock(apps_sock);
-               if (sock < 0) {
+               switch (pollfd[1].revents) {
+               case POLLNVAL:
+               case POLLHUP:
+               case POLLRDHUP:
+               case POLLERR:
+                       ERR("Register apps socket poll error");
                        goto error;
-               }
+               case POLLIN:
+                       sock = lttcomm_accept_unix_sock(apps_sock);
+                       if (sock < 0) {
+                               goto error;
+                       }
 
-               /* Create UST registration command for enqueuing */
-               ust_cmd = malloc(sizeof(struct ust_command));
-               if (ust_cmd == NULL) {
-                       perror("ust command malloc");
-                       goto error;
-               }
+                       /* Create UST registration command for enqueuing */
+                       ust_cmd = malloc(sizeof(struct ust_command));
+                       if (ust_cmd == NULL) {
+                               perror("ust command malloc");
+                               goto error;
+                       }
 
-               /*
-                * Using message-based transmissions to ensure we don't have to deal
-                * with partially received messages.
-                */
-               ret = lttcomm_recv_unix_sock(sock, &ust_cmd->reg_msg,
-                               sizeof(struct ust_register_msg));
-               if (ret < 0 || ret < sizeof(struct ust_register_msg)) {
-                       if (ret < 0) {
-                               perror("lttcomm_recv_unix_sock register apps");
-                       } else {
-                               ERR("Wrong size received on apps register");
+                       /*
+                        * Using message-based transmissions to ensure we don't have to deal
+                        * with partially received messages.
+                        */
+                       ret = lttcomm_recv_unix_sock(sock, &ust_cmd->reg_msg,
+                                       sizeof(struct ust_register_msg));
+                       if (ret < 0 || ret < sizeof(struct ust_register_msg)) {
+                               if (ret < 0) {
+                                       perror("lttcomm_recv_unix_sock register apps");
+                               } else {
+                                       ERR("Wrong size received on apps register");
+                               }
+                               free(ust_cmd);
+                               close(sock);
+                               continue;
                        }
-                       free(ust_cmd);
-                       close(sock);
-                       continue;
-               }
 
-               ust_cmd->sock = sock;
+                       ust_cmd->sock = sock;
 
-               DBG("UST registration received with pid:%d ppid:%d uid:%d"
-                               " gid:%d sock:%d name:%s (version %d.%d)",
-                               ust_cmd->reg_msg.pid, ust_cmd->reg_msg.ppid,
-                               ust_cmd->reg_msg.uid, ust_cmd->reg_msg.gid,
-                               ust_cmd->sock, ust_cmd->reg_msg.name,
-                               ust_cmd->reg_msg.major, ust_cmd->reg_msg.minor);
-               /*
-                * Lock free enqueue the registration request.
-                * The red pill has been taken! This apps will be part of the *system*
-                */
-               cds_wfq_enqueue(&ust_cmd_queue.queue, &ust_cmd->node);
+                       DBG("UST registration received with pid:%d ppid:%d uid:%d"
+                                       " gid:%d sock:%d name:%s (version %d.%d)",
+                                       ust_cmd->reg_msg.pid, ust_cmd->reg_msg.ppid,
+                                       ust_cmd->reg_msg.uid, ust_cmd->reg_msg.gid,
+                                       ust_cmd->sock, ust_cmd->reg_msg.name,
+                                       ust_cmd->reg_msg.major, ust_cmd->reg_msg.minor);
+                       /*
+                        * Lock free enqueue the registration request.
+                        * The red pill has been taken! This apps will be part of the *system*
+                        */
+                       cds_wfq_enqueue(&ust_cmd_queue.queue, &ust_cmd->node);
 
-               /*
-                * Wake the registration queue futex.
-                * Implicit memory barrier with the exchange in cds_wfq_enqueue.
-                */
-               futex_nto1_wake(&ust_cmd_queue.futex);
+                       /*
+                        * Wake the registration queue futex.
+                        * Implicit memory barrier with the exchange in cds_wfq_enqueue.
+                        */
+                       futex_nto1_wake(&ust_cmd_queue.futex);
+                       break;
+               }
        }
 
 error:
@@ -2610,13 +2636,15 @@ static void *thread_manage_clients(void *data)
 
        /* First fd is always the quit pipe */
        pollfd[0].fd = thread_quit_pipe[0];
+       pollfd[0].events =
+               POLLHUP | POLLNVAL | POLLERR | POLLIN | POLLRDHUP | POLLPRI;
 
        /* Apps socket */
        pollfd[1].fd = client_sock;
        pollfd[1].events = POLLIN;
 
-       /* Notify parent pid that we are ready
-        * to accept command for client side.
+       /*
+        * Notify parent pid that we are ready to accept command for client side.
         */
        if (opt_sig_parent) {
                kill(ppid, SIGCHLD);
@@ -2635,63 +2663,69 @@ static void *thread_manage_clients(void *data)
                /* Thread quit pipe has been closed. Killing thread. */
                if (pollfd[0].revents == POLLNVAL) {
                        goto error;
-               } else if (pollfd[1].revents == POLLERR) {
-                       ERR("Client socket poll error");
-                       goto error;
                }
 
-               sock = lttcomm_accept_unix_sock(client_sock);
-               if (sock < 0) {
+               switch (pollfd[1].revents) {
+               case POLLNVAL:
+               case POLLHUP:
+               case POLLERR:
+                       ERR("Client socket poll error");
                        goto error;
-               }
+               case POLLIN:
+                       sock = lttcomm_accept_unix_sock(client_sock);
+                       if (sock < 0) {
+                               goto error;
+                       }
 
-               /* Allocate context command to process the client request */
-               cmd_ctx = malloc(sizeof(struct command_ctx));
+                       /* Allocate context command to process the client request */
+                       cmd_ctx = malloc(sizeof(struct command_ctx));
 
-               /* Allocate data buffer for reception */
-               cmd_ctx->lsm = malloc(sizeof(struct lttcomm_session_msg));
-               cmd_ctx->llm = NULL;
-               cmd_ctx->session = NULL;
+                       /* Allocate data buffer for reception */
+                       cmd_ctx->lsm = malloc(sizeof(struct lttcomm_session_msg));
+                       cmd_ctx->llm = NULL;
+                       cmd_ctx->session = NULL;
 
-               /*
-                * Data is received from the lttng client. The struct
-                * lttcomm_session_msg (lsm) contains the command and data request of
-                * the client.
-                */
-               DBG("Receiving data from client ...");
-               ret = lttcomm_recv_unix_sock(sock, cmd_ctx->lsm, sizeof(struct lttcomm_session_msg));
-               if (ret <= 0) {
-                       continue;
-               }
+                       /*
+                        * Data is received from the lttng client. The struct
+                        * lttcomm_session_msg (lsm) contains the command and data request of
+                        * the client.
+                        */
+                       DBG("Receiving data from client ...");
+                       ret = lttcomm_recv_unix_sock(sock, cmd_ctx->lsm, sizeof(struct lttcomm_session_msg));
+                       if (ret <= 0) {
+                               continue;
+                       }
 
-               // TODO: Validate cmd_ctx including sanity check for security purpose.
+                       // TODO: Validate cmd_ctx including sanity check for security purpose.
 
-               /*
-                * This function dispatch the work to the kernel or userspace tracer
-                * libs and fill the lttcomm_lttng_msg data structure of all the needed
-                * informations for the client. The command context struct contains
-                * everything this function may needs.
-                */
-               ret = process_client_msg(cmd_ctx);
-               if (ret < 0) {
-                       /* TODO: Inform client somehow of the fatal error. At this point,
-                        * ret < 0 means that a malloc failed (ENOMEM). */
-                       /* Error detected but still accept command */
-                       clean_command_ctx(&cmd_ctx);
-                       continue;
-               }
+                       /*
+                        * This function dispatch the work to the kernel or userspace tracer
+                        * libs and fill the lttcomm_lttng_msg data structure of all the needed
+                        * informations for the client. The command context struct contains
+                        * everything this function may needs.
+                        */
+                       ret = process_client_msg(cmd_ctx);
+                       if (ret < 0) {
+                               /* TODO: Inform client somehow of the fatal error. At this point,
+                                * ret < 0 means that a malloc failed (ENOMEM). */
+                               /* Error detected but still accept command */
+                               clean_command_ctx(&cmd_ctx);
+                               continue;
+                       }
 
-               DBG("Sending response (size: %d, retcode: %d)",
-                               cmd_ctx->lttng_msg_size, cmd_ctx->llm->ret_code);
-               ret = send_unix_sock(sock, cmd_ctx->llm, cmd_ctx->lttng_msg_size);
-               if (ret < 0) {
-                       ERR("Failed to send data back to client");
-               }
+                       DBG("Sending response (size: %d, retcode: %d)",
+                                       cmd_ctx->lttng_msg_size, cmd_ctx->llm->ret_code);
+                       ret = send_unix_sock(sock, cmd_ctx->llm, cmd_ctx->lttng_msg_size);
+                       if (ret < 0) {
+                               ERR("Failed to send data back to client");
+                       }
 
-               clean_command_ctx(&cmd_ctx);
+                       clean_command_ctx(&cmd_ctx);
 
-               /* End of transmission */
-               close(sock);
+                       /* End of transmission */
+                       close(sock);
+                       break;
+               }
        }
 
 error:
This page took 0.028107 seconds and 4 git commands to generate.