int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int domain,
struct ltt_ust_channel *uchan, struct lttng_event *event)
{
- int ret, to_create = 0;
+ int ret = LTTCOMM_OK, to_create = 0;
struct ltt_ust_event *uevent;
uevent = trace_ust_find_event_by_name(uchan->events, event->name);
ret = LTTCOMM_FATAL;
goto error;
}
+ /* Valid to set it after the goto error since uevent is still NULL */
to_create = 1;
}
goto end;
}
+ uevent->enabled = 1;
+
switch (domain) {
case LTTNG_DOMAIN_UST:
{
goto end;
}
- uevent->enabled = 1;
- /* Add ltt ust event to channel */
if (to_create) {
rcu_read_lock();
+ /* Add ltt ust event to channel */
lttng_ht_add_unique_str(uchan->events, &uevent->node);
rcu_read_unlock();
}
DBG("Event UST %s %s in channel %s", uevent->attr.name,
to_create ? "created" : "enabled", uchan->name);
+ ret = LTTCOMM_OK;
+
end:
- return LTTCOMM_OK;
+ return ret;
error:
- trace_ust_destroy_event(uevent);
+ /*
+ * Only destroy event on creation time (not enabling time) because if the
+ * event is found in the channel (to_create == 0), it means that at some
+ * point the enable_event worked and it's thus valid to keep it alive.
+ * Destroying it also implies that we also destroy it's shadow copy to sync
+ * everyone up.
+ */
+ if (to_create) {
+ /* In this code path, the uevent was not added to the hash table */
+ trace_ust_destroy_event(uevent);
+ }
return ret;
}