static pthread_mutex_t kconsumerd_pid_mutex; /* Mutex to control kconsumerd pid assignation */
+/*
+ * Pointer initialized before thread creation.
+ *
+ * This points to the tracing session list containing the session count and a
+ * mutex lock. The lock MUST be taken if you iterate over the list. The lock
+ * MUST NOT be taken if you call a public function in session.c.
+ */
+static struct ltt_session_list *session_list_ptr;
+
/*
* teardown_kernel_session
*
- * Complete teardown of a kernel session. This free all data structure
- * related to a kernel session and update counter.
+ * Complete teardown of a kernel session. This free all data structure related
+ * to a kernel session and update counter.
*/
static void teardown_kernel_session(struct ltt_session *session)
{
DBG("Cleaning up all session");
/* Cleanup ALL session */
- cds_list_for_each_entry(sess, <t_session_list.head, list) {
+ cds_list_for_each_entry(sess, &session_list_ptr->head, list) {
teardown_kernel_session(sess);
// TODO complete session cleanup (including UST)
}
+ /* Destroy session list mutex */
+ pthread_mutex_destroy(&session_list_ptr->lock);
+
DBG("Closing kernel fd");
close(kernel_tracer_fd);
close(kernel_poll_pipe[0]);
DBG("Updating kernel_pollfd");
/* Get the number of channel of all kernel session */
- cds_list_for_each_entry(session, <t_session_list.head, list) {
+ pthread_mutex_lock(&session_list_ptr->lock);
+ cds_list_for_each_entry(session, &session_list_ptr->head, list) {
+ lock_session(session);
if (session->kernel_session == NULL) {
+ unlock_session(session);
continue;
}
nb_fd += session->kernel_session->channel_count;
+ unlock_session(session);
}
DBG("Resizing kernel_pollfd to size %d", nb_fd);
goto error;
}
- cds_list_for_each_entry(session, <t_session_list.head, list) {
+ cds_list_for_each_entry(session, &session_list_ptr->head, list) {
+ lock_session(session);
if (session->kernel_session == NULL) {
+ unlock_session(session);
continue;
}
if (i >= nb_fd) {
ERR("To much channel for kernel_pollfd size");
+ unlock_session(session);
break;
}
cds_list_for_each_entry(channel, &session->kernel_session->channel_list.head, list) {
kernel_pollfd[i].events = POLLIN | POLLRDNORM;
i++;
}
+ unlock_session(session);
}
+ pthread_mutex_unlock(&session_list_ptr->lock);
/* Adding wake up pipe */
kernel_pollfd[nb_fd - 1].fd = kernel_poll_pipe[0];
return nb_fd;
error:
+ pthread_mutex_unlock(&session_list_ptr->lock);
return -1;
}
DBG("Updating kernel streams for channel fd %d", fd);
- cds_list_for_each_entry(session, <t_session_list.head, list) {
+ pthread_mutex_lock(&session_list_ptr->lock);
+ cds_list_for_each_entry(session, &session_list_ptr->head, list) {
+ lock_session(session);
if (session->kernel_session == NULL) {
+ unlock_session(session);
continue;
}
cds_list_for_each_entry(channel, &session->kernel_session->channel_list.head, list) {
goto end;
}
}
+ unlock_session(session);
}
end:
+ if (session) {
+ unlock_session(session);
+ }
+ pthread_mutex_unlock(&session_list_ptr->lock);
return ret;
}
* Check if the wake up pipe was triggered. If so, the kernel_pollfd
* must be updated.
*/
- if (kernel_pollfd[nb_fd - 1].revents == POLLIN) {
+ switch (kernel_pollfd[nb_fd - 1].revents) {
+ case POLLIN:
ret = read(kernel_poll_pipe[0], &tmp, 1);
update_poll_flag = 1;
continue;
+ case POLLERR:
+ goto error;
+ default:
+ break;
}
for (i = 0; i < nb_fd; i++) {
ret = LTTCOMM_SELECT_SESS;
}
goto error;
+ } else {
+ /* Acquire lock for the session */
+ lock_session(cmd_ctx->session);
}
break;
}
/* Set return code */
cmd_ctx->llm->ret_code = ret;
+ if (cmd_ctx->session) {
+ unlock_session(cmd_ctx->session);
+ }
+
return ret;
error:
cmd_ctx->llm->ret_code = ret;
setup_error:
+ if (cmd_ctx->session) {
+ unlock_session(cmd_ctx->session);
+ }
return ret;
}
goto error;
}
+ /* Get session list pointer */
+ session_list_ptr = get_session_list();
+
while (1) {
/* Create thread to manage the client socket */
ret = pthread_create(&client_thread, NULL, thread_manage_clients, (void *) NULL);