struct cds_list_head node;
};
+struct notification_trigger_tokens_ht_element {
+ uint64_t token;
+ /* Weak reference to the trigger. */
+ struct lttng_trigger *trigger;
+ struct cds_lfht_node node;
+ /* call_rcu delayed reclaim. */
+ struct rcu_head rcu_node;
+};
+
struct notification_thread_handle {
/*
* Queue of struct notification command.
struct cds_lfht *sessions_ht;
struct cds_lfht *triggers_ht;
struct cds_lfht *triggers_by_name_uid_ht;
+ struct cds_lfht *trigger_tokens_ht;
struct {
uint64_t next_tracer_token;
uint64_t name_offset;
struct cds_list_head tracer_event_sources_list;
notification_client_id next_notification_client_id;
struct action_executor *executor;
+
+ /*
+ * Indicates the thread to break for the poll event processing loop and
+ * call _poll_wait() again.
+ *
+ * This is necessary because some events on one fd might trigger the
+ * consumption of another fd.
+ * For example, a single _poll_wait() call can return notification
+ * thread commands and events from the tracer event source (event
+ * notifier).
+ * Picture a scenario where we receive two events:
+ * the first one is a _REMOVE_TRACER_EVENT_SOURCE command, and
+ * the second is an POLLIN on the tracer event source fd.
+ *
+ * The _REMOVE_TRACER_EVENT_SOURCE will read all the data of the
+ * removed tracer event source.
+ *
+ * The second event is now invalid has we consumed all the data for
+ * which we received the POLLIN.
+ *
+ * For this reason, we need to break for the event processing loop and
+ * call _poll_wait() again to get a clean view of the activity on the
+ * fds.
+ */
+ bool restart_poll;
};
/* notification_thread_data takes ownership of the channel monitor pipes. */