+error:
+ DBG("Application communication apps dying");
+ close(apps_cmd_pipe[0]);
+ close(apps_cmd_pipe[1]);
+
+ lttng_poll_clean(&events);
+
+ return NULL;
+}
+
+/*
+ * Dispatch request from the registration threads to the application
+ * communication thread.
+ */
+static void *thread_dispatch_ust_registration(void *data)
+{
+ int ret;
+ struct cds_wfq_node *node;
+ struct ust_command *ust_cmd = NULL;
+
+ DBG("[thread] Dispatch UST command started");
+
+ while (!dispatch_thread_exit) {
+ /* Atomically prepare the queue futex */
+ futex_nto1_prepare(&ust_cmd_queue.futex);
+
+ do {
+ /* Dequeue command for registration */
+ node = cds_wfq_dequeue_blocking(&ust_cmd_queue.queue);
+ if (node == NULL) {
+ DBG("Waked up but nothing in the UST command queue");
+ /* Continue thread execution */
+ break;
+ }
+
+ ust_cmd = caa_container_of(node, struct ust_command, node);
+
+ DBG("Dispatching UST registration 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);
+ /*
+ * Inform apps thread of the new application registration. This
+ * call is blocking so we can be assured that the data will be read
+ * at some point in time or wait to the end of the world :)
+ */
+ ret = write(apps_cmd_pipe[1], ust_cmd,
+ sizeof(struct ust_command));
+ if (ret < 0) {
+ perror("write apps cmd pipe");
+ if (errno == EBADF) {
+ /*
+ * We can't inform the application thread to process
+ * registration. We will exit or else application
+ * registration will not occur and tracing will never
+ * start.
+ */
+ goto error;
+ }
+ }
+ free(ust_cmd);
+ } while (node != NULL);
+
+ /* Futex wait on queue. Blocking call on futex() */
+ futex_nto1_wait(&ust_cmd_queue.futex);
+ }
+
+error:
+ DBG("Dispatch thread dying");
+ return NULL;
+}
+
+/*
+ * This thread manage application registration.
+ */
+static void *thread_registration_apps(void *data)
+{
+ int sock = 0, i, ret, pollfd;
+ uint32_t revents, nb_fd;
+ struct lttng_poll_event events;
+ /*
+ * Get allocated in this thread, enqueued to a global queue, dequeued and
+ * freed in the manage apps thread.
+ */
+ struct ust_command *ust_cmd = NULL;
+
+ DBG("[thread] Manage application registration started");
+
+ ret = lttcomm_listen_unix_sock(apps_sock);
+ if (ret < 0) {
+ goto error;
+ }
+
+ /*
+ * Pass 2 as size here for the thread quit pipe and apps socket. Nothing
+ * more will be added to this poll set.
+ */
+ ret = create_thread_poll_set(&events, 2);
+ if (ret < 0) {
+ goto error;
+ }
+
+ /* Add the application registration socket */
+ ret = lttng_poll_add(&events, apps_sock, LPOLLIN | LPOLLRDHUP);
+ if (ret < 0) {
+ goto error;
+ }
+
+ /* Notify all applications to register */
+ ret = notify_ust_apps(1);
+ if (ret < 0) {
+ ERR("Failed to notify applications or create the wait shared memory.\n"
+ "Execution continues but there might be problem for already\n"
+ "running applications that wishes to register.");
+ }
+
+ while (1) {
+ DBG("Accepting application registration");
+
+ nb_fd = LTTNG_POLL_GETNB(&events);
+
+ /* Inifinite blocking call, waiting for transmission */
+ ret = lttng_poll_wait(&events, -1);