fix race on startup and support for cpu hotplug
[lttngtop.git] / src / lttngtop.c
index 7d89e5c8af12896dcc38eb36cf79251bed207cfd..9b650f4bddc5b43926bf318ba6961d1b591caf7c 100644 (file)
 const char *opt_input_path;
 int opt_textdump;
 
+int quit = 0;
+
 struct lttngtop *copy;
 pthread_t display_thread;
 pthread_t timer_thread;
 
 unsigned long refresh_display = 1 * NSEC_PER_SEC;
 unsigned long last_display_update = 0;
-int quit = 0;
 
 /* list of FDs available for being read with snapshots */
 struct mmap_stream_list mmap_list;
@@ -69,9 +70,7 @@ struct lttng_consumer_local_data *ctx = NULL;
 /* list of snapshots currently not consumed */
 GPtrArray *available_snapshots;
 sem_t metadata_available;
-FILE *metadata_fp;
-int trace_opened = 0;
-int metadata_ready = 0;
+int reload_trace = 0;
 
 enum {
        OPT_NONE = 0,
@@ -91,8 +90,12 @@ void *refresh_thread(void *p)
        struct mmap_stream *mmap_info;
 
        while (1) {
-               if (quit)
-                       return NULL;
+               if (quit) {
+                       sem_post(&pause_sem);
+                       sem_post(&timer);
+                       sem_post(&goodtodisplay);
+                       pthread_exit(0);
+               }
                bt_list_for_each_entry(mmap_info, &mmap_list.head, list)
                        helper_kernctl_buffer_flush(mmap_info->fd);
                sem_wait(&pause_sem);
@@ -118,17 +121,19 @@ void *ncurses_display(void *p)
                sem_wait(&goodtodisplay);
                sem_wait(&pause_sem);
 
+               if (quit) {
+                       sem_post(&pause_sem);
+                       sem_post(&timer);
+                       reset_ncurses();
+                       pthread_exit(0);
+               }
+
                copy = g_ptr_array_index(copies, current_display_index);
                assert(copy);
                display(current_display_index++);
 
                sem_post(&goodtoupdate);
                sem_post(&pause_sem);
-
-               if (quit) {
-                       reset_ncurses();
-                       pthread_exit(0);
-               }
        }
 }
 
@@ -469,6 +474,8 @@ void iter_trace(struct bt_context *bt_ctx)
        }
 
        while ((event = bt_ctf_iter_read_event(iter)) != NULL) {
+               if (quit || reload_trace)
+                       goto end_iter;
                ret = bt_iter_next(bt_ctf_get_iter(iter));
                if (ret < 0)
                        goto end_iter;
@@ -764,6 +771,8 @@ int on_recv_fd(struct lttng_consumer_stream *kconsumerd_fd)
                ret = 0;
        }
 
+       reload_trace = 1;
+
 end:
        return ret;
 }
@@ -771,26 +780,21 @@ end:
 void live_consume(struct bt_context **bt_ctx)
 {
        int ret;
+       FILE *metadata_fp;
 
-       if (!metadata_ready) {
-               sem_wait(&metadata_available);
-               if (access("/tmp/livesession/kernel/metadata", F_OK) != 0) {
-                       fprintf(stderr,"no metadata\n");
-                       goto end;
-               }
-               metadata_ready = 1;
-               metadata_fp = fopen("/tmp/livesession/kernel/metadata", "r");
+       sem_wait(&metadata_available);
+       if (access("/tmp/livesession/kernel/metadata", F_OK) != 0) {
+               fprintf(stderr,"no metadata\n");
+               goto end;
        }
+       metadata_fp = fopen("/tmp/livesession/kernel/metadata", "r");
 
-       if (!trace_opened) {
-               *bt_ctx = bt_context_create();
-               ret = bt_context_add_trace(*bt_ctx, NULL, "ctf",
-                               lttngtop_ctf_packet_seek, &mmap_list, metadata_fp);
-               if (ret < 0) {
-                       printf("Error adding trace\n");
-                       goto end;
-               }
-               trace_opened = 1;
+       *bt_ctx = bt_context_create();
+       ret = bt_context_add_trace(*bt_ctx, NULL, "ctf",
+                       lttngtop_ctf_packet_seek, &mmap_list, metadata_fp);
+       if (ret < 0) {
+               printf("Error adding trace\n");
+               goto end;
        }
 
 end:
@@ -871,6 +875,16 @@ void *setup_live_tracing()
                goto end;
        }
 
+       /*
+        * FIXME : need to let the
+        * helper_lttng_consumer_thread_receive_fds create the
+        * socket.
+        * Cleaner solution ?
+        */
+       while (access(command_sock_path, F_OK)) {
+               sleep(0.1);
+       }
+
        if ((ret = lttng_register_consumer(handle, command_sock_path)) < 0) {
                fprintf(stderr,"error registering consumer : %s\n",
                                helper_lttcomm_get_readable_code(ret));
@@ -936,6 +950,8 @@ int main(int argc, char **argv)
 {
        int ret;
        struct bt_context *bt_ctx = NULL;
+       struct mmap_stream *mmap_info;
+       unsigned long mmap_len;
 
        ret = parse_options(argc, argv);
        if (ret < 0) {
@@ -953,12 +969,37 @@ int main(int argc, char **argv)
                        pthread_create(&display_thread, NULL, ncurses_display, (void *) NULL);
                        pthread_create(&timer_thread, NULL, refresh_thread, (void *) NULL);
                }
-               live_consume(&bt_ctx);
-               iter_trace(bt_ctx);
+               while (!quit) {
+                       reload_trace = 0;
+                       live_consume(&bt_ctx);
+                       iter_trace(bt_ctx);
+                       ret = bt_context_remove_trace(bt_ctx, 0);
+                       if (ret != 0)
+                               fprintf(stderr, "error removing trace\n");
+                       if (bt_ctx) {
+                               bt_context_put(bt_ctx);
+                       }
+
+                       /*
+                        * since we receive all FDs every time there is an
+                        * update and the FD number is different every time,
+                        * we don't know which one are valid.
+                        * so we check if all FDs are usable with a simple
+                        * ioctl call.
+                        */
+                       bt_list_for_each_entry(mmap_info, &mmap_list.head, list) {
+                               ret = helper_kernctl_get_mmap_len(mmap_info->fd, &mmap_len);
+                               if (ret != 0) {
+                                       ret = errno;
+                                       bt_list_del(&mmap_info->list);
+                               }
+                       }
+                       sem_post(&metadata_available);
+               }
 
+               pthread_join(timer_thread, NULL);
                quit = 1;
                pthread_join(display_thread, NULL);
-               pthread_join(timer_thread, NULL);
 
                lttng_stop_tracing("test");
                lttng_destroy_session("test");
@@ -984,8 +1025,8 @@ int main(int argc, char **argv)
 
                iter_trace(bt_ctx);
 
-               quit = 1;
                pthread_join(display_thread, NULL);
+               quit = 1;
                pthread_join(timer_thread, NULL);
        }
 
This page took 0.029607 seconds and 4 git commands to generate.