ht_cleanup_push(app->ust_sessions_objd);
ht_cleanup_push(app->ust_objd);
+ /*
+ * This could be NULL if the event notifier setup failed (e.g the app
+ * was killed or the tracer does not support this feature).
+ */
+ if (app->event_notifier_group.object) {
+ enum lttng_error_code ret_code;
+ const int event_notifier_read_fd = lttng_pipe_get_readfd(
+ app->event_notifier_group.event_pipe);
+
+ ret_code = notification_thread_command_remove_tracer_event_source(
+ notification_thread_handle,
+ event_notifier_read_fd);
+ if (ret_code != LTTNG_OK) {
+ ERR("Failed to remove application tracer event source from notification thread");
+ }
+
+ ustctl_release_object(sock, app->event_notifier_group.object);
+ free(app->event_notifier_group.object);
+ }
+
+ lttng_pipe_destroy(app->event_notifier_group.event_pipe);
+
/*
* Wait until we have deleted the application from the sock hash table
* before closing this socket, otherwise an application could re-use the
struct ust_app *ust_app_create(struct ust_register_msg *msg, int sock)
{
struct ust_app *lta = NULL;
+ struct lttng_pipe *event_notifier_event_source_pipe = NULL;
assert(msg);
assert(sock >= 0);
goto error;
}
+ event_notifier_event_source_pipe = lttng_pipe_open(FD_CLOEXEC);
+ if (!event_notifier_event_source_pipe) {
+ PERROR("Failed to open application event source pipe: '%s' (ppid = %d)",
+ msg->name, msg->ppid);
+ goto error;
+ }
+
lta = zmalloc(sizeof(struct ust_app));
if (lta == NULL) {
PERROR("malloc");
- goto error;
+ goto error_free_pipe;
}
+ lta->event_notifier_group.event_pipe = event_notifier_event_source_pipe;
+
lta->ppid = msg->ppid;
lta->uid = msg->uid;
lta->gid = msg->gid;
lttng_ht_node_init_ulong(<a->sock_n, (unsigned long) lta->sock);
CDS_INIT_LIST_HEAD(<a->teardown_head);
-error:
return lta;
+
+error_free_pipe:
+ lttng_pipe_destroy(event_notifier_event_source_pipe);
+error:
+ return NULL;
}
/*
return ret;
}
+/*
+ * Setup the base event notifier group.
+ *
+ * Return 0 on success else a negative value either an errno code or a
+ * LTTng-UST error code.
+ */
+int ust_app_setup_event_notifier_group(struct ust_app *app)
+{
+ int ret;
+ int event_pipe_write_fd;
+ struct lttng_ust_object_data *event_notifier_group = NULL;
+ enum lttng_error_code lttng_ret;
+
+ assert(app);
+
+ /* Get the write side of the pipe. */
+ event_pipe_write_fd = lttng_pipe_get_writefd(
+ app->event_notifier_group.event_pipe);
+
+ pthread_mutex_lock(&app->sock_lock);
+ ret = ustctl_create_event_notifier_group(app->sock,
+ event_pipe_write_fd, &event_notifier_group);
+ pthread_mutex_unlock(&app->sock_lock);
+ if (ret < 0) {
+ if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
+ ERR("Failed to create application event notifier group: ret = %d, app socket fd = %d, event_pipe_write_fd = %d",
+ ret, app->sock, event_pipe_write_fd);
+ } else {
+ DBG("Failed to create application event notifier group (application is dead): app socket fd = %d",
+ app->sock);
+ }
+
+ goto error;
+ }
+
+ lttng_ret = notification_thread_command_add_tracer_event_source(
+ notification_thread_handle,
+ lttng_pipe_get_readfd(app->event_notifier_group.event_pipe),
+ LTTNG_DOMAIN_UST);
+ if (lttng_ret != LTTNG_OK) {
+ ERR("Failed to add tracer event source to notification thread");
+ ret = - 1;
+ goto error;
+ }
+
+ /* Assign handle only when the complete setup is valid. */
+ app->event_notifier_group.object = event_notifier_group;
+ return ret;
+
+error:
+ ustctl_release_object(app->sock, app->event_notifier_group.object);
+ free(app->event_notifier_group.object);
+ return ret;
+}
+
/*
* Unregister app by removing it from the global traceable app list and freeing
* the data struct.
* Used for path creation
*/
time_t registration_time;
+ /*
+ * Event notifier
+ */
+ struct {
+ /*
+ * Handle to the lttng_ust object representing the event
+ * notifier group.
+ */
+ struct lttng_ust_object_data *object;
+ struct lttng_pipe *event_pipe;
+ } event_notifier_group;
};
#ifdef HAVE_LIBLTTNG_UST_CTL
enum lttng_error_code ust_app_clear_session(struct ltt_session *session);
enum lttng_error_code ust_app_open_packets(struct ltt_session *session);
+int ust_app_setup_event_notifier_group(struct ust_app *app);
+
static inline
int ust_app_supported(void)
{
void ust_app_global_update(struct ltt_ust_session *usess, struct ust_app *app)
{}
static inline
+void ust_app_global_update_tokens(struct ust_app *app)
+{}
+static inline
+int ust_app_setup_event_notifier_group(struct ust_app *app)
+{
+ return 0;
+}
+static inline
int ust_app_disable_channel_glb(struct ltt_ust_session *usess,
struct ltt_ust_channel *uchan)
{