/proc/self/cwd/source/common/event/dispatcher_impl.h
Line | Count | Source |
1 | | #pragma once |
2 | | |
3 | | #include <cstdint> |
4 | | #include <functional> |
5 | | #include <list> |
6 | | #include <memory> |
7 | | #include <vector> |
8 | | |
9 | | #include "envoy/api/api.h" |
10 | | #include "envoy/common/scope_tracker.h" |
11 | | #include "envoy/common/time.h" |
12 | | #include "envoy/event/deferred_deletable.h" |
13 | | #include "envoy/event/dispatcher.h" |
14 | | #include "envoy/network/connection_handler.h" |
15 | | #include "envoy/stats/scope.h" |
16 | | |
17 | | #include "source/common/common/logger.h" |
18 | | #include "source/common/common/thread.h" |
19 | | #include "source/common/event/libevent.h" |
20 | | #include "source/common/event/libevent_scheduler.h" |
21 | | #include "source/common/signal/fatal_error_handler.h" |
22 | | |
23 | | #include "absl/container/inlined_vector.h" |
24 | | |
25 | | namespace Envoy { |
26 | | namespace Event { |
27 | | |
28 | | // The tracked object stack likely won't grow larger than this initial |
29 | | // reservation; this should make appends constant time since the stack |
30 | | // shouldn't have to grow larger. |
31 | | inline constexpr size_t ExpectedMaxTrackedObjectStackDepth = 10; |
32 | | |
33 | | /** |
34 | | * libevent implementation of Event::Dispatcher. |
35 | | */ |
36 | | class DispatcherImpl : Logger::Loggable<Logger::Id::main>, |
37 | | public Dispatcher, |
38 | | public FatalErrorHandlerInterface { |
39 | | public: |
40 | | DispatcherImpl(const std::string& name, Api::Api& api, Event::TimeSystem& time_system); |
41 | | DispatcherImpl(const std::string& name, Api::Api& api, Event::TimeSystem& time_systems, |
42 | | const Buffer::WatermarkFactorySharedPtr& watermark_factory); |
43 | | DispatcherImpl(const std::string& name, Api::Api& api, Event::TimeSystem& time_system, |
44 | | const ScaledRangeTimerManagerFactory& scaled_timer_factory, |
45 | | const Buffer::WatermarkFactorySharedPtr& watermark_factory); |
46 | | DispatcherImpl(const std::string& name, Thread::ThreadFactory& thread_factory, |
47 | | TimeSource& time_source, Filesystem::Instance& file_system, |
48 | | Event::TimeSystem& time_system, |
49 | | const ScaledRangeTimerManagerFactory& scaled_timer_factory, |
50 | | const Buffer::WatermarkFactorySharedPtr& watermark_factory); |
51 | | ~DispatcherImpl() override; |
52 | | |
53 | | /** |
54 | | * @return event_base& the libevent base. |
55 | | */ |
56 | 23.2k | event_base& base() { return base_scheduler_.base(); } |
57 | | |
58 | | // Event::Dispatcher |
59 | 34.0k | const std::string& name() override { return name_; } |
60 | | void registerWatchdog(const Server::WatchDogSharedPtr& watchdog, |
61 | | std::chrono::milliseconds min_touch_interval) override; |
62 | 111k | TimeSource& timeSource() override { return time_source_; } |
63 | | void initializeStats(Stats::Scope& scope, const absl::optional<std::string>& prefix) override; |
64 | | void clearDeferredDeleteList() override; |
65 | | Network::ServerConnectionPtr |
66 | | createServerConnection(Network::ConnectionSocketPtr&& socket, |
67 | | Network::TransportSocketPtr&& transport_socket, |
68 | | StreamInfo::StreamInfo& stream_info) override; |
69 | | Network::ClientConnectionPtr createClientConnection( |
70 | | Network::Address::InstanceConstSharedPtr address, |
71 | | Network::Address::InstanceConstSharedPtr source_address, |
72 | | Network::TransportSocketPtr&& transport_socket, |
73 | | const Network::ConnectionSocket::OptionsSharedPtr& options, |
74 | | const Network::TransportSocketOptionsConstSharedPtr& transport_options) override; |
75 | | FileEventPtr createFileEvent(os_fd_t fd, FileReadyCb cb, FileTriggerType trigger, |
76 | | uint32_t events) override; |
77 | | Filesystem::WatcherPtr createFilesystemWatcher() override; |
78 | | TimerPtr createTimer(TimerCb cb) override; |
79 | | TimerPtr createScaledTimer(ScaledTimerType timer_type, TimerCb cb) override; |
80 | | TimerPtr createScaledTimer(ScaledTimerMinimum minimum, TimerCb cb) override; |
81 | | |
82 | | Event::SchedulableCallbackPtr createSchedulableCallback(std::function<void()> cb) override; |
83 | | void deferredDelete(DeferredDeletablePtr&& to_delete) override; |
84 | | void exit() override; |
85 | | SignalEventPtr listenForSignal(signal_t signal_num, SignalCb cb) override; |
86 | | void post(PostCb callback) override; |
87 | | void deleteInDispatcherThread(DispatcherThreadDeletableConstPtr deletable) override; |
88 | | void run(RunType type) override; |
89 | 26.9k | Buffer::WatermarkFactory& getWatermarkFactory() override { return *buffer_factory_; } |
90 | | void pushTrackedObject(const ScopeTrackedObject* object) override; |
91 | | void popTrackedObject(const ScopeTrackedObject* expected_object) override; |
92 | 3.21k | bool trackedObjectStackIsEmpty() const override { return tracked_object_stack_.empty(); } |
93 | | MonotonicTime approximateMonotonicTime() const override; |
94 | | void updateApproximateMonotonicTime() override; |
95 | | void shutdown() override; |
96 | | |
97 | | // FatalErrorInterface |
98 | | void onFatalError(std::ostream& os) const override; |
99 | | void |
100 | | runFatalActionsOnTrackedObject(const FatalAction::FatalActionPtrList& actions) const override; |
101 | | |
102 | | private: |
103 | | // Holds a reference to the watchdog registered with this dispatcher and the timer used to ensure |
104 | | // that the dog is touched periodically. |
105 | | class WatchdogRegistration { |
106 | | public: |
107 | | WatchdogRegistration(const Server::WatchDogSharedPtr& watchdog, Scheduler& scheduler, |
108 | | std::chrono::milliseconds timer_interval, Dispatcher& dispatcher) |
109 | 3.95k | : watchdog_(watchdog), timer_interval_(timer_interval) { |
110 | 3.95k | touch_timer_ = scheduler.createTimer( |
111 | 3.95k | [this]() -> void { |
112 | 562 | watchdog_->touch(); |
113 | 562 | touch_timer_->enableTimer(timer_interval_); |
114 | 562 | }, |
115 | 3.95k | dispatcher); |
116 | 3.95k | touch_timer_->enableTimer(timer_interval_); |
117 | 3.95k | } |
118 | | |
119 | 48.6k | void touchWatchdog() { watchdog_->touch(); } |
120 | | |
121 | | private: |
122 | | Server::WatchDogSharedPtr watchdog_; |
123 | | const std::chrono::milliseconds timer_interval_; |
124 | | TimerPtr touch_timer_; |
125 | | }; |
126 | | using WatchdogRegistrationPtr = std::unique_ptr<WatchdogRegistration>; |
127 | | |
128 | | TimerPtr createTimerInternal(TimerCb cb); |
129 | | void updateApproximateMonotonicTimeInternal(); |
130 | | void runPostCallbacks(); |
131 | | void runThreadLocalDelete(); |
132 | | |
133 | | // Helper used to touch the watchdog after most schedulable, fd, and timer callbacks. |
134 | | void touchWatchdog(); |
135 | | |
136 | | // Validate that an operation is thread safe, i.e. it's invoked on the same thread that the |
137 | | // dispatcher run loop is executing on. We allow run_tid_ to be empty for tests where we don't |
138 | | // invoke run(). |
139 | 686k | bool isThreadSafe() const override { |
140 | 686k | return run_tid_.isEmpty() || run_tid_ == thread_factory_.currentThreadId(); |
141 | 686k | } |
142 | | |
143 | | const std::string name_; |
144 | | Thread::ThreadFactory& thread_factory_; |
145 | | TimeSource& time_source_; |
146 | | Filesystem::Instance& file_system_; |
147 | | std::string stats_prefix_; |
148 | | DispatcherStatsPtr stats_; |
149 | | Thread::ThreadId run_tid_; |
150 | | Buffer::WatermarkFactorySharedPtr buffer_factory_; |
151 | | LibeventScheduler base_scheduler_; |
152 | | SchedulerPtr scheduler_; |
153 | | |
154 | | SchedulableCallbackPtr thread_local_delete_cb_; |
155 | | Thread::MutexBasicLockable thread_local_deletable_lock_; |
156 | | // `deletables_in_dispatcher_thread` must be destroyed last to allow other callbacks populate. |
157 | | std::list<DispatcherThreadDeletableConstPtr> |
158 | | deletables_in_dispatcher_thread_ ABSL_GUARDED_BY(thread_local_deletable_lock_); |
159 | | bool shutdown_called_{false}; |
160 | | |
161 | | SchedulableCallbackPtr deferred_delete_cb_; |
162 | | |
163 | | SchedulableCallbackPtr post_cb_; |
164 | | Thread::MutexBasicLockable post_lock_; |
165 | | std::list<PostCb> post_callbacks_ ABSL_GUARDED_BY(post_lock_); |
166 | | |
167 | | std::vector<DeferredDeletablePtr> to_delete_1_; |
168 | | std::vector<DeferredDeletablePtr> to_delete_2_; |
169 | | std::vector<DeferredDeletablePtr>* current_to_delete_; |
170 | | |
171 | | absl::InlinedVector<const ScopeTrackedObject*, ExpectedMaxTrackedObjectStackDepth> |
172 | | tracked_object_stack_; |
173 | | bool deferred_deleting_{}; |
174 | | MonotonicTime approximate_monotonic_time_; |
175 | | WatchdogRegistrationPtr watchdog_registration_; |
176 | | const ScaledRangeTimerManagerPtr scaled_timer_manager_; |
177 | | }; |
178 | | |
179 | | } // namespace Event |
180 | | } // namespace Envoy |