/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, Random::RandomGenerator& random_generator, |
48 | | Filesystem::Instance& file_system, 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 | 35.9k | event_base& base() { return base_scheduler_.base(); } |
57 | | |
58 | | // Event::Dispatcher |
59 | 41.9k | const std::string& name() override { return name_; } |
60 | | void registerWatchdog(const Server::WatchDogSharedPtr& watchdog, |
61 | | std::chrono::milliseconds min_touch_interval) override; |
62 | 160k | 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 | | Network::ListenerPtr |
79 | | createListener(Network::SocketSharedPtr&& socket, Network::TcpListenerCallbacks& cb, |
80 | | Runtime::Loader& runtime, const Network::ListenerConfig& listener_config, |
81 | | Server::ThreadLocalOverloadStateOptRef overload_state) override; |
82 | | TimerPtr createTimer(TimerCb cb) override; |
83 | | TimerPtr createScaledTimer(ScaledTimerType timer_type, TimerCb cb) override; |
84 | | TimerPtr createScaledTimer(ScaledTimerMinimum minimum, TimerCb cb) override; |
85 | | |
86 | | Event::SchedulableCallbackPtr createSchedulableCallback(std::function<void()> cb) override; |
87 | | void deferredDelete(DeferredDeletablePtr&& to_delete) override; |
88 | | void exit() override; |
89 | | SignalEventPtr listenForSignal(signal_t signal_num, SignalCb cb) override; |
90 | | void post(PostCb callback) override; |
91 | | void deleteInDispatcherThread(DispatcherThreadDeletableConstPtr deletable) override; |
92 | | void run(RunType type) override; |
93 | 53.2k | Buffer::WatermarkFactory& getWatermarkFactory() override { return *buffer_factory_; } |
94 | | void pushTrackedObject(const ScopeTrackedObject* object) override; |
95 | | void popTrackedObject(const ScopeTrackedObject* expected_object) override; |
96 | 4.45k | bool trackedObjectStackIsEmpty() const override { return tracked_object_stack_.empty(); } |
97 | | MonotonicTime approximateMonotonicTime() const override; |
98 | | void updateApproximateMonotonicTime() override; |
99 | | void shutdown() override; |
100 | | |
101 | | // FatalErrorInterface |
102 | | void onFatalError(std::ostream& os) const override; |
103 | | void |
104 | | runFatalActionsOnTrackedObject(const FatalAction::FatalActionPtrList& actions) const override; |
105 | | |
106 | | private: |
107 | | // Holds a reference to the watchdog registered with this dispatcher and the timer used to ensure |
108 | | // that the dog is touched periodically. |
109 | | class WatchdogRegistration { |
110 | | public: |
111 | | WatchdogRegistration(const Server::WatchDogSharedPtr& watchdog, Scheduler& scheduler, |
112 | | std::chrono::milliseconds timer_interval, Dispatcher& dispatcher) |
113 | 5.29k | : watchdog_(watchdog), timer_interval_(timer_interval) { |
114 | 5.29k | touch_timer_ = scheduler.createTimer( |
115 | 5.29k | [this]() -> void { |
116 | 1.99k | watchdog_->touch(); |
117 | 1.99k | touch_timer_->enableTimer(timer_interval_); |
118 | 1.99k | }, |
119 | 5.29k | dispatcher); |
120 | 5.29k | touch_timer_->enableTimer(timer_interval_); |
121 | 5.29k | } |
122 | | |
123 | 88.3k | void touchWatchdog() { watchdog_->touch(); } |
124 | | |
125 | | private: |
126 | | Server::WatchDogSharedPtr watchdog_; |
127 | | const std::chrono::milliseconds timer_interval_; |
128 | | TimerPtr touch_timer_; |
129 | | }; |
130 | | using WatchdogRegistrationPtr = std::unique_ptr<WatchdogRegistration>; |
131 | | |
132 | | TimerPtr createTimerInternal(TimerCb cb); |
133 | | void updateApproximateMonotonicTimeInternal(); |
134 | | void runPostCallbacks(); |
135 | | void runThreadLocalDelete(); |
136 | | |
137 | | // Helper used to touch the watchdog after most schedulable, fd, and timer callbacks. |
138 | | void touchWatchdog(); |
139 | | |
140 | | // Validate that an operation is thread safe, i.e. it's invoked on the same thread that the |
141 | | // dispatcher run loop is executing on. We allow run_tid_ to be empty for tests where we don't |
142 | | // invoke run(). |
143 | 1.41M | bool isThreadSafe() const override { |
144 | 1.41M | return run_tid_.isEmpty() || run_tid_ == thread_factory_.currentThreadId(); |
145 | 1.41M | } |
146 | | |
147 | | const std::string name_; |
148 | | Thread::ThreadFactory& thread_factory_; |
149 | | TimeSource& time_source_; |
150 | | Random::RandomGenerator& random_generator_; |
151 | | Filesystem::Instance& file_system_; |
152 | | std::string stats_prefix_; |
153 | | DispatcherStatsPtr stats_; |
154 | | Thread::ThreadId run_tid_; |
155 | | Buffer::WatermarkFactorySharedPtr buffer_factory_; |
156 | | LibeventScheduler base_scheduler_; |
157 | | SchedulerPtr scheduler_; |
158 | | |
159 | | SchedulableCallbackPtr thread_local_delete_cb_; |
160 | | Thread::MutexBasicLockable thread_local_deletable_lock_; |
161 | | // `deletables_in_dispatcher_thread` must be destroyed last to allow other callbacks populate. |
162 | | std::list<DispatcherThreadDeletableConstPtr> |
163 | | deletables_in_dispatcher_thread_ ABSL_GUARDED_BY(thread_local_deletable_lock_); |
164 | | bool shutdown_called_{false}; |
165 | | |
166 | | SchedulableCallbackPtr deferred_delete_cb_; |
167 | | |
168 | | SchedulableCallbackPtr post_cb_; |
169 | | Thread::MutexBasicLockable post_lock_; |
170 | | std::list<PostCb> post_callbacks_ ABSL_GUARDED_BY(post_lock_); |
171 | | |
172 | | std::vector<DeferredDeletablePtr> to_delete_1_; |
173 | | std::vector<DeferredDeletablePtr> to_delete_2_; |
174 | | std::vector<DeferredDeletablePtr>* current_to_delete_; |
175 | | |
176 | | absl::InlinedVector<const ScopeTrackedObject*, ExpectedMaxTrackedObjectStackDepth> |
177 | | tracked_object_stack_; |
178 | | bool deferred_deleting_{}; |
179 | | MonotonicTime approximate_monotonic_time_; |
180 | | WatchdogRegistrationPtr watchdog_registration_; |
181 | | const ScaledRangeTimerManagerPtr scaled_timer_manager_; |
182 | | }; |
183 | | |
184 | | } // namespace Event |
185 | | } // namespace Envoy |