+
+ while (1) {
+ /* Zeroed the events structure */
+ lttng_poll_reset(&events);
+
+ nb_fd = LTTNG_POLL_GETNB(&events);
+
+ DBG("Apps thread polling on %d fds", nb_fd);
+
+ /* Inifinite blocking call, waiting for transmission */
+ ret = lttng_poll_wait(&events, -1);
+ if (ret < 0) {
+ goto error;
+ }
+
+ for (i = 0; i < nb_fd; i++) {
+ /* Fetch once the poll data */
+ revents = LTTNG_POLL_GETEV(&events, i);
+ pollfd = LTTNG_POLL_GETFD(&events, i);
+
+ /* Thread quit pipe has been closed. Killing thread. */
+ ret = check_thread_quit_pipe(pollfd, revents);
+ if (ret) {
+ goto error;
+ }
+
+ /* Inspect the apps cmd pipe */
+ if (pollfd == apps_cmd_pipe[0]) {
+ if (revents & (LPOLLERR | LPOLLHUP | LPOLLRDHUP)) {
+ ERR("Apps command pipe error");
+ goto error;
+ } else if (revents & LPOLLIN) {
+ /* Empty pipe */
+ ret = read(apps_cmd_pipe[0], &ust_cmd, sizeof(ust_cmd));
+ if (ret < 0 || ret < sizeof(ust_cmd)) {
+ perror("read apps cmd pipe");
+ goto error;
+ }
+
+ /* Register applicaton to the session daemon */
+ ret = ust_app_register(&ust_cmd.reg_msg,
+ ust_cmd.sock);
+ if (ret < 0) {
+ /* Only critical ENOMEM error can be returned here */
+ goto error;
+ }
+
+ ret = ustctl_register_done(ust_cmd.sock);
+ if (ret < 0) {
+ /*
+ * If the registration is not possible, we simply
+ * unregister the apps and continue
+ */
+ ust_app_unregister(ust_cmd.sock);
+ } else {
+ /*
+ * We just need here to monitor the close of the UST
+ * socket and poll set monitor those by default.
+ */
+ ret = lttng_poll_add(&events, ust_cmd.sock, 0);
+ if (ret < 0) {
+ goto error;
+ }
+
+ DBG("Apps with sock %d added to poll set",
+ ust_cmd.sock);
+ }
+ break;
+ }
+ } else {
+ /*
+ * At this point, we know that a registered application made
+ * the event at poll_wait.
+ */
+ if (revents & (LPOLLERR | LPOLLHUP | LPOLLRDHUP)) {
+ /* Removing from the poll set */
+ ret = lttng_poll_del(&events, pollfd);
+ if (ret < 0) {
+ goto error;
+ }
+
+ /* Socket closed */
+ ust_app_unregister(pollfd);
+ break;
+ }
+ }
+ }