X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=liblttng-ust%2Flttng-ust-comm.c;h=256cbdc625ef19f6da306124542a6e0a08ab593f;hb=9e16611568f395e9b646ecee0906a5a1e3bb7110;hp=597712bc1313057daaa4ee32730b46c3951eb78d;hpb=86e361632f8cb161d6cf3cfd1bb964a7f7fa0a52;p=lttng-ust.git diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c index 597712bc..256cbdc6 100644 --- a/liblttng-ust/lttng-ust-comm.c +++ b/liblttng-ust/lttng-ust-comm.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,7 @@ #include "lttng-tracer-core.h" #include "compat.h" #include "../libringbuffer/tlsfixup.h" +#include "lttng-ust-baddr.h" /* * Has lttng ust comm constructor been called ? @@ -106,6 +108,8 @@ struct sock_info { char wait_shm_path[PATH_MAX]; char *wait_shm_mmap; + /* Keep track of lazy state dump not performed yet. */ + int statedump_pending; }; /* Socket from app (connect) to session daemon (listen) for communication */ @@ -122,6 +126,8 @@ struct sock_info global_apps = { .notify_socket = -1, .wait_shm_path = "/" LTTNG_UST_WAIT_FILENAME, + + .statedump_pending = 0, }; /* TODO: allow global_apps_sock_path override */ @@ -135,6 +141,8 @@ struct sock_info local_apps = { .socket = -1, .notify_socket = -1, + + .statedump_pending = 0, }; static int wait_poll_fallback; @@ -380,6 +388,28 @@ int handle_register_done(struct sock_info *sock_info) return 0; } +/* + * Only execute pending statedump after the constructor semaphore has + * been posted by each listener thread. This means statedump will only + * be performed after the "registration done" command is received from + * each session daemon the application is connected to. + * + * This ensures we don't run into deadlock issues with the dynamic + * loader mutex, which is held while the constructor is called and + * waiting on the constructor semaphore. All operations requiring this + * dynamic loader lock need to be postponed using this mechanism. + */ +static +void handle_pending_statedump(struct sock_info *sock_info) +{ + int ctor_passed = sock_info->constructor_sem_posted; + + if (ctor_passed && sock_info->statedump_pending) { + sock_info->statedump_pending = 0; + lttng_handle_pending_statedump(sock_info); + } +} + static int handle_message(struct sock_info *sock_info, int sock, struct ustcomm_ust_msg *lum) @@ -698,6 +728,14 @@ end: error: ust_unlock(); + + /* + * Performed delayed statedump operations outside of the UST + * lock. We need to take the dynamic loader lock before we take + * the UST lock internally within handle_pending_statedump(). + */ + handle_pending_statedump(sock_info); + return ret; } @@ -1519,3 +1557,9 @@ void ust_after_fork_child(sigset_t *restore_sigset) ust_after_fork_common(restore_sigset); lttng_ust_init(); } + +void lttng_ust_sockinfo_session_enabled(void *owner) +{ + struct sock_info *sock_info = owner; + sock_info->statedump_pending = 1; +}