Add a deleted flag within the ust app session which is raised (with ust
app session lock held) at delete, and checked within each RCU traversal,
again with ust app session lock held.
This takes care of races between teardown of an application (unregister)
and execution of commands which are accessing the app session
concurrently.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
int ret = LTTNG_OK;
unsigned int use_tmp_output = 0;
struct snapshot_output tmp_output;
int ret = LTTNG_OK;
unsigned int use_tmp_output = 0;
struct snapshot_output tmp_output;
- unsigned int nb_streams, snapshot_success = 0;
+ unsigned int snapshot_success = 0;
assert(session);
assert(output);
assert(session);
assert(output);
pthread_mutex_unlock(®istry->lock);
return ret_val;
}
pthread_mutex_unlock(®istry->lock);
return ret_val;
}
pthread_mutex_lock(&ua_sess->lock);
pthread_mutex_lock(&ua_sess->lock);
+ assert(!ua_sess->deleted);
+ ua_sess->deleted = true;
+
registry = get_session_registry(ua_sess);
if (registry) {
/* Push metadata for application before freeing the application. */
registry = get_session_registry(ua_sess);
if (registry) {
/* Push metadata for application before freeing the application. */
*/
pthread_mutex_lock(&ua_sess->lock);
*/
pthread_mutex_lock(&ua_sess->lock);
+ if (ua_sess->deleted) {
+ pthread_mutex_unlock(&ua_sess->lock);
+ continue;
+ }
+
/*
* Normally, this is done in the delete session process which is
* executed in the call rcu below. However, upon registration we can't
/*
* Normally, this is done in the delete session process which is
* executed in the call rcu below. However, upon registration we can't
assert(ua_sess);
pthread_mutex_lock(&ua_sess->lock);
assert(ua_sess);
pthread_mutex_lock(&ua_sess->lock);
+
+ if (ua_sess->deleted) {
+ pthread_mutex_unlock(&ua_sess->lock);
+ continue;
+ }
+
if (!strncmp(uchan->name, DEFAULT_METADATA_NAME,
sizeof(uchan->name))) {
copy_channel_attr_to_ustctl(&ua_sess->metadata_attr, &uchan->attr);
if (!strncmp(uchan->name, DEFAULT_METADATA_NAME,
sizeof(uchan->name))) {
copy_channel_attr_to_ustctl(&ua_sess->metadata_attr, &uchan->attr);
pthread_mutex_lock(&ua_sess->lock);
pthread_mutex_lock(&ua_sess->lock);
+ if (ua_sess->deleted) {
+ pthread_mutex_unlock(&ua_sess->lock);
+ continue;
+ }
+
/* Lookup channel in the ust app session */
lttng_ht_lookup(ua_sess->channels, (void *)uchan->name, &uiter);
ua_chan_node = lttng_ht_iter_get_node_str(&uiter);
/* Lookup channel in the ust app session */
lttng_ht_lookup(ua_sess->channels, (void *)uchan->name, &uiter);
ua_chan_node = lttng_ht_iter_get_node_str(&uiter);
}
pthread_mutex_lock(&ua_sess->lock);
}
pthread_mutex_lock(&ua_sess->lock);
+
+ if (ua_sess->deleted) {
+ pthread_mutex_unlock(&ua_sess->lock);
+ continue;
+ }
+
/* Lookup channel in the ust app session */
lttng_ht_lookup(ua_sess->channels, (void *)uchan->name, &uiter);
ua_chan_node = lttng_ht_iter_get_node_str(&uiter);
/* Lookup channel in the ust app session */
lttng_ht_lookup(ua_sess->channels, (void *)uchan->name, &uiter);
ua_chan_node = lttng_ht_iter_get_node_str(&uiter);
pthread_mutex_lock(&ua_sess->lock);
pthread_mutex_lock(&ua_sess->lock);
+ if (ua_sess->deleted) {
+ pthread_mutex_unlock(&ua_sess->lock);
+ goto end;
+ }
+
/* Upon restart, we skip the setup, already done */
if (ua_sess->started) {
goto skip_setup;
/* Upon restart, we skip the setup, already done */
if (ua_sess->started) {
goto skip_setup;
pthread_mutex_lock(&ua_sess->lock);
pthread_mutex_lock(&ua_sess->lock);
+ if (ua_sess->deleted) {
+ pthread_mutex_unlock(&ua_sess->lock);
+ goto end_no_session;
+ }
+
/*
* If started = 0, it means that stop trace has been called for a session
* that was never started. It's possible since we can have a fail start
/*
* If started = 0, it means that stop trace has been called for a session
* that was never started. It's possible since we can have a fail start
pthread_mutex_lock(&ua_sess->lock);
pthread_mutex_lock(&ua_sess->lock);
+ if (ua_sess->deleted) {
+ goto end_deleted;
+ }
+
health_code_update();
/* Flushing buffers */
health_code_update();
/* Flushing buffers */
pthread_mutex_unlock(&ua_sess->lock);
end_not_compatible:
pthread_mutex_unlock(&ua_sess->lock);
end_not_compatible:
rcu_read_unlock();
health_code_update();
return ret;
rcu_read_unlock();
health_code_update();
return ret;
pthread_mutex_lock(&ua_sess->lock);
pthread_mutex_lock(&ua_sess->lock);
+ if (ua_sess->deleted) {
+ pthread_mutex_unlock(&ua_sess->lock);
+ goto error;
+ }
+
/*
* We can iterate safely here over all UST app session since the create ust
* app session above made a shadow copy of the UST global domain from the
/*
* We can iterate safely here over all UST app session since the create ust
* app session above made a shadow copy of the UST global domain from the
}
pthread_mutex_lock(&ua_sess->lock);
}
pthread_mutex_lock(&ua_sess->lock);
+
+ if (ua_sess->deleted) {
+ pthread_mutex_unlock(&ua_sess->lock);
+ continue;
+ }
+
/* Lookup channel in the ust app session */
lttng_ht_lookup(ua_sess->channels, (void *)uchan->name, &uiter);
ua_chan_node = lttng_ht_iter_get_node_str(&uiter);
/* Lookup channel in the ust app session */
lttng_ht_lookup(ua_sess->channels, (void *)uchan->name, &uiter);
ua_chan_node = lttng_ht_iter_get_node_str(&uiter);
}
pthread_mutex_lock(&ua_sess->lock);
}
pthread_mutex_lock(&ua_sess->lock);
+
+ if (ua_sess->deleted) {
+ ret = 0;
+ goto end_unlock;
+ }
+
/* Lookup channel in the ust app session */
lttng_ht_lookup(ua_sess->channels, (void *)uchan->name, &iter);
ua_chan_node = lttng_ht_iter_get_node_str(&iter);
/* Lookup channel in the ust app session */
lttng_ht_lookup(ua_sess->channels, (void *)uchan->name, &iter);
ua_chan_node = lttng_ht_iter_get_node_str(&iter);
int started; /* allows detection of start vs restart. */
int handle; /* used has unique identifier for app session */
int started; /* allows detection of start vs restart. */
int handle; /* used has unique identifier for app session */
+ bool deleted; /* Session deleted flag. Check with lock held. */
+
/*
* Tracing session ID. Multiple ust app session can have the same tracing
* session id making this value NOT unique to the object.
/*
* Tracing session ID. Multiple ust app session can have the same tracing
* session id making this value NOT unique to the object.