+static
+void _lttng_event_notifier_unregister(struct lttng_event_notifier *event_notifier)
+{
+ if (event_notifier->registered)
+ unregister_event_notifier(event_notifier);
+}
+
+void lttng_session_destroy(struct lttng_session *session)
+{
+ struct lttng_channel *chan, *tmpchan;
+ struct lttng_event *event, *tmpevent;
+ struct lttng_enum *_enum, *tmp_enum;
+ struct lttng_event_enabler *event_enabler, *event_tmpenabler;
+
+ CMM_ACCESS_ONCE(session->active) = 0;
+ cds_list_for_each_entry(event, &session->events_head, node) {
+ _lttng_event_unregister(event);
+ }
+ lttng_ust_synchronize_trace(); /* Wait for in-flight events to complete */
+ __tracepoint_probe_prune_release_queue();
+ cds_list_for_each_entry_safe(event_enabler, event_tmpenabler,
+ &session->enablers_head, node)
+ lttng_event_enabler_destroy(event_enabler);
+ cds_list_for_each_entry_safe(event, tmpevent,
+ &session->events_head, node)
+ _lttng_event_destroy(event);
+ cds_list_for_each_entry_safe(_enum, tmp_enum,
+ &session->enums_head, node)
+ _lttng_enum_destroy(_enum);
+ cds_list_for_each_entry_safe(chan, tmpchan, &session->chan_head, node)
+ _lttng_channel_unmap(chan);
+ cds_list_del(&session->node);
+ lttng_destroy_context(session->ctx);
+ free(session);
+}
+
+void lttng_event_notifier_group_destroy(
+ struct lttng_event_notifier_group *event_notifier_group)
+{
+ int close_ret;
+ struct lttng_event_notifier_enabler *notifier_enabler, *tmpnotifier_enabler;
+ struct lttng_event_notifier *notifier, *tmpnotifier;
+
+ if (!event_notifier_group) {
+ return;
+ }
+
+ cds_list_for_each_entry(notifier,
+ &event_notifier_group->event_notifiers_head, node)
+ _lttng_event_notifier_unregister(notifier);
+
+ lttng_ust_synchronize_trace();
+
+ cds_list_for_each_entry_safe(notifier_enabler, tmpnotifier_enabler,
+ &event_notifier_group->enablers_head, node)
+ lttng_event_notifier_enabler_destroy(notifier_enabler);
+
+ cds_list_for_each_entry_safe(notifier, tmpnotifier,
+ &event_notifier_group->event_notifiers_head, node)
+ _lttng_event_notifier_destroy(notifier);
+
+ if (event_notifier_group->error_counter)
+ lttng_ust_counter_destroy(event_notifier_group->error_counter);
+
+ /* Close the notification fd to the listener of event_notifiers. */
+
+ lttng_ust_lock_fd_tracker();
+ close_ret = close(event_notifier_group->notification_fd);
+ if (!close_ret) {
+ lttng_ust_delete_fd_from_tracker(
+ event_notifier_group->notification_fd);
+ } else {
+ PERROR("close");
+ abort();
+ }
+ lttng_ust_unlock_fd_tracker();
+
+ cds_list_del(&event_notifier_group->node);
+
+ free(event_notifier_group);
+}
+
+static
+void lttng_enabler_destroy(struct lttng_enabler *enabler)
+{
+ struct lttng_ust_bytecode_node *filter_node, *tmp_filter_node;
+ struct lttng_ust_excluder_node *excluder_node, *tmp_excluder_node;
+
+ if (!enabler) {
+ return;
+ }
+
+ /* Destroy filter bytecode */
+ cds_list_for_each_entry_safe(filter_node, tmp_filter_node,
+ &enabler->filter_bytecode_head, node) {
+ free(filter_node);
+ }
+
+ /* Destroy excluders */
+ cds_list_for_each_entry_safe(excluder_node, tmp_excluder_node,
+ &enabler->excluder_head, node) {
+ free(excluder_node);
+ }
+}
+
+ void lttng_event_notifier_enabler_destroy(struct lttng_event_notifier_enabler *event_notifier_enabler)
+{
+ if (!event_notifier_enabler) {
+ return;
+ }
+
+ cds_list_del(&event_notifier_enabler->node);
+
+ lttng_enabler_destroy(lttng_event_notifier_enabler_as_enabler(event_notifier_enabler));
+
+ free(event_notifier_enabler);
+}
+
+static
+int lttng_enum_create(const struct lttng_enum_desc *desc,
+ struct lttng_session *session)