* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/* This file contains the implementation of the UST listener thread, which
+ * receives trace control commands. It also coordinates the initialization of
+ * libust.
+ */
+
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
*/
s64 pidunique = -1LL;
+extern struct chan_info_struct chan_infos[];
+
struct list_head blocked_consumers = LIST_HEAD_INIT(blocked_consumers);
static struct ustcomm_app ustcomm_app;
static unsigned int pow2_higher_or_eq(unsigned int v)
{
int hb = fls(v);
- int hbm1 = hb-1;
int retval = 1<<(hb-1);
if(v-retval == 0)
ustcomm_fini_app(&ustcomm_app, 0);
}
+static void do_cmd_force_switch()
+{
+ struct blocked_consumer *bc;
+
+ list_for_each_entry(bc, &blocked_consumers, list) {
+ ltt_force_switch(bc->buf, FORCE_FLUSH);
+ }
+}
+
int process_client_cmd(char *recvbuf, struct ustcomm_source *src)
{
int result;
free(reply);
}
+ else if(nth_token_is(recvbuf, "get_sock_path", 0) == 1) {
+ char *reply = getenv("UST_DAEMON_SOCKET");
+ if(!reply) {
+ asprintf(&reply, "%s/%s", SOCK_DIR, "ustd");
+ result = ustcomm_send_reply(&ustcomm_app.server, reply, src);
+ free(reply);
+ }
+ else {
+ result = ustcomm_send_reply(&ustcomm_app.server, reply, src);
+ }
+ if(result)
+ ERR("ustcomm_send_reply failed");
+ }
+ else if(nth_token_is(recvbuf, "set_sock_path", 0) == 1) {
+ char *sock_path = nth_token(recvbuf, 1);
+ result = setenv("UST_DAEMON_SOCKET", sock_path, 1);
+ if(result)
+ ERR("cannot set UST_DAEMON_SOCKET environment variable");
+ }
+ else if(nth_token_is(recvbuf, "force_switch", 0) == 1) {
+ do_cmd_force_switch();
+ }
else {
ERR("unable to parse message: %s", recvbuf);
}
if(result) {
PERROR("pthread_sigmask: %s", strerror(result));
}
-
- have_listener = 1;
+ else {
+ have_listener = 1;
+ }
}
static int init_socket(void)
{
int result;
char* autoprobe_val = NULL;
+ char* subbuffer_size_val = NULL;
+ char* subbuffer_count_val = NULL;
+ unsigned int subbuffer_size;
+ unsigned int subbuffer_count;
+ unsigned int power;
/* Assign the pidunique, to be able to differentiate the processes with same
* pid, (before and after an exec).
}
}
+ subbuffer_size_val = getenv("UST_SUBBUF_SIZE");
+ if(subbuffer_size_val) {
+ sscanf(subbuffer_size_val, "%u", &subbuffer_size);
+ power = pow2_higher_or_eq(subbuffer_size);
+ if(power != subbuffer_size)
+ WARN("using the next power of two for buffer size = %u\n", power);
+ chan_infos[LTT_CHANNEL_UST].def_subbufsize = power;
+ }
+
+ subbuffer_count_val = getenv("UST_SUBBUF_NUM");
+ if(subbuffer_count_val) {
+ sscanf(subbuffer_count_val, "%u", &subbuffer_count);
+ if(subbuffer_count < 2)
+ subbuffer_count = 2;
+ chan_infos[LTT_CHANNEL_UST].def_subbufcount = subbuffer_count;
+ }
+
if(getenv("UST_TRACE")) {
char trace_name[] = "auto";
char trace_type[] = "ustrelay";
inform_consumer_daemon(trace_name);
}
-
return;
/* should decrementally destroy stuff if error */
return result;
}
-static void stop_listener()
+static void stop_listener(void)
{
int result;
+ if(!have_listener)
+ return;
+
result = pthread_cancel(listener_thread);
if(result != 0) {
ERR("pthread_cancel: %s", strerror(result));