X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=libust%2Flttng-ust-comm.c;h=1e4031be273fcbcc7a29d397ab0bb8db3bbcfa22;hb=e822f505be95ac8c30c7b535a7b48c05ed0c1293;hp=0f7bc34b6ed14200af50f44731c89ca1ee1a4457;hpb=74d89c32c1f8928943e1ce7eae5d659d4fd601a9;p=lttng-ust.git diff --git a/libust/lttng-ust-comm.c b/libust/lttng-ust-comm.c index 0f7bc34b..1e4031be 100644 --- a/libust/lttng-ust-comm.c +++ b/libust/lttng-ust-comm.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,7 @@ #include #include #include +#include /* * Has lttng ust comm constructor been called ? @@ -541,3 +543,58 @@ void __attribute__((destructor)) lttng_ust_exit(void) ltt_ring_buffer_metadata_client_exit(); exit_tracepoint(); } + +/* + * We exclude the worker threads across fork and clone (except + * CLONE_VM), because these system calls only keep the forking thread + * running in the child. Therefore, we don't want to call fork or clone + * in the middle of an tracepoint or ust tracing state modification. + * Holding this mutex protects these structures across fork and clone. + */ +void ust_before_fork(ust_fork_info_t *fork_info) +{ + /* + * Disable signals. This is to avoid that the child intervenes + * before it is properly setup for tracing. It is safer to + * disable all signals, because then we know we are not breaking + * anything by restoring the original mask. + */ + sigset_t all_sigs; + int ret; + + /* Disable signals */ + sigfillset(&all_sigs); + ret = sigprocmask(SIG_BLOCK, &all_sigs, &fork_info->orig_sigs); + if (ret == -1) { + PERROR("sigprocmask"); + } + pthread_mutex_lock(<tng_ust_comm_mutex); + rcu_bp_before_fork(); +} + +static void ust_after_fork_common(ust_fork_info_t *fork_info) +{ + int ret; + + pthread_mutex_unlock(<tng_ust_comm_mutex); + /* Restore signals */ + ret = sigprocmask(SIG_SETMASK, &fork_info->orig_sigs, NULL); + if (ret == -1) { + PERROR("sigprocmask"); + } +} + +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) +{ + /* Release urcu mutexes */ + rcu_bp_after_fork_child(); + /* Release mutexes and reenable signals */ + ust_after_fork_common(fork_info); +}