* this function.
*/
static
-void delete_ust_app_ctx(int sock, struct ust_app_ctx *ua_ctx)
+void delete_ust_app_ctx(int sock, struct ust_app_ctx *ua_ctx,
+ struct ust_app *app)
{
int ret;
assert(ua_ctx);
if (ua_ctx->obj) {
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_release_object(sock, ua_ctx->obj);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("UST app sock %d release ctx obj handle %d failed with ret %d",
sock, ua_ctx->obj->handle, ret);
* this function.
*/
static
-void delete_ust_app_event(int sock, struct ust_app_event *ua_event)
+void delete_ust_app_event(int sock, struct ust_app_event *ua_event,
+ struct ust_app *app)
{
int ret;
if (ua_event->exclusion != NULL)
free(ua_event->exclusion);
if (ua_event->obj != NULL) {
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_release_object(sock, ua_event->obj);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("UST app sock %d release event obj failed with ret %d",
sock, ret);
*
* Return 0 on success or else a negative value.
*/
-static int release_ust_app_stream(int sock, struct ust_app_stream *stream)
+static int release_ust_app_stream(int sock, struct ust_app_stream *stream,
+ struct ust_app *app)
{
int ret = 0;
assert(stream);
if (stream->obj) {
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_release_object(sock, stream->obj);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("UST app sock %d release stream obj failed with ret %d",
sock, ret);
* this function.
*/
static
-void delete_ust_app_stream(int sock, struct ust_app_stream *stream)
+void delete_ust_app_stream(int sock, struct ust_app_stream *stream,
+ struct ust_app *app)
{
assert(stream);
- (void) release_ust_app_stream(sock, stream);
+ (void) release_ust_app_stream(sock, stream, app);
free(stream);
}
/* Wipe stream */
cds_list_for_each_entry_safe(stream, stmp, &ua_chan->streams.head, list) {
cds_list_del(&stream->list);
- delete_ust_app_stream(sock, stream);
+ delete_ust_app_stream(sock, stream, app);
}
/* Wipe context */
cds_list_del(&ua_ctx->list);
ret = lttng_ht_del(ua_chan->ctx, &iter);
assert(!ret);
- delete_ust_app_ctx(sock, ua_ctx);
+ delete_ust_app_ctx(sock, ua_ctx, app);
}
/* Wipe events */
node.node) {
ret = lttng_ht_del(ua_chan->events, &iter);
assert(!ret);
- delete_ust_app_event(sock, ua_event);
+ delete_ust_app_event(sock, ua_event, app);
}
if (ua_chan->session->buffer_type == LTTNG_BUFFER_PER_PID) {
iter.iter.node = &ua_chan->ust_objd_node.node;
ret = lttng_ht_del(app->ust_objd, &iter);
assert(!ret);
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_release_object(sock, ua_chan->obj);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("UST app sock %d release channel obj failed with ret %d",
sock, ret);
call_rcu(&ua_chan->rcu_head, delete_ust_app_channel_rcu);
}
+int ust_app_register_done(struct ust_app *app)
+{
+ int ret;
+
+ pthread_mutex_lock(&app->sock_lock);
+ ret = ustctl_register_done(app->sock);
+ pthread_mutex_unlock(&app->sock_lock);
+ return ret;
+}
+
+int ust_app_release_object(struct ust_app *app, struct lttng_ust_object_data *data)
+{
+ int ret, sock;
+
+ if (app) {
+ pthread_mutex_lock(&app->sock_lock);
+ sock = app->sock;
+ } else {
+ sock = -1;
+ }
+ ret = ustctl_release_object(sock, data);
+ if (app) {
+ pthread_mutex_unlock(&app->sock_lock);
+ }
+ return ret;
+}
+
/*
* Push metadata to consumer socket.
*
}
if (ua_sess->handle != -1) {
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_release_handle(sock, ua_sess->handle);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("UST app sock %d release session handle failed with ret %d",
sock, ret);
health_code_update();
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_add_context(app->sock, &ua_ctx->ctx,
ua_chan->obj, &ua_ctx->obj);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0) {
if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("UST app create channel context failed for app (pid: %d) "
goto error;
}
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_set_filter(app->sock, ua_event->filter,
ua_event->obj);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0) {
if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("UST app event %s filter failed for app (pid: %d) "
goto error;
}
- ret = ustctl_set_exclusion(app->sock, ua_event->exclusion,
- ua_event->obj);
+ pthread_mutex_lock(&app->sock_lock);
+ ret = ustctl_set_exclusion(app->sock, ua_event->exclusion, ua_event->obj);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0) {
if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("UST app event %s exclusions failed for app (pid: %d) "
health_code_update();
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_disable(app->sock, ua_event->obj);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0) {
if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("UST app event %s disable failed for app (pid: %d) "
health_code_update();
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_disable(app->sock, ua_chan->obj);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0) {
if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("UST app channel %s disable failed for app (pid: %d) "
health_code_update();
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_enable(app->sock, ua_chan->obj);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0) {
if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("UST app channel %s enable failed for app (pid: %d) "
health_code_update();
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_enable(app->sock, ua_event->obj);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0) {
if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("UST app event %s enable failed for app (pid: %d) "
}
/* We don't need the stream anymore once sent to the tracer. */
cds_list_del(&stream->list);
- delete_ust_app_stream(-1, stream);
+ delete_ust_app_stream(-1, stream, app);
}
/* Flag the channel that it is sent to the application. */
ua_chan->is_sent = 1;
health_code_update();
/* Create UST event on tracer */
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_create_event(app->sock, &ua_event->attr, ua_chan->obj,
&ua_event->obj);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0) {
if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("Error ustctl create event %s for app pid: %d with ret %d",
health_code_update();
if (ua_sess->handle == -1) {
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_create_session(app->sock);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0) {
if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("Creating session for app pid %d with ret %d",
* Return 0 on success or else a negative value.
*/
static int setup_buffer_reg_streams(struct buffer_reg_channel *reg_chan,
- struct ust_app_channel *ua_chan)
+ struct ust_app_channel *ua_chan,
+ struct ust_app *app)
{
int ret = 0;
struct ust_app_stream *stream, *stmp;
/* We don't need the streams anymore. */
cds_list_del(&stream->list);
- delete_ust_app_stream(-1, stream);
+ delete_ust_app_stream(-1, stream, app);
}
error:
* Return 0 on success else a negative value.
*/
static int setup_buffer_reg_channel(struct buffer_reg_session *reg_sess,
- struct ust_app_channel *ua_chan, struct buffer_reg_channel *reg_chan)
+ struct ust_app_channel *ua_chan, struct buffer_reg_channel *reg_chan,
+ struct ust_app *app)
{
int ret;
DBG2("UST app setup buffer registry channel for %s", ua_chan->name);
/* Setup all streams for the registry. */
- ret = setup_buffer_reg_streams(reg_chan, ua_chan);
+ ret = setup_buffer_reg_streams(reg_chan, ua_chan, app);
if (ret < 0) {
goto error;
}
ret = ust_consumer_send_stream_to_ust(app, ua_chan, &stream);
if (ret < 0) {
- (void) release_ust_app_stream(-1, &stream);
+ (void) release_ust_app_stream(-1, &stream, app);
if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
ret = -ENOTCONN; /* Caused by app exiting. */
goto error_stream_unlock;
* The return value is not important here. This function will output an
* error if needed.
*/
- (void) release_ust_app_stream(-1, &stream);
+ (void) release_ust_app_stream(-1, &stream, app);
}
ua_chan->is_sent = 1;
/*
* Setup the streams and add it to the session registry.
*/
- ret = setup_buffer_reg_channel(reg_uid->registry, ua_chan, reg_chan);
+ ret = setup_buffer_reg_channel(reg_uid->registry,
+ ua_chan, reg_chan, app);
if (ret < 0) {
ERR("Error setting up UST channel \"%s\"",
ua_chan->name);
error:
/* Valid. Calling here is already in a read side lock */
- delete_ust_app_event(-1, ua_event);
+ delete_ust_app_event(-1, ua_event, app);
return ret;
}
lta->pid = msg->pid;
lttng_ht_node_init_ulong(<a->pid_n, (unsigned long) lta->pid);
lta->sock = sock;
+ pthread_mutex_init(<a->sock_lock, NULL);
lttng_ht_node_init_ulong(<a->sock_n, (unsigned long) lta->sock);
CDS_INIT_LIST_HEAD(<a->teardown_head);
-
error:
return lta;
}
assert(app);
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_tracer_version(app->sock, &app->version);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0) {
if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
ERR("UST app %d version failed with ret %d", app->sock, ret);
*/
continue;
}
+ pthread_mutex_lock(&app->sock_lock);
handle = ustctl_tracepoint_list(app->sock);
if (handle < 0) {
if (handle != -EPIPE && handle != -LTTNG_UST_ERR_EXITING) {
ERR("UST app list events getting handle failed for app pid %d",
app->pid);
}
+ pthread_mutex_unlock(&app->sock_lock);
continue;
}
&uiter)) != -LTTNG_UST_ERR_NOENT) {
/* Handle ustctl error. */
if (ret < 0) {
+ int release_ret;
+
if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
ERR("UST app tp list get failed for app %d with ret %d",
app->sock, ret);
break;
}
free(tmp_event);
+ release_ret = ustctl_release_handle(app->sock, handle);
+ if (release_ret != -LTTNG_UST_ERR_EXITING && release_ret != -EPIPE) {
+ ERR("Error releasing app handle for app %d with ret %d", app->sock, release_ret);
+ }
+ pthread_mutex_unlock(&app->sock_lock);
goto rcu_error;
}
new_tmp_event = realloc(tmp_event,
new_nbmem * sizeof(struct lttng_event));
if (new_tmp_event == NULL) {
+ int release_ret;
+
PERROR("realloc ust app events");
free(tmp_event);
ret = -ENOMEM;
+ release_ret = ustctl_release_handle(app->sock, handle);
+ if (release_ret != -LTTNG_UST_ERR_EXITING && release_ret != -EPIPE) {
+ ERR("Error releasing app handle for app %d with ret %d", app->sock, release_ret);
+ }
+ pthread_mutex_unlock(&app->sock_lock);
goto rcu_error;
}
/* Zero the new memory */
tmp_event[count].enabled = -1;
count++;
}
+ ret = ustctl_release_handle(app->sock, handle);
+ pthread_mutex_unlock(&app->sock_lock);
+ if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
+ ERR("Error releasing app handle for app %d with ret %d", app->sock, ret);
+ }
}
ret = count;
*/
continue;
}
+ pthread_mutex_lock(&app->sock_lock);
handle = ustctl_tracepoint_field_list(app->sock);
if (handle < 0) {
if (handle != -EPIPE && handle != -LTTNG_UST_ERR_EXITING) {
ERR("UST app list field getting handle failed for app pid %d",
app->pid);
}
+ pthread_mutex_unlock(&app->sock_lock);
continue;
}
&uiter)) != -LTTNG_UST_ERR_NOENT) {
/* Handle ustctl error. */
if (ret < 0) {
+ int release_ret;
+
if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
ERR("UST app tp list field failed for app %d with ret %d",
app->sock, ret);
break;
}
free(tmp_event);
+ release_ret = ustctl_release_handle(app->sock, handle);
+ pthread_mutex_unlock(&app->sock_lock);
+ if (release_ret != -LTTNG_UST_ERR_EXITING && release_ret != -EPIPE) {
+ ERR("Error releasing app handle for app %d with ret %d", app->sock, release_ret);
+ }
goto rcu_error;
}
new_tmp_event = realloc(tmp_event,
new_nbmem * sizeof(struct lttng_event_field));
if (new_tmp_event == NULL) {
+ int release_ret;
+
PERROR("realloc ust app event fields");
free(tmp_event);
ret = -ENOMEM;
+ release_ret = ustctl_release_handle(app->sock, handle);
+ pthread_mutex_unlock(&app->sock_lock);
+ if (release_ret != -LTTNG_UST_ERR_EXITING && release_ret != -EPIPE) {
+ ERR("Error releasing app handle for app %d with ret %d", app->sock, release_ret);
+ }
goto rcu_error;
}
/* Zero the new memory */
tmp_event[count].event.enabled = -1;
count++;
}
+ ret = ustctl_release_handle(app->sock, handle);
+ pthread_mutex_unlock(&app->sock_lock);
+ if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
+ ERR("Error releasing app handle for app %d with ret %d", app->sock, ret);
+ }
}
ret = count;
skip_setup:
/* This start the UST tracing */
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_start_session(app->sock, ua_sess->handle);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0) {
if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("Error starting tracing for app pid: %d (ret: %d)",
health_code_update();
/* Quiescent wait after starting trace */
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_wait_quiescent(app->sock);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("UST app wait quiescent failed for app pid %d ret %d",
app->pid, ret);
health_code_update();
/* This inhibits UST tracing */
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_stop_session(app->sock, ua_sess->handle);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0) {
if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("Error stopping tracing for app pid: %d (ret: %d)",
health_code_update();
/* Quiescent wait after stopping trace */
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_wait_quiescent(app->sock);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("UST app wait quiescent failed for app pid %d ret %d",
app->pid, ret);
health_code_update();
/* Quiescent wait after stopping trace */
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_wait_quiescent(app->sock);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
ERR("UST app wait quiescent failed for app pid %d ret %d",
app->pid, ret);
health_code_update();
+ pthread_mutex_lock(&app->sock_lock);
ret = ustctl_calibrate(app->sock, calibrate);
+ pthread_mutex_unlock(&app->sock_lock);
if (ret < 0) {
switch (ret) {
case -ENOSYS: