#include <sched.h>
#include <fcntl.h>
#include <poll.h>
+#include <regex.h>
#include <urcu.h>
return 0;
}
+static regex_t preg;
+static int regex_is_ok = -1;
+
static void auto_probe_connect(struct marker *m)
{
int result;
+ char* comp_name = NULL;
+ char* regex;
+
+ if (regex_is_ok != 0) {
+ goto end;
+ }
+
+ if (asprintf(&comp_name, "%s/%s", m->channel, m->name) == -1) {
+ ERR("auto_probe_connect: `asprintf' failed (marker %s/%s)",
+ m->channel, m->name);
+ return;
+ }
+ if (regexec(&preg, comp_name, 0, NULL, 0) != 0) {
+ goto end; /* Not matching */
+ }
+
+// connect:
+
result = ltt_marker_connect(m->channel, m->name, "default");
if(result && result != -EEXIST)
ERR("ltt_marker_connect (marker = %s/%s, errno = %d)", m->channel, m->name, -result);
DBG("just auto connected marker %s %s to probe default", m->channel, m->name);
+
+ end:
+ if (comp_name != NULL) {
+ free(comp_name);
+ }
}
static void __attribute__((constructor(101))) init0()
static void __attribute__((constructor(1000))) init()
{
int result;
+ char* regex = NULL;
/* Initialize RCU in case the constructor order is not good. */
urcu_init();
return;
}
- if(getenv("UST_AUTOPROBE")) {
+ regex = getenv("UST_AUTOPROBE");
+ if(regex) {
+ char* regex = NULL;
struct marker_iter iter;
DBG("IN AUTOPROBE\n");
* probe on new markers
*/
marker_set_new_marker_cb(auto_probe_connect);
-
+ regex_is_ok = regcomp(&preg, regex, 0);
+ if (regex_is_ok) {
+ ERR("cannot parse regex %s", regex);
+ }
/* Now, connect the probes that were already registered. */
marker_iter_reset(&iter);
marker_iter_start(&iter);
}
#endif
+#if 0
+static int trace_recording(void)
+{
+ int retval = 0;
+ struct ltt_trace_struct *trace;
+
+ ltt_lock_traces();
+
+ list_for_each_entry(trace, <t_traces.head, list) {
+ if(trace->active) {
+ retval = 1;
+ break;
+ }
+ }
+
+ ltt_unlock_traces();
+
+ return retval;
+}
+
+static int have_consumer(void)
+{
+ return !list_empty(&blocked_consumers);
+}
+
+/* This destructor keeps the process alive for a few seconds in order
+ * to leave time to ustd to consume its buffers.
+ */
+
+int restarting_sleep(int secs)
+{
+ struct timespec tv;
+ int result;
+
+ tv.tv_sec = secs;
+ tv.tv_nsec = 0;
+
+ do {
+ result = nanosleep(&tv, &tv);
+ } while(result == -1 && errno == EINTR);
+
+ return result;
+}
+
+static void __attribute__((destructor)) keepalive()
+{
+// struct ustcomm_ustd ustd;
+// int result;
+// sigset_t sigset;
+//
+// result = sigemptyset(&sigset);
+// if(result == -1) {
+// perror("sigemptyset");
+// return;
+// }
+// result = sigaddset(&sigset, SIGIO);
+// if(result == -1) {
+// perror("sigaddset");
+// return;
+// }
+// result = sigprocmask(SIG_BLOCK, &sigset, NULL);
+// if(result == -1) {
+// perror("sigprocmask");
+// return;
+// }
+//
+// if(trace_recording()) {
+// if(!have_consumer()) {
+// /* Request listener creation. We've blocked SIGIO's in
+// * order to not interrupt sleep(), so we will miss the
+// * one sent by the daemon and therefore won't create
+// * the listener automatically.
+// */
+// create_listener();
+//
+ printf("Keeping process alive for consumer daemon...\n");
+ restarting_sleep(3);
+ printf("Finally dying...\n");
+// }
+// }
+//
+// result = sigprocmask(SIG_UNBLOCK, &sigset, NULL);
+// if(result == -1) {
+// perror("sigprocmask");
+// return;
+// }
+}
+#endif
+
/* Notify ust that there was a fork. This needs to be called inside
* the new process, anytime a process whose memory is not shared with
* the parent is created. If this function is not called, the events