Create `_for_each` function to unregister probe providers
[deliverable/lttng-ust.git] / liblttng-ust / lttng-events.c
index 0c684df2f3f6759d9930c2317926dce2853ae7a9..0c508af7bc9a263f3a4f1dd39ed5e535b906d234 100644 (file)
@@ -560,6 +560,23 @@ end:
        return ret;
 }
 
+static inline
+struct cds_hlist_head *borrow_hash_table_bucket(
+               struct cds_hlist_head *hash_table,
+               unsigned int hash_table_size,
+               const struct lttng_event_desc *desc)
+{
+       const char *event_name;
+       size_t name_len;
+       uint32_t hash;
+
+       event_name = desc->name;
+       name_len = strlen(event_name);
+
+       hash = jhash(event_name, name_len, 0);
+       return &hash_table[hash & (hash_table_size - 1)];
+}
+
 /*
  * Supports event creation while tracing session is active.
  */
@@ -567,18 +584,15 @@ static
 int lttng_event_create(const struct lttng_event_desc *desc,
                struct lttng_channel *chan)
 {
-       const char *event_name = desc->name;
        struct lttng_event *event;
        struct lttng_session *session = chan->session;
        struct cds_hlist_head *head;
        int ret = 0;
-       size_t name_len = strlen(event_name);
-       uint32_t hash;
        int notify_socket, loglevel;
        const char *uri;
 
-       hash = jhash(event_name, name_len, 0);
-       head = &chan->session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)];
+       head = borrow_hash_table_bucket(chan->session->events_ht.table,
+               LTTNG_UST_EVENT_HT_SIZE, desc);
 
        notify_socket = lttng_get_notify_socket(session->owner);
        if (notify_socket < 0) {
@@ -624,7 +638,7 @@ int lttng_event_create(const struct lttng_event_desc *desc,
                session,
                session->objd,
                chan->objd,
-               event_name,
+               desc->name,
                loglevel,
                desc->signature,
                desc->nr_fields,
@@ -785,22 +799,16 @@ void lttng_create_event_if_missing(struct lttng_event_enabler *event_enabler)
                        bool found = false;
                        struct cds_hlist_head *head;
                        struct cds_hlist_node *node;
-                       const char *event_name;
-                       size_t name_len;
-                       uint32_t hash;
 
                        desc = probe_desc->event_desc[i];
                        if (!lttng_desc_match_enabler(desc,
                                        lttng_event_enabler_as_enabler(event_enabler)))
                                continue;
-                       event_name = desc->name;
-                       name_len = strlen(event_name);
 
-                       /*
-                        * Check if already created.
-                        */
-                       hash = jhash(event_name, name_len, 0);
-                       head = &session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)];
+                       head = borrow_hash_table_bucket(
+                               session->events_ht.table,
+                               LTTNG_UST_EVENT_HT_SIZE, desc);
+
                        cds_hlist_for_each_entry(event, node, head, hlist) {
                                if (event->desc == desc
                                                && event->chan == event_enabler->chan) {
@@ -825,54 +833,106 @@ void lttng_create_event_if_missing(struct lttng_event_enabler *event_enabler)
        }
 }
 
-/*
- * Iterate over all the UST sessions to unregister and destroy all probes from
- * the probe provider descriptor received as argument. Must me called with the
- * ust_lock held.
- */
-void lttng_probe_provider_unregister_events(struct lttng_probe_desc *provider_desc)
+static
+void probe_provider_event_for_each(struct lttng_probe_desc *provider_desc,
+               void (*event_func)(struct lttng_session *session, struct lttng_event *event))
 {
        struct cds_hlist_node *node, *tmp_node;
        struct cds_list_head *sessionsp;
-       struct lttng_session *session;
-       struct cds_hlist_head *head;
-       struct lttng_event *event;
-       unsigned int i, j;
+       unsigned int i;
 
        /* Get handle on list of sessions. */
        sessionsp = _lttng_get_sessions();
 
        /*
-        * Iterate over all events in the probe provider descriptions and sessions
-        * to queue the unregistration of the events.
+        * Iterate over all events in the probe provider descriptions and
+        * sessions to queue the unregistration of the events.
         */
        for (i = 0; i < provider_desc->nr_events; i++) {
                const struct lttng_event_desc *event_desc;
-               const char *event_name;
-               size_t name_len;
-               uint32_t hash;
+               struct lttng_session *session;
+               struct cds_hlist_head *head;
+               struct lttng_event *event;
 
                event_desc = provider_desc->event_desc[i];
-               event_name = event_desc->name;
-               name_len = strlen(event_name);
-               hash = jhash(event_name, name_len, 0);
 
-               /* Iterate over all session to find the current event description. */
+               /*
+                * Iterate over all session to find the current event
+                * description.
+                */
                cds_list_for_each_entry(session, sessionsp, node) {
                        /*
-                        * Get the list of events in the hashtable bucket and iterate to
-                        * find the event matching this descriptor.
+                        * Get the list of events in the hashtable bucket and
+                        * iterate to find the event matching this descriptor.
                         */
-                       head = &session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)];
-                       cds_hlist_for_each_entry(event, node, head, hlist) {
+                       head = borrow_hash_table_bucket(
+                               session->events_ht.table,
+                               LTTNG_UST_EVENT_HT_SIZE, event_desc);
+
+                       cds_hlist_for_each_entry_safe(event, node, tmp_node, head, hlist) {
                                if (event_desc == event->desc) {
-                                       /* Queue the unregistration of this event. */
-                                       _lttng_event_unregister(event);
+                                       event_func(session, event);
                                        break;
                                }
                        }
                }
        }
+}
+
+static
+void _unregister_event(struct lttng_session *session,
+               struct lttng_event *event)
+{
+       _lttng_event_unregister(event);
+}
+
+static
+void _event_enum_destroy(struct lttng_session *session,
+               struct lttng_event *event)
+{
+       unsigned int i;
+
+       /* Destroy enums of the current event. */
+       for (i = 0; i < event->desc->nr_fields; i++) {
+               const struct lttng_enum_desc *enum_desc;
+               const struct lttng_event_field *field;
+               struct lttng_enum *curr_enum;
+
+               field = &(event->desc->fields[i]);
+               switch (field->type.atype) {
+               case atype_enum:
+                       enum_desc = field->type.u.legacy.basic.enumeration.desc;
+                       break;
+               case atype_enum_nestable:
+                       enum_desc = field->type.u.enum_nestable.desc;
+                       break;
+               default:
+                       continue;
+               }
+
+               curr_enum = lttng_ust_enum_get_from_desc(session, enum_desc);
+               if (curr_enum) {
+                       _lttng_enum_destroy(curr_enum);
+               }
+       }
+
+       /* Destroy event. */
+       _lttng_event_destroy(event);
+}
+
+/*
+ * Iterate over all the UST sessions to unregister and destroy all probes from
+ * the probe provider descriptor received as argument. Must me called with the
+ * ust_lock held.
+ */
+void lttng_probe_provider_unregister_events(
+               struct lttng_probe_desc *provider_desc)
+{
+       /*
+        * Iterate over all events in the probe provider descriptions and sessions
+        * to queue the unregistration of the events.
+        */
+       probe_provider_event_for_each(provider_desc, _unregister_event);
 
        /* Wait for grace period. */
        synchronize_trace();
@@ -883,56 +943,7 @@ void lttng_probe_provider_unregister_events(struct lttng_probe_desc *provider_de
         * It is now safe to destroy the events and remove them from the event list
         * and hashtables.
         */
-       for (i = 0; i < provider_desc->nr_events; i++) {
-               const struct lttng_event_desc *event_desc;
-               const char *event_name;
-               size_t name_len;
-               uint32_t hash;
-
-               event_desc = provider_desc->event_desc[i];
-               event_name = event_desc->name;
-               name_len = strlen(event_name);
-               hash = jhash(event_name, name_len, 0);
-
-               /* Iterate over all sessions to find the current event description. */
-               cds_list_for_each_entry(session, sessionsp, node) {
-                       /*
-                        * Get the list of events in the hashtable bucket and iterate to
-                        * find the event matching this descriptor.
-                        */
-                       head = &session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)];
-                       cds_hlist_for_each_entry_safe(event, node, tmp_node, head, hlist) {
-                               if (event_desc == event->desc) {
-                                       /* Destroy enums of the current event. */
-                                       for (j = 0; j < event->desc->nr_fields; j++) {
-                                               const struct lttng_enum_desc *enum_desc;
-                                               const struct lttng_event_field *field;
-                                               struct lttng_enum *curr_enum;
-
-                                               field = &(event->desc->fields[j]);
-                                               switch (field->type.atype) {
-                                               case atype_enum:
-                                                       enum_desc = field->type.u.legacy.basic.enumeration.desc;
-                                                       break;
-                                               case atype_enum_nestable:
-                                                       enum_desc = field->type.u.enum_nestable.desc;
-                                                       break;
-                                               default:
-                                                       continue;
-                                               }
-                                               curr_enum = lttng_ust_enum_get_from_desc(session, enum_desc);
-                                               if (curr_enum) {
-                                                       _lttng_enum_destroy(curr_enum);
-                                               }
-                                       }
-
-                                       /* Destroy event. */
-                                       _lttng_event_destroy(event);
-                                       break;
-                               }
-                       }
-               }
-       }
+       probe_provider_event_for_each(provider_desc, _event_enum_destroy);
 }
 
 /*
@@ -977,7 +988,10 @@ int lttng_event_enabler_ref_events(struct lttng_event_enabler *event_enabler)
                /*
                 * Link filter bytecodes if not linked yet.
                 */
-               lttng_event_enabler_link_bytecode(event, event_enabler);
+               lttng_enabler_link_bytecode(event->desc,
+                       &session->ctx,
+                       &event->bytecode_runtime_head,
+                       lttng_event_enabler_as_enabler(event_enabler));
 
                /* TODO: merge event context. */
        }
This page took 0.042036 seconds and 5 git commands to generate.