libust: remove process_simple_client_cmd function
[ust.git] / libust / tracectl.c
index 3b60975391abf72c155f9822a1b06fe3db68004d..f59edd35902eacd94c7b8c52bbead9f397a753d5 100644 (file)
@@ -543,6 +543,11 @@ unlock_traces:
        return retval;
 }
 
+static void release_listener_mutex(void *ptr)
+{
+       pthread_mutex_unlock(&listener_thread_data_mutex);
+}
+
 static void listener_cleanup(void *ptr)
 {
        pthread_mutex_lock(&listen_sock_mutex);
@@ -553,47 +558,32 @@ static void listener_cleanup(void *ptr)
        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;
@@ -711,6 +701,15 @@ static int process_trace_cmd(int command, char *trace_name)
                        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;
@@ -952,7 +951,7 @@ static void process_client_cmd(struct ustcomm_header *recv_header,
                print_markers(fp);
                fclose(fp);
 
-               reply_header->size = size;
+               reply_header->size = size + 1;  /* Include final \0 */
 
                result = ustcomm_send(sock, reply_header, ptr);
 
@@ -978,7 +977,7 @@ static void process_client_cmd(struct ustcomm_header *recv_header,
                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);
 
@@ -1036,6 +1035,21 @@ static void process_client_cmd(struct ustcomm_header *recv_header,
 
                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:
@@ -1043,6 +1057,7 @@ static void process_client_cmd(struct ustcomm_header *recv_header,
        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;
@@ -1061,11 +1076,9 @@ static void process_client_cmd(struct ustcomm_header *recv_header,
 
        }
        default:
-               reply_header->result =
-                       process_simple_client_cmd(recv_header->command,
-                                                 recv_buf);
-               goto send_response;
+               reply_header->result = -EINVAL;
 
+               goto send_response;
        }
 
        return;
@@ -1096,6 +1109,7 @@ void *listener_main(void *p)
 
                for (i = 0; i < nfds; i++) {
                        pthread_mutex_lock(&listener_thread_data_mutex);
+                       pthread_cleanup_push(release_listener_mutex, NULL);
                        epoll_sock = (struct ustcomm_sock *)events[i].data.ptr;
                        if (epoll_sock == listen_sock) {
                                addr_size = sizeof(struct sockaddr);
@@ -1124,7 +1138,7 @@ void *listener_main(void *p)
                                                           epoll_sock->fd);
                                }
                        }
-                       pthread_mutex_unlock(&listener_thread_data_mutex);
+                       pthread_cleanup_pop(1); /* release listener mutex */
                }
        }
 
@@ -1691,6 +1705,7 @@ void ust_before_fork(ust_fork_info_t *fork_info)
         * 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 */
@@ -1711,24 +1726,20 @@ static void ust_after_fork_common(ust_fork_info_t *fork_info)
 
 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();
 }
 
This page took 0.024368 seconds and 4 git commands to generate.