1
#pragma once
2

            
3
#include <cstdint>
4
#include <functional>
5
#include <memory>
6
#include <string>
7
#include <vector>
8

            
9
#include "envoy/common/scope_tracker.h"
10
#include "envoy/common/time.h"
11
#include "envoy/config/core/v3/resolver.pb.h"
12
#include "envoy/config/core/v3/udp_socket_config.pb.h"
13
#include "envoy/event/dispatcher_thread_deletable.h"
14
#include "envoy/event/file_event.h"
15
#include "envoy/event/scaled_timer.h"
16
#include "envoy/event/schedulable_cb.h"
17
#include "envoy/event/signal.h"
18
#include "envoy/event/timer.h"
19
#include "envoy/filesystem/watcher.h"
20
#include "envoy/network/connection.h"
21
#include "envoy/network/connection_handler.h"
22
#include "envoy/network/dns.h"
23
#include "envoy/network/listen_socket.h"
24
#include "envoy/network/listener.h"
25
#include "envoy/network/transport_socket.h"
26
#include "envoy/server/overload/thread_local_overload_state.h"
27
#include "envoy/server/watchdog.h"
28
#include "envoy/stats/scope.h"
29
#include "envoy/stats/stats_macros.h"
30
#include "envoy/stream_info/stream_info.h"
31
#include "envoy/thread/thread.h"
32

            
33
#include "absl/functional/any_invocable.h"
34

            
35
namespace Envoy {
36
namespace Event {
37

            
38
/**
39
 * All dispatcher stats. @see stats_macros.h
40
 */
41
#define ALL_DISPATCHER_STATS(HISTOGRAM)                                                            \
42
15
  HISTOGRAM(loop_duration_us, Microseconds)                                                        \
43
15
  HISTOGRAM(poll_delay_us, Microseconds)
44

            
45
/**
46
 * Struct definition for all dispatcher stats. @see stats_macros.h
47
 */
48
struct DispatcherStats {
49
  ALL_DISPATCHER_STATS(GENERATE_HISTOGRAM_STRUCT)
50
};
51

            
52
using DispatcherStatsPtr = std::unique_ptr<DispatcherStats>;
53

            
54
/**
55
 * Callback invoked when a dispatcher post() runs.
56
 */
57
using PostCb = absl::AnyInvocable<void()>;
58

            
59
using PostCbSharedPtr = std::shared_ptr<PostCb>;
60

            
61
/**
62
 * Minimal interface to the dispatching loop used to create low-level primitives. See Dispatcher
63
 * below for the full interface.
64
 */
65
class DispatcherBase {
66
public:
67
245769
  virtual ~DispatcherBase() = default;
68

            
69
  /**
70
   * Posts a functor to the dispatcher. This is safe cross thread. The functor runs in the context
71
   * of the dispatcher event loop which may be on a different thread than the caller.
72
   */
73
  virtual void post(PostCb callback) PURE;
74

            
75
  /**
76
   * Validates that an operation is thread-safe with respect to this dispatcher; i.e. that the
77
   * current thread of execution is on the same thread upon which the dispatcher loop is running.
78
   */
79
  virtual bool isThreadSafe() const PURE;
80
};
81

            
82
/**
83
 * Minimal interface to support ScopeTrackedObjects.
84
 */
85
class ScopeTracker {
86
public:
87
245769
  virtual ~ScopeTracker() = default;
88

            
89
  /**
90
   * Appends a tracked object to the current stack of tracked objects operating
91
   * in the dispatcher.
92
   *
93
   * It's recommended to use ScopeTrackerScopeState to manage the object's tracking. If directly
94
   * invoking, there needs to be a subsequent call to popTrackedObject().
95
   */
96
  virtual void pushTrackedObject(const ScopeTrackedObject* object) PURE;
97

            
98
  /**
99
   * Removes the top of the stack of tracked object and asserts that it was expected.
100
   */
101
  virtual void popTrackedObject(const ScopeTrackedObject* expected_object) PURE;
102

            
103
  /**
104
   * Whether the tracked object stack is empty.
105
   */
106
  virtual bool trackedObjectStackIsEmpty() const PURE;
107
};
108

            
109
/**
110
 * Abstract event dispatching loop.
111
 */
112
class Dispatcher : public DispatcherBase, public ScopeTracker {
113
public:
114
  /**
115
   * Returns the name that identifies this dispatcher, such as "worker_2" or "main_thread".
116
   * @return const std::string& the name that identifies this dispatcher.
117
   */
118
  virtual const std::string& name() PURE;
119

            
120
  /**
121
   * Creates a file event that will signal when a file is readable or writable. On UNIX systems this
122
   * can be used for any file like interface (files, sockets, etc.).
123
   * @param fd supplies the fd to watch.
124
   * @param cb supplies the callback to fire when the file is ready.
125
   * @param trigger specifies whether to edge or level trigger.
126
   * @param events supplies a logical OR of FileReadyType events that the file event should
127
   *               initially listen on.
128
   */
129
  virtual FileEventPtr createFileEvent(os_fd_t fd, FileReadyCb cb, FileTriggerType trigger,
130
                                       uint32_t events) PURE;
131

            
132
  /**
133
   * Allocates a timer. @see Timer for docs on how to use the timer.
134
   * @param cb supplies the callback to invoke when the timer fires.
135
   */
136
  virtual Event::TimerPtr createTimer(TimerCb cb) PURE;
137

            
138
  /**
139
   * Allocates a scaled timer. @see Timer for docs on how to use the timer.
140
   * @param timer_type the type of timer to create.
141
   * @param cb supplies the callback to invoke when the timer fires.
142
   */
143
  virtual Event::TimerPtr createScaledTimer(Event::ScaledTimerType timer_type, TimerCb cb) PURE;
144

            
145
  /**
146
   * Allocates a scaled timer. @see Timer for docs on how to use the timer.
147
   * @param minimum the rule for computing the minimum value of the timer.
148
   * @param cb supplies the callback to invoke when the timer fires.
149
   */
150
  virtual Event::TimerPtr createScaledTimer(Event::ScaledTimerMinimum minimum, TimerCb cb) PURE;
151

            
152
  /**
153
   * Allocates a schedulable callback. @see SchedulableCallback for docs on how to use the wrapped
154
   * callback.
155
   * @param cb supplies the callback to invoke when the SchedulableCallback is triggered on the
156
   * event loop.
157
   */
158
  virtual Event::SchedulableCallbackPtr createSchedulableCallback(std::function<void()> cb) PURE;
159

            
160
  /**
161
   * Register a watchdog for this dispatcher. The dispatcher is responsible for touching the
162
   * watchdog at least once per touch interval. Dispatcher implementations may choose to touch more
163
   * often to avoid spurious miss events when processing long callback queues.
164
   * @param min_touch_interval Touch interval for the watchdog.
165
   */
166
  virtual void registerWatchdog(const Server::WatchDogSharedPtr& watchdog,
167
                                std::chrono::milliseconds min_touch_interval) PURE;
168

            
169
  /**
170
   * Returns a time-source to use with this dispatcher.
171
   */
172
  virtual TimeSource& timeSource() PURE;
173

            
174
  /**
175
   * Returns a recently cached MonotonicTime value.
176
   */
177
  virtual MonotonicTime approximateMonotonicTime() const PURE;
178

            
179
  /**
180
   * Initializes stats for this dispatcher. Note that this can't generally be done at construction
181
   * time, since the main and worker thread dispatchers are constructed before
182
   * ThreadLocalStoreImpl::initializeThreading.
183
   * @param scope the scope to contain the new per-dispatcher stats created here.
184
   * @param prefix the stats prefix to identify this dispatcher. If empty, the dispatcher will be
185
   *               identified by its name.
186
   */
187
  virtual void initializeStats(Stats::Scope& scope,
188
                               const absl::optional<std::string>& prefix = absl::nullopt) PURE;
189

            
190
  /**
191
   * Clears any items in the deferred deletion queue.
192
   */
193
  virtual void clearDeferredDeleteList() PURE;
194

            
195
  /**
196
   * Wraps an already-accepted socket in an instance of Envoy's server Network::Connection.
197
   * @param socket supplies an open file descriptor and connection metadata to use for the
198
   *        connection. Takes ownership of the socket.
199
   * @param transport_socket supplies a transport socket to be used by the connection.
200
   * @param stream_info info object for the server connection
201
   * @return Network::ConnectionPtr a server connection that is owned by the caller.
202
   */
203
  virtual Network::ServerConnectionPtr
204
  createServerConnection(Network::ConnectionSocketPtr&& socket,
205
                         Network::TransportSocketPtr&& transport_socket,
206
                         StreamInfo::StreamInfo& stream_info) PURE;
207

            
208
  /**
209
   * Creates an instance of Envoy's Network::ClientConnection. Does NOT initiate the connection;
210
   * the caller must then call connect() on the returned Network::ClientConnection.
211
   * @param address supplies the address to connect to.
212
   * @param source_address supplies an address to bind to or nullptr if no bind is necessary.
213
   * @param transport_socket supplies a transport socket to be used by the connection.
214
   * @param options the socket options to be set on the underlying socket before anything is sent
215
   *        on the socket.
216
   * @param transport socket options used to create the transport socket.
217
   * @return Network::ClientConnectionPtr a client connection that is owned by the caller.
218
   */
219
  virtual Network::ClientConnectionPtr createClientConnection(
220
      Network::Address::InstanceConstSharedPtr address,
221
      Network::Address::InstanceConstSharedPtr source_address,
222
      Network::TransportSocketPtr&& transport_socket,
223
      const Network::ConnectionSocket::OptionsSharedPtr& options,
224
      const Network::TransportSocketOptionsConstSharedPtr& transport_options) PURE;
225

            
226
  /**
227
   * @return Filesystem::WatcherPtr a filesystem watcher owned by the caller.
228
   */
229
  virtual Filesystem::WatcherPtr createFilesystemWatcher() PURE;
230

            
231
  /**
232
   * Submits an item for deferred delete. @see DeferredDeletable.
233
   */
234
  virtual void deferredDelete(DeferredDeletablePtr&& to_delete) PURE;
235

            
236
  /**
237
   * Exits the event loop.
238
   */
239
  virtual void exit() PURE;
240

            
241
  /**
242
   * Listens for a signal event. Only a single dispatcher in the process can listen for signals.
243
   * If more than one dispatcher calls this routine in the process the behavior is undefined.
244
   *
245
   * @param signal_num supplies the signal to listen on.
246
   * @param cb supplies the callback to invoke when the signal fires.
247
   * @return SignalEventPtr a signal event that is owned by the caller.
248
   */
249
  virtual SignalEventPtr listenForSignal(signal_t signal_num, SignalCb cb) PURE;
250

            
251
  /**
252
   * Post the deletable to this dispatcher. The deletable objects are guaranteed to be destroyed on
253
   * the dispatcher's thread before dispatcher destroy. This is safe cross thread.
254
   */
255
  virtual void deleteInDispatcherThread(DispatcherThreadDeletableConstPtr deletable) PURE;
256

            
257
  /**
258
   * Runs the event loop. This will not return until exit() is called either from within a callback
259
   * or from a different thread.
260
   * @param type specifies whether to run in blocking mode (run() will not return until exit() is
261
   *              called) or non-blocking mode where only active events will be executed and then
262
   *              run() will return.
263
   */
264
  enum class RunType {
265
    Block,       // Runs the event-loop until there are no pending events.
266
    NonBlock,    // Checks for any pending events to activate, executes them,
267
                 // then exits. Exits immediately if there are no pending or
268
                 // active events.
269
    RunUntilExit // Runs the event-loop until loopExit() is called, blocking
270
                 // until there are pending or active events.
271
  };
272
  virtual void run(RunType type) PURE;
273

            
274
  /**
275
   * Returns a factory which connections may use for watermark buffer creation.
276
   * @return the watermark buffer factory for this dispatcher.
277
   */
278
  virtual Buffer::WatermarkFactory& getWatermarkFactory() PURE;
279

            
280
  /**
281
   * Updates approximate monotonic time to current value.
282
   */
283
  virtual void updateApproximateMonotonicTime() PURE;
284

            
285
  /**
286
   * Shutdown the dispatcher by clear dispatcher thread deletable.
287
   */
288
  virtual void shutdown() PURE;
289
};
290

            
291
using DispatcherPtr = std::unique_ptr<Dispatcher>;
292

            
293
} // namespace Event
294
} // namespace Envoy