extern struct chan_info_struct chan_infos[];
-static struct cds_list_head open_buffers_list = CDS_LIST_HEAD_INIT(open_buffers_list);
-
static struct cds_list_head ust_socks = CDS_LIST_HEAD_INIT(ust_socks);
/* volatile because shared between the listener and the main thread */
CMM_STORE_SHARED(buffers_to_export, CMM_LOAD_SHARED(buffers_to_export)-1);
}
- /* The buffer has been exported, ergo, we can add it to the
- * list of open buffers
- */
- cds_list_add(&buf->open_buffers_list, &open_buffers_list);
-
unlock_traces:
ltt_unlock_traces();
pthread_mutex_unlock(&listen_sock_mutex);
}
-static void force_subbuf_switch()
+static int force_subbuf_switch(const char *trace_name)
{
- struct ust_buffer *buf;
-
- cds_list_for_each_entry(buf, &open_buffers_list,
- open_buffers_list) {
- ltt_force_switch(buf, FORCE_FLUSH);
- }
-}
+ struct ust_trace *trace;
+ int i, j, retval = 0;
-/* Simple commands are those which need only respond with a return value. */
-static int process_simple_client_cmd(int command, char *recv_buf)
-{
- int result;
+ ltt_lock_traces();
+ trace = _ltt_trace_find(trace_name);
+ if (!trace) {
+ retval = -ENODATA;
+ DBG("Cannot find trace. It was likely destroyed by the user.");
+ goto unlock_traces;
+ }
- switch(command) {
- case SET_SOCK_PATH:
- {
- struct ustcomm_single_field *sock_msg;
- sock_msg = (struct ustcomm_single_field *)recv_buf;
- result = ustcomm_unpack_single_field(sock_msg);
- if (result < 0) {
- return result;
+ for (i = 0; i < trace->nr_channels; i++) {
+ for (j = 0; j < trace->channels[i].n_cpus; j++) {
+ ltt_force_switch(trace->channels[i].buf[j],
+ FORCE_FLUSH);
}
- return setenv("UST_DAEMON_SOCKET", sock_msg->field, 1);
}
- case FORCE_SUBBUF_SWITCH:
- /* FIXME: return codes? */
- force_subbuf_switch();
-
- break;
-
- default:
- return -EINVAL;
- }
+unlock_traces:
+ ltt_unlock_traces();
- return 0;
+ return retval;
}
-
static int process_trace_cmd(int command, char *trace_name)
{
int result;
return result;
}
return 0;
+ case FORCE_SUBBUF_SWITCH:
+ DBG("force switch");
+
+ result = force_subbuf_switch(trace_name);
+ if (result < 0) {
+ ERR("force_subbuf_switch failed");
+ return result;
+ }
+ return 0;
}
return 0;
print_markers(fp);
fclose(fp);
- reply_header->size = size;
+ reply_header->size = size + 1; /* Include final \0 */
result = ustcomm_send(sock, reply_header, ptr);
print_trace_events(fp);
fclose(fp);
- reply_header->size = size;
+ reply_header->size = size + 1; /* Include final \0 */
result = ustcomm_send(sock, reply_header, ptr);
goto send_response;
}
+ case SET_SOCK_PATH:
+ {
+ struct ustcomm_single_field *sock_msg;
+ sock_msg = (struct ustcomm_single_field *)recv_buf;
+ result = ustcomm_unpack_single_field(sock_msg);
+ if (result < 0) {
+ reply_header->result = -EINVAL;
+ goto send_response;
+ }
+
+ reply_header->result = setenv("UST_DAEMON_SOCKET",
+ sock_msg->field, 1);
+
+ goto send_response;
+ }
case START:
case SETUP_TRACE:
case ALLOC_TRACE:
case START_TRACE:
case STOP_TRACE:
case DESTROY_TRACE:
+ case FORCE_SUBBUF_SWITCH:
{
struct ustcomm_single_field *trace_inf =
(struct ustcomm_single_field *)recv_buf;
}
default:
- reply_header->result =
- process_simple_client_cmd(recv_header->command,
- recv_buf);
- goto send_response;
+ reply_header->result = -EINVAL;
+ goto send_response;
}
return;
ustcomm_del_sock(sock, 1);
}
- /* Delete all blocked consumers */
- cds_list_for_each_entry_safe(buf, buf_tmp, &open_buffers_list,
- open_buffers_list) {
- cds_list_del(&buf->open_buffers_list);
- }
-
/*
* FIXME: This could be prettier, we loop over the list twice and
* following good locking practice should lock around the loop
* Hold listen_sock_mutex to protect from listen_sock teardown.
*/
pthread_mutex_lock(&listen_sock_mutex);
+ rcu_bp_before_fork();
}
/* Don't call this function directly in a traced program */
void ust_after_fork_parent(ust_fork_info_t *fork_info)
{
+ rcu_bp_after_fork_parent();
/* Release mutexes and reenable signals */
ust_after_fork_common(fork_info);
}
void ust_after_fork_child(ust_fork_info_t *fork_info)
{
- /* First sanitize the child */
+ /* Release urcu mutexes */
+ rcu_bp_after_fork_child();
+
+ /* Sanitize the child */
ust_fork();
/* Then release mutexes and reenable signals */
ust_after_fork_common(fork_info);
-
- /*
- * Make sure we clean up the urcu-bp thread list in the child by running
- * the garbage collection before any pthread_create can be called.
- * Failure to do so could lead to a deadlock caused by reuse of a thread
- * ID before urcu-bp garbage collection is performed.
- */
- synchronize_rcu();
}