Fix: locking order between consumer and stream
[lttng-tools.git] / src / common / consumer.h
index 53b6151822ba36102b6b6df5a53878ac35b714a7..87ba490d7500af8ea078cec6ab652495ab5c91d5 100644 (file)
 #include <common/compat/fcntl.h>
 #include <common/sessiond-comm/sessiond-comm.h>
 
-/*
- * When the receiving thread dies, we need to have a way to make the polling
- * thread exit eventually. If all FDs hang up (normal case when the
- * lttng-sessiond stops), we can exit cleanly, but if there is a problem and
- * for whatever reason some FDs remain open, the consumer should still exit
- * eventually.
- *
- * If the timeout is reached, it means that during this period no events
- * occurred on the FDs so we need to force an exit. This case should not happen
- * but it is a safety to ensure we won't block the consumer indefinitely.
- *
- * The value of 2 seconds is an arbitrary choice.
- */
-#define LTTNG_CONSUMER_POLL_TIMEOUT 2000
-
 /* Commands for consumer */
 enum lttng_consumer_command {
        LTTNG_CONSUMER_ADD_CHANNEL,
@@ -57,7 +42,7 @@ enum lttng_consumer_command {
        /* Inform the consumer to kill a specific relayd connection */
        LTTNG_CONSUMER_DESTROY_RELAYD,
        /* Return to the sessiond if there is data pending for a session */
-       LTTNG_CONSUMER_DATA_AVAILABLE,
+       LTTNG_CONSUMER_DATA_PENDING,
 };
 
 /* State of each fd in consumer */
@@ -74,6 +59,11 @@ enum lttng_consumer_type {
        LTTNG_CONSUMER32_UST,
 };
 
+enum consumer_endpoint_status {
+       CONSUMER_ENDPOINT_ACTIVE,
+       CONSUMER_ENDPOINT_INACTIVE,
+};
+
 struct lttng_consumer_channel {
        struct lttng_ht_node_ulong node;
        int key;
@@ -142,14 +132,21 @@ struct lttng_consumer_stream {
        /* Next sequence number to use for trace packet */
        uint64_t next_net_seq_num;
        /*
-        * Lock to use the stream FDs since they are used between threads. Using
-        * this lock with network streaming, when using the control mutex of a
-        * consumer_relayd_sock_pair, make sure to acquire this lock BEFORE locking
-        * it and releasing it AFTER the control mutex unlock.
+        * Lock to use the stream FDs since they are used between threads.
+        *
+        * This is nested INSIDE the consumer_data lock.
+        * This is nested OUTSIDE consumer_relayd_sock_pair lock.
         */
        pthread_mutex_t lock;
        /* Tracing session id */
        uint64_t session_id;
+       /*
+        * Indicates if the stream end point is still active or not (network
+        * streaming or local file system). The thread "owning" the stream is
+        * handling this status and can be notified of a state change through the
+        * consumer data appropriate pipe.
+        */
+       enum consumer_endpoint_status endpoint_status;
 };
 
 /*
@@ -173,6 +170,9 @@ struct consumer_relayd_sock_pair {
         * between threads sending data to the relayd. Since metadata data is sent
         * over that socket, at least two sendmsg() are needed (header + data)
         * creating a race for packets to overlap between threads using it.
+        *
+        * This is nested INSIDE the consumer_data lock.
+        * This is nested INSIDE the stream lock.
         */
        pthread_mutex_t ctrl_sock_mutex;
 
@@ -260,8 +260,8 @@ struct lttng_consumer_global_data {
         * and number of element in the hash table. It's also a protection for
         * concurrent read/write between threads.
         *
-        * XXX: We need to see if this lock is still needed with the lockless RCU
-        * hash tables.
+        * This is nested OUTSIDE the stream lock.
+        * This is nested OUTSIDE the consumer_relayd_sock_pair lock.
         */
        pthread_mutex_t lock;
 
@@ -296,10 +296,6 @@ struct lttng_consumer_global_data {
        struct lttng_ht *stream_list_ht;
 };
 
-/* Defined in consumer.c and coupled with explanations */
-extern struct lttng_ht *metadata_ht;
-extern struct lttng_ht *data_ht;
-
 /*
  * Init consumer data structures.
  */
@@ -419,6 +415,6 @@ int consumer_add_relayd_socket(int net_seq_idx, int sock_type,
                struct pollfd *consumer_sockpoll, struct lttcomm_sock *relayd_sock);
 void consumer_flag_relayd_for_destroy(
                struct consumer_relayd_sock_pair *relayd);
-int consumer_data_available(uint64_t id);
+int consumer_data_pending(uint64_t id);
 
 #endif /* LIB_CONSUMER_H */
This page took 0.046039 seconds and 4 git commands to generate.