+ /*
+ * Create the thread to manage the UST metadata periodic timer and
+ * live timer.
+ */
+ ret = pthread_create(&metadata_timer_thread, NULL,
+ consumer_timer_thread, (void *) ctx);
+ if (ret) {
+ errno = ret;
+ PERROR("pthread_create");
+ retval = -1;
+ goto exit_metadata_timer_thread;
+ }
+
+ ret = pthread_detach(metadata_timer_thread);
+ if (ret) {
+ errno = ret;
+ PERROR("pthread_detach");
+ retval = -1;
+ goto exit_metadata_timer_detach;
+ }
+
+ /*
+ * This is where we start awaiting program completion (e.g. through
+ * signal that asks threads to teardown.
+ */
+
+exit_metadata_timer_detach:
+exit_metadata_timer_thread:
+ ret = pthread_join(sessiond_thread, &status);
+ if (ret) {
+ errno = ret;
+ PERROR("pthread_join sessiond_thread");
+ retval = -1;
+ }
+exit_sessiond_thread:
+
+ ret = pthread_join(data_thread, &status);
+ if (ret) {
+ errno = ret;
+ PERROR("pthread_join data_thread");
+ retval = -1;
+ }
+exit_data_thread:
+
+ ret = pthread_join(metadata_thread, &status);
+ if (ret) {
+ errno = ret;
+ PERROR("pthread_join metadata_thread");
+ retval = -1;
+ }
+exit_metadata_thread:
+
+ ret = pthread_join(channel_thread, &status);
+ if (ret) {
+ errno = ret;
+ PERROR("pthread_join channel_thread");
+ retval = -1;
+ }
+exit_channel_thread:
+
+ ret = pthread_join(health_thread, &status);
+ if (ret) {
+ errno = ret;
+ PERROR("pthread_join health_thread");
+ retval = -1;
+ }
+exit_health_thread:
+
+ utils_close_pipe(health_quit_pipe);
+exit_health_pipe:
+
+exit_init_data:
+ tmp_ctx = ctx;
+ ctx = NULL;
+ cmm_barrier(); /* Clear ctx for signal handler. */
+ lttng_consumer_destroy(tmp_ctx);