+/*
+ * Match function for the hash table lookup.
+ *
+ * It matches an ust app event based on three attributes which are the event
+ * name, the filter bytecode and the loglevel.
+ */
+static int ht_match_ust_app_event(struct cds_lfht_node *node, const void *_key)
+{
+ struct ust_app_event *event;
+ const struct ust_app_ht_key *key;
+
+ assert(node);
+ assert(_key);
+
+ event = caa_container_of(node, struct ust_app_event, node.node);
+ key = _key;
+
+ /* Match the 3 elements of the key: name, filter and loglevel. */
+
+ /* Event name */
+ if (strncmp(event->attr.name, key->name, sizeof(event->attr.name)) != 0) {
+ goto no_match;
+ }
+
+ /* Event loglevel. */
+ if (event->attr.loglevel != key->loglevel) {
+ if (event->attr.loglevel_type == LTTNG_UST_LOGLEVEL_ALL
+ && key->loglevel == 0 && event->attr.loglevel == -1) {
+ /*
+ * Match is accepted. This is because on event creation, the
+ * loglevel is set to -1 if the event loglevel type is ALL so 0 and
+ * -1 are accepted for this loglevel type since 0 is the one set by
+ * the API when receiving an enable event.
+ */
+ } else {
+ goto no_match;
+ }
+ }
+
+ /* One of the filters is NULL, fail. */
+ if ((key->filter && !event->filter) || (!key->filter && event->filter)) {
+ goto no_match;
+ }
+
+ if (key->filter && event->filter) {
+ /* Both filters exists, check length followed by the bytecode. */
+ if (event->filter->len != key->filter->len ||
+ memcmp(event->filter->data, key->filter->data,
+ event->filter->len) != 0) {
+ goto no_match;
+ }
+ }
+
+ /* Match. */
+ return 1;
+
+no_match:
+ return 0;
+}
+
+/*
+ * Unique add of an ust app event in the given ht. This uses the custom
+ * ht_match_ust_app_event match function and the event name as hash.
+ */
+static void add_unique_ust_app_event(struct lttng_ht *ht,
+ struct ust_app_event *event)
+{
+ struct cds_lfht_node *node_ptr;
+ struct ust_app_ht_key key;
+
+ assert(ht);
+ assert(ht->ht);
+ assert(event);
+
+ key.name = event->attr.name;
+ key.filter = event->filter;
+ key.loglevel = event->attr.loglevel;
+
+ node_ptr = cds_lfht_add_unique(ht->ht,
+ ht->hash_fct(event->node.key, lttng_ht_seed),
+ ht_match_ust_app_event, &key, &event->node.node);
+ assert(node_ptr == &event->node.node);
+}
+