Do NOT join threads: use of sys_futex makes it impossible to join the
threads without using async-cancel, but async-cancel is delivered by a
signal, which could hit the target thread anywhere in its code path,
including while the ust_lock() is held, causing a deadlock for the other
thread. Let the OS cleanup the threads if there are stalled in a
syscall.
wait_shm_mmap is used by listener threads outside of the ust lock, so we
cannot tear it down ourselves, because we cannot join on these threads.
Leave this task to the OS process exit.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
-void cleanup_sock_info(struct sock_info *sock_info)
+void cleanup_sock_info(struct sock_info *sock_info, int exiting)
sock_info->root_handle = -1;
}
sock_info->constructor_sem_posted = 0;
sock_info->root_handle = -1;
}
sock_info->constructor_sem_posted = 0;
- if (sock_info->wait_shm_mmap) {
+ /*
+ * wait_shm_mmap is used by listener threads outside of the
+ * ust lock, so we cannot tear it down ourselves, because we
+ * cannot join on these threads. Leave this task to the OS
+ * process exit.
+ */
+ if (!exiting && sock_info->wait_shm_mmap) {
ret = munmap(sock_info->wait_shm_mmap, sysconf(_SC_PAGE_SIZE));
if (ret) {
ERR("Error unmapping wait shm");
ret = munmap(sock_info->wait_shm_mmap, sysconf(_SC_PAGE_SIZE));
if (ret) {
ERR("Error unmapping wait shm");
static
void wait_for_sessiond(struct sock_info *sock_info)
{
static
void wait_for_sessiond(struct sock_info *sock_info)
{
ust_lock();
if (lttng_ust_comm_should_quit) {
ust_lock();
if (lttng_ust_comm_should_quit) {
ust_unlock();
DBG("Waiting for %s apps sessiond", sock_info->name);
ust_unlock();
DBG("Waiting for %s apps sessiond", sock_info->name);
- /*
- * sys_futex does not honor pthread cancel requests. Set to
- * async.
- */
- ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
- if (ret) {
- ERR("Error setting thread cancel type");
- }
/* Wait for futex wakeup */
if (uatomic_read((int32_t *) sock_info->wait_shm_mmap) == 0) {
ret = futex_async((int32_t *) sock_info->wait_shm_mmap,
/* Wait for futex wakeup */
if (uatomic_read((int32_t *) sock_info->wait_shm_mmap) == 0) {
ret = futex_async((int32_t *) sock_info->wait_shm_mmap,
- ret = pthread_setcanceltype(oldtype, &oldtype);
- if (ret) {
- ERR("Error setting thread cancel type");
- }
static
void lttng_ust_cleanup(int exiting)
{
static
void lttng_ust_cleanup(int exiting)
{
- cleanup_sock_info(&global_apps);
+ cleanup_sock_info(&global_apps, exiting);
if (local_apps.allowed) {
if (local_apps.allowed) {
- cleanup_sock_info(&local_apps);
+ cleanup_sock_info(&local_apps, exiting);
+ /*
+ * The teardown in this function all affect data structures
+ * accessed under the UST lock by the listener thread. This
+ * lock, along with the lttng_ust_comm_should_quit flag, ensure
+ * that none of these threads are accessing this data at this
+ * point.
+ */
lttng_ust_abi_exit();
lttng_ust_events_exit();
ltt_ring_buffer_client_discard_exit();
lttng_ust_abi_exit();
lttng_ust_events_exit();
ltt_ring_buffer_client_discard_exit();
ERR("Error cancelling local ust listener thread");
}
}
ERR("Error cancelling local ust listener thread");
}
}
- /* join threads */
- ret = pthread_join(global_apps.ust_listener, NULL);
- if (ret) {
- ERR("Error joining global ust listener thread");
- }
- if (local_apps.allowed) {
- ret = pthread_join(local_apps.ust_listener, NULL);
- if (ret) {
- ERR("Error joining local ust listener thread");
- }
- }
+ /*
+ * Do NOT join threads: use of sys_futex makes it impossible to
+ * join the threads without using async-cancel, but async-cancel
+ * is delivered by a signal, which could hit the target thread
+ * anywhere in its code path, including while the ust_lock() is
+ * held, causing a deadlock for the other thread. Let the OS
+ * cleanup the threads if there are stalled in a syscall.
+ */