The notification thread may receive commands issued through the
call_rcu thread during the destruction of some of the sessiond's
data structure.
This change tears down the notification thread after the clean-up
has occured and the issuance of an RCU barrier. This ensures that
all previously-queued call_rcu work has been performed and that
any ensuing notification thread commands have been queued in return.
It is safe, at that point, to queue a "quit" command in the
notification thread's command queue. The notification thread's
shutdown method will issue the command and wait for its completion
before returning.
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
/* Queue of rotation jobs populated by the sessiond-timer. */
struct rotation_thread_timer_queue *rotation_timer_queue = NULL;
struct lttng_thread *client_thread = NULL;
/* Queue of rotation jobs populated by the sessiond-timer. */
struct rotation_thread_timer_queue *rotation_timer_queue = NULL;
struct lttng_thread *client_thread = NULL;
+ struct lttng_thread *notification_thread = NULL;
init_kernel_workarounds();
init_kernel_workarounds();
}
/* Create notification thread. */
}
/* Create notification thread. */
- if (!launch_notification_thread(notification_thread_handle)) {
+ notification_thread = launch_notification_thread(
+ notification_thread_handle);
+ if (!notification_thread) {
retval = -1;
goto exit_notification;
}
retval = -1;
goto exit_notification;
}
rcu_thread_online();
sessiond_cleanup();
rcu_thread_online();
sessiond_cleanup();
+ if (notification_thread) {
+ lttng_thread_shutdown(notification_thread);
+ lttng_thread_put(notification_thread);
+ }
+
/*
* Ensure all prior call_rcu are done. call_rcu callbacks may push
* hash tables to the ht_cleanup thread. Therefore, we ensure that
/*
* Ensure all prior call_rcu are done. call_rcu callbacks may push
* hash tables to the ht_cleanup thread. Therefore, we ensure that
-bool launch_notification_thread(struct notification_thread_handle *handle)
+struct lttng_thread *launch_notification_thread(
+ struct notification_thread_handle *handle)
{
struct lttng_thread *thread;
{
struct lttng_thread *thread;
* (e.g. rotation thread).
*/
wait_until_thread_is_ready(handle);
* (e.g. rotation thread).
*/
wait_until_thread_is_ready(handle);
- lttng_thread_put(thread);
- return true;
#include <common/hashtable/hashtable.h>
#include <pthread.h>
#include <semaphore.h>
#include <common/hashtable/hashtable.h>
#include <pthread.h>
#include <semaphore.h>
struct notification_thread_handle {
/*
struct notification_thread_handle {
/*
struct lttng_pipe *kernel_channel_monitor_pipe);
void notification_thread_handle_destroy(
struct notification_thread_handle *handle);
struct lttng_pipe *kernel_channel_monitor_pipe);
void notification_thread_handle_destroy(
struct notification_thread_handle *handle);
-bool launch_notification_thread(struct notification_thread_handle *handle);
+struct lttng_thread *launch_notification_thread(
+ struct notification_thread_handle *handle);
#endif /* NOTIFICATION_THREAD_H */
#endif /* NOTIFICATION_THREAD_H */