*/
static int sem_count = { 2 };
+/*
+ * Counting nesting within lttng-ust. Used to ensure that calling fork()
+ * from liblttng-ust does not execute the pre/post fork handlers.
+ */
+static int __thread lttng_ust_nest_count;
+
/*
* Info about socket and associated listener thread.
*/
extern void ltt_ring_buffer_client_discard_exit(void);
extern void ltt_ring_buffer_metadata_client_exit(void);
+/*
+ * Force a read (imply TLS fixup for dlopen) of TLS variables.
+ */
+static
+void lttng_fixup_nest_count_tls(void)
+{
+ asm volatile ("" : : "m" (lttng_ust_nest_count));
+}
+
static
int setup_local_apps(void)
{
* If the open failed because the file did not exist, try
* creating it ourself.
*/
+ lttng_ust_nest_count++;
pid = fork();
+ lttng_ust_nest_count--;
if (pid > 0) {
int status;
lttng_fixup_event_tls();
lttng_fixup_ringbuffer_tls();
lttng_fixup_vtid_tls();
+ lttng_fixup_nest_count_tls();
/*
* We want precise control over the order in which we construct
sigset_t all_sigs;
int ret;
+ if (lttng_ust_nest_count)
+ return;
/* Disable signals */
sigfillset(&all_sigs);
ret = sigprocmask(SIG_BLOCK, &all_sigs, save_sigset);
void ust_after_fork_parent(sigset_t *restore_sigset)
{
+ if (lttng_ust_nest_count)
+ return;
DBG("process %d", getpid());
rcu_bp_after_fork_parent();
/* Release mutexes and reenable signals */
*/
void ust_after_fork_child(sigset_t *restore_sigset)
{
+ if (lttng_ust_nest_count)
+ return;
DBG("process %d", getpid());
/* Release urcu mutexes */
rcu_bp_after_fork_child();