| 1 | /* |
| 2 | * Copyright (C) 2017 Julien Desfossez <jdesfossez@efficios.com> |
| 3 | * Copyright (C) 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com> |
| 4 | * |
| 5 | * SPDX-License-Identifier: GPL-2.0-only |
| 6 | * |
| 7 | */ |
| 8 | |
| 9 | #ifndef ROTATION_THREAD_H |
| 10 | #define ROTATION_THREAD_H |
| 11 | |
| 12 | #include "notification-thread.hpp" |
| 13 | #include "session.hpp" |
| 14 | |
| 15 | #include <common/compat/poll.hpp> |
| 16 | #include <common/eventfd.hpp> |
| 17 | #include <common/hashtable/hashtable.hpp> |
| 18 | #include <common/make-unique-wrapper.hpp> |
| 19 | #include <common/pipe.hpp> |
| 20 | |
| 21 | #include <lttng/domain.h> |
| 22 | #include <lttng/notification/channel-internal.hpp> |
| 23 | |
| 24 | #include <memory> |
| 25 | #include <pthread.h> |
| 26 | #include <semaphore.h> |
| 27 | #include <urcu.h> |
| 28 | #include <urcu/list.h> |
| 29 | #include <urcu/rculfhash.h> |
| 30 | |
| 31 | namespace lttng { |
| 32 | namespace sessiond { |
| 33 | |
| 34 | enum class rotation_thread_job_type { SCHEDULED_ROTATION, CHECK_PENDING_ROTATION }; |
| 35 | |
| 36 | struct rotation_thread_timer_queue; |
| 37 | |
| 38 | class rotation_thread { |
| 39 | public: |
| 40 | using uptr = std::unique_ptr<rotation_thread>; |
| 41 | |
| 42 | rotation_thread(rotation_thread_timer_queue& rotation_timer_queue, |
| 43 | notification_thread_handle& notification_thread_handle); |
| 44 | rotation_thread(const rotation_thread&) = delete; |
| 45 | rotation_thread(rotation_thread&&) = delete; |
| 46 | rotation_thread& operator=(const rotation_thread&) = delete; |
| 47 | rotation_thread& operator=(rotation_thread&&) = delete; |
| 48 | ~rotation_thread(); |
| 49 | |
| 50 | /* Only use through the lttng_thread facilities. */ |
| 51 | void launch_thread(); |
| 52 | bool shutdown() const noexcept; |
| 53 | |
| 54 | /* |
| 55 | * Subscribe/unsubscribe the rotation_thread's notification_channel to/from |
| 56 | * session usage notifications to perform size-based rotations. |
| 57 | */ |
| 58 | void subscribe_session_consumed_size_rotation(ltt_session& session, std::uint64_t size); |
| 59 | void unsubscribe_session_consumed_size_rotation(ltt_session& session); |
| 60 | |
| 61 | private: |
| 62 | void _thread_function() noexcept; |
| 63 | void _run(); |
| 64 | void _handle_job_queue(); |
| 65 | void _handle_notification(const lttng_notification& notification); |
| 66 | void _handle_notification_channel_activity(); |
| 67 | |
| 68 | struct rotation_thread_timer_queue& _rotation_timer_queue; |
| 69 | /* Access to the notification thread cmd_queue */ |
| 70 | notification_thread_handle& _notification_thread_handle; |
| 71 | /* Thread-specific quit pipe. */ |
| 72 | lttng_pipe::uptr _quit_pipe; |
| 73 | lttng_notification_channel::uptr _notification_channel; |
| 74 | /* |
| 75 | * Use an event_fd to wake-up the rotation thread whenever a command |
| 76 | * completes on the notification channel. This ensures that any |
| 77 | * notification that was queued while waiting for a reply to the command is |
| 78 | * eventually consumed. |
| 79 | */ |
| 80 | lttng::eventfd _notification_channel_subscribtion_change_eventfd; |
| 81 | lttng_poll_event _events; |
| 82 | }; |
| 83 | |
| 84 | struct rotation_thread_timer_queue *rotation_thread_timer_queue_create(); |
| 85 | void rotation_thread_timer_queue_destroy(struct rotation_thread_timer_queue *queue); |
| 86 | void rotation_thread_enqueue_job(struct rotation_thread_timer_queue *queue, |
| 87 | enum rotation_thread_job_type job_type, |
| 88 | struct ltt_session *session); |
| 89 | |
| 90 | } /* namespace sessiond */ |
| 91 | } /* namespace lttng */ |
| 92 | |
| 93 | #endif /* ROTATION_THREAD_H */ |