Fix: consumerd: HT init/teardown with program
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 27 Jan 2014 03:39:44 +0000 (22:39 -0500)
committerDavid Goulet <dgoulet@efficios.com>
Tue, 28 Jan 2014 21:19:41 +0000 (16:19 -0500)
Hash tables shared between threads should not be initialized by a
specific thread, because the other threads could start using it before
it is initialized.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: David Goulet <dgoulet@efficios.com>
src/bin/lttng-consumerd/lttng-consumerd.c
src/common/consumer.c
src/common/consumer.h

index 4a9a7a4929200bfd53c838eed13b48f52dd0ae50..d9ec0f33efc4cbb0453f91ba479db9e550bd8ed8 100644 (file)
@@ -341,7 +341,10 @@ int main(int argc, char **argv)
        }
 
        /* Init */
        }
 
        /* Init */
-       lttng_consumer_init();
+       if (lttng_consumer_init() < 0) {
+               goto error;
+       }
+
        /* Init socket timeouts */
        lttcomm_init();
        lttcomm_inet_init();
        /* Init socket timeouts */
        lttcomm_init();
        lttcomm_inet_init();
@@ -405,9 +408,6 @@ int main(int argc, char **argv)
 
        ctx->type = opt_type;
 
 
        ctx->type = opt_type;
 
-       /* Initialize communication library */
-       lttcomm_init();
-
        ret = utils_create_pipe(health_quit_pipe);
        if (ret < 0) {
                goto error_health_pipe;
        ret = utils_create_pipe(health_quit_pipe);
        if (ret < 0) {
                goto error_health_pipe;
index f47d8de1b2669665a4a138a8b0fcbcdb65dc3b3d..cbcb2f74d27f8dfb8297b8c37f04b67112f6806e 100644 (file)
@@ -1311,6 +1311,57 @@ error:
        return NULL;
 }
 
        return NULL;
 }
 
+/*
+ * Iterate over all streams of the hashtable and free them properly.
+ */
+static void destroy_data_stream_ht(struct lttng_ht *ht)
+{
+       struct lttng_ht_iter iter;
+       struct lttng_consumer_stream *stream;
+
+       if (ht == NULL) {
+               return;
+       }
+
+       rcu_read_lock();
+       cds_lfht_for_each_entry(ht->ht, &iter.iter, stream, node.node) {
+               /*
+                * Ignore return value since we are currently cleaning up so any error
+                * can't be handled.
+                */
+               (void) consumer_del_stream(stream, ht);
+       }
+       rcu_read_unlock();
+
+       lttng_ht_destroy(ht);
+}
+
+/*
+ * Iterate over all streams of the metadata hashtable and free them
+ * properly.
+ */
+static void destroy_metadata_stream_ht(struct lttng_ht *ht)
+{
+       struct lttng_ht_iter iter;
+       struct lttng_consumer_stream *stream;
+
+       if (ht == NULL) {
+               return;
+       }
+
+       rcu_read_lock();
+       cds_lfht_for_each_entry(ht->ht, &iter.iter, stream, node.node) {
+               /*
+                * Ignore return value since we are currently cleaning up so any error
+                * can't be handled.
+                */
+               (void) consumer_del_metadata_stream(stream, ht);
+       }
+       rcu_read_unlock();
+
+       lttng_ht_destroy(ht);
+}
+
 /*
  * Close all fds associated with the instance and free the context.
  */
 /*
  * Close all fds associated with the instance and free the context.
  */
@@ -1320,6 +1371,9 @@ void lttng_consumer_destroy(struct lttng_consumer_local_data *ctx)
 
        DBG("Consumer destroying it. Closing everything.");
 
 
        DBG("Consumer destroying it. Closing everything.");
 
+       destroy_data_stream_ht(data_ht);
+       destroy_metadata_stream_ht(metadata_ht);
+
        ret = close(ctx->consumer_error_socket);
        if (ret) {
                PERROR("close");
        ret = close(ctx->consumer_error_socket);
        if (ret) {
                PERROR("close");
@@ -1894,60 +1948,6 @@ int lttng_consumer_recv_cmd(struct lttng_consumer_local_data *ctx,
        }
 }
 
        }
 }
 
-/*
- * Iterate over all streams of the hashtable and free them properly.
- *
- * WARNING: *MUST* be used with data stream only.
- */
-static void destroy_data_stream_ht(struct lttng_ht *ht)
-{
-       struct lttng_ht_iter iter;
-       struct lttng_consumer_stream *stream;
-
-       if (ht == NULL) {
-               return;
-       }
-
-       rcu_read_lock();
-       cds_lfht_for_each_entry(ht->ht, &iter.iter, stream, node.node) {
-               /*
-                * Ignore return value since we are currently cleaning up so any error
-                * can't be handled.
-                */
-               (void) consumer_del_stream(stream, ht);
-       }
-       rcu_read_unlock();
-
-       lttng_ht_destroy(ht);
-}
-
-/*
- * Iterate over all streams of the hashtable and free them properly.
- *
- * XXX: Should not be only for metadata stream or else use an other name.
- */
-static void destroy_stream_ht(struct lttng_ht *ht)
-{
-       struct lttng_ht_iter iter;
-       struct lttng_consumer_stream *stream;
-
-       if (ht == NULL) {
-               return;
-       }
-
-       rcu_read_lock();
-       cds_lfht_for_each_entry(ht->ht, &iter.iter, stream, node.node) {
-               /*
-                * Ignore return value since we are currently cleaning up so any error
-                * can't be handled.
-                */
-               (void) consumer_del_metadata_stream(stream, ht);
-       }
-       rcu_read_unlock();
-
-       lttng_ht_destroy(ht);
-}
-
 void lttng_consumer_close_metadata(void)
 {
        switch (consumer_data.type) {
 void lttng_consumer_close_metadata(void)
 {
        switch (consumer_data.type) {
@@ -2256,12 +2256,6 @@ void *consumer_thread_metadata_poll(void *data)
 
        health_code_update();
 
 
        health_code_update();
 
-       metadata_ht = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
-       if (!metadata_ht) {
-               /* ENOMEM at this point. Better to bail out. */
-               goto end_ht;
-       }
-
        DBG("Thread metadata poll started");
 
        /* Size is set to 1 for the consumer_metadata pipe */
        DBG("Thread metadata poll started");
 
        /* Size is set to 1 for the consumer_metadata pipe */
@@ -2434,8 +2428,6 @@ end:
 
        lttng_poll_clean(&events);
 end_poll:
 
        lttng_poll_clean(&events);
 end_poll:
-       destroy_stream_ht(metadata_ht);
-end_ht:
        if (err) {
                health_error();
                ERR("Health error occurred in %s", __func__);
        if (err) {
                health_error();
                ERR("Health error occurred in %s", __func__);
@@ -2466,12 +2458,6 @@ void *consumer_thread_data_poll(void *data)
 
        health_code_update();
 
 
        health_code_update();
 
-       data_ht = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
-       if (data_ht == NULL) {
-               /* ENOMEM at this point. Better to bail out. */
-               goto end;
-       }
-
        local_stream = zmalloc(sizeof(struct lttng_consumer_stream *));
        if (local_stream == NULL) {
                PERROR("local_stream malloc");
        local_stream = zmalloc(sizeof(struct lttng_consumer_stream *));
        if (local_stream == NULL) {
                PERROR("local_stream malloc");
@@ -2701,8 +2687,6 @@ end:
         */
        (void) lttng_pipe_write_close(ctx->consumer_metadata_pipe);
 
         */
        (void) lttng_pipe_write_close(ctx->consumer_metadata_pipe);
 
-       destroy_data_stream_ht(data_ht);
-
        if (err) {
                health_error();
                ERR("Health error occurred in %s", __func__);
        if (err) {
                health_error();
                ERR("Health error occurred in %s", __func__);
@@ -3256,12 +3240,42 @@ int lttng_consumer_on_recv_stream(struct lttng_consumer_stream *stream)
 /*
  * Allocate and set consumer data hash tables.
  */
 /*
  * Allocate and set consumer data hash tables.
  */
-void lttng_consumer_init(void)
+int lttng_consumer_init(void)
 {
        consumer_data.channel_ht = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
 {
        consumer_data.channel_ht = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
+       if (!consumer_data.channel_ht) {
+               goto error;
+       }
+
        consumer_data.relayd_ht = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
        consumer_data.relayd_ht = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
+       if (!consumer_data.relayd_ht) {
+               goto error;
+       }
+
        consumer_data.stream_list_ht = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
        consumer_data.stream_list_ht = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
+       if (!consumer_data.stream_list_ht) {
+               goto error;
+       }
+
        consumer_data.stream_per_chan_id_ht = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
        consumer_data.stream_per_chan_id_ht = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
+       if (!consumer_data.stream_per_chan_id_ht) {
+               goto error;
+       }
+
+       data_ht = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
+       if (!data_ht) {
+               goto error;
+       }
+
+       metadata_ht = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
+       if (!metadata_ht) {
+               goto error;
+       }
+
+       return 0;
+
+error:
+       return -1;
 }
 
 /*
 }
 
 /*
index 8d7e1d0a46d0a678685d7bac209e477ffa6c8bee..a7517a34083db737d9be2b2b51b61ddb3a60eb36 100644 (file)
@@ -512,7 +512,7 @@ struct lttng_consumer_global_data {
 /*
  * Init consumer data structures.
  */
 /*
  * Init consumer data structures.
  */
-void lttng_consumer_init(void);
+int lttng_consumer_init(void);
 
 /*
  * Set the error socket for communication with a session daemon.
 
 /*
  * Set the error socket for communication with a session daemon.
This page took 0.030602 seconds and 4 git commands to generate.