Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 85 additions & 68 deletions include/envoy/event/dispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,44 +63,63 @@ class DispatcherBase {
virtual ~DispatcherBase() = default;

/**
* Creates a file event that will signal when a file is readable or writable. On UNIX systems this
* can be used for any file like interface (files, sockets, etc.).
* @param fd supplies the fd to watch.
* @param cb supplies the callback to fire when the file is ready.
* @param trigger specifies whether to edge or level trigger.
* @param events supplies a logical OR of FileReadyType events that the file event should
* initially listen on.
* Posts a functor to the dispatcher. This is safe cross thread. The functor runs in the context
* of the dispatcher event loop which may be on a different thread than the caller.
*/
virtual FileEventPtr createFileEvent(os_fd_t fd, FileReadyCb cb, FileTriggerType trigger,
uint32_t events) PURE;
virtual void post(PostCb callback) PURE;

/**
* Allocates a timer. @see Timer for docs on how to use the timer.
* @param cb supplies the callback to invoke when the timer fires.
* Validates that an operation is thread-safe with respect to this dispatcher; i.e. that the
* current thread of execution is on the same thread upon which the dispatcher loop is running.
*/
virtual Event::TimerPtr createTimer(TimerCb cb) PURE;
virtual bool isThreadSafe() const PURE;

/**
* Allocates a scaled timer. @see Timer for docs on how to use the timer.
* @param timer_type the type of timer to create.
* @param cb supplies the callback to invoke when the timer fires.
* Runs the event loop. This will not return until exit() is called either from within a callback
* or from a different thread.
* @param type specifies whether to run in blocking mode (run() will not return until exit() is
* called) or non-blocking mode where only active events will be executed and then
* run() will return.
*/
virtual Event::TimerPtr createScaledTimer(Event::ScaledTimerType timer_type, TimerCb cb) PURE;
enum class RunType {
Block, // Runs the event-loop until there are no pending events.
NonBlock, // Checks for any pending events to activate, executes them,
// then exits. Exits immediately if there are no pending or
// active events.
RunUntilExit // Runs the event-loop until loopExit() is called, blocking
// until there are pending or active events.
};
virtual void run(RunType type) PURE;

/**
* Allocates a scaled timer. @see Timer for docs on how to use the timer.
* @param minimum the rule for computing the minimum value of the timer.
* @param cb supplies the callback to invoke when the timer fires.
* Exits the event loop.
*/
virtual Event::TimerPtr createScaledTimer(Event::ScaledTimerMinimum minimum, TimerCb cb) PURE;
virtual void exit() PURE;

/**
* Allocates a schedulable callback. @see SchedulableCallback for docs on how to use the wrapped
* callback.
* @param cb supplies the callback to invoke when the SchedulableCallback is triggered on the
* event loop.
* Shutdown the dispatcher by clear dispatcher thread deletable.
*/
virtual Event::SchedulableCallbackPtr createSchedulableCallback(std::function<void()> cb) PURE;
virtual void shutdown() PURE;
};

class DeferredDeleter {
public:
virtual ~DeferredDeleter() = default;

/**
* Clears any items in the deferred deletion queue.
*/
virtual void clearDeferredDeleteList() PURE;

/**
* Submits an item for deferred delete. @see DeferredDeletable.
*/
virtual void deferredDelete(DeferredDeletablePtr&& to_delete) PURE;
};

class ScopeTracker {
public:
virtual ~ScopeTracker() = default;

/**
* Appends a tracked object to the current stack of tracked objects operating
Expand All @@ -120,12 +139,31 @@ class DispatcherBase {
* Whether the tracked object stack is empty.
*/
virtual bool trackedObjectStackIsEmpty() const PURE;
};

class TimerProvider {
public:
virtual ~TimerProvider() = default;

/**
* Validates that an operation is thread-safe with respect to this dispatcher; i.e. that the
* current thread of execution is on the same thread upon which the dispatcher loop is running.
* Allocates a timer. @see Timer for docs on how to use the timer.
* @param cb supplies the callback to invoke when the timer fires.
*/
virtual bool isThreadSafe() const PURE;
virtual Event::TimerPtr createTimer(TimerCb cb) PURE;

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

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

/**
* Returns a recently cached MonotonicTime value.
Expand All @@ -136,7 +174,7 @@ class DispatcherBase {
/**
* Abstract event dispatching loop.
*/
class Dispatcher : public DispatcherBase {
class Dispatcher : public DispatcherBase, public DeferredDeleter, public ScopeTracker, public TimerProvider {
public:
/**
* Returns the name that identifies this dispatcher, such as "worker_2" or "main_thread".
Expand Down Expand Up @@ -170,9 +208,25 @@ class Dispatcher : public DispatcherBase {
const absl::optional<std::string>& prefix = absl::nullopt) PURE;

/**
* Clears any items in the deferred deletion queue.
* Creates a file event that will signal when a file is readable or writable. On UNIX systems this
* can be used for any file like interface (files, sockets, etc.).
* @param fd supplies the fd to watch.
* @param cb supplies the callback to fire when the file is ready.
* @param trigger specifies whether to edge or level trigger.
* @param events supplies a logical OR of FileReadyType events that the file event should
* initially listen on.
*/
virtual void clearDeferredDeleteList() PURE;
virtual FileEventPtr createFileEvent(os_fd_t fd, FileReadyCb cb, FileTriggerType trigger,
uint32_t events) PURE;

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


/**
* Wraps an already-accepted socket in an instance of Envoy's server Network::Connection.
Expand Down Expand Up @@ -243,15 +297,6 @@ class Dispatcher : public DispatcherBase {
virtual Network::UdpListenerPtr
createUdpListener(Network::SocketSharedPtr socket, Network::UdpListenerCallbacks& cb,
const envoy::config::core::v3::UdpSocketConfig& config) PURE;
/**
* Submits an item for deferred delete. @see DeferredDeletable.
*/
virtual void deferredDelete(DeferredDeletablePtr&& to_delete) PURE;

/**
* Exits the event loop.
*/
virtual void exit() PURE;

/**
* Listens for a signal event. Only a single dispatcher in the process can listen for signals.
Expand All @@ -263,35 +308,12 @@ class Dispatcher : public DispatcherBase {
*/
virtual SignalEventPtr listenForSignal(signal_t signal_num, SignalCb cb) PURE;

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

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

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

/**
* Returns a factory which connections may use for watermark buffer creation.
* @return the watermark buffer factory for this dispatcher.
Expand All @@ -302,11 +324,6 @@ class Dispatcher : public DispatcherBase {
* Updates approximate monotonic time to current value.
*/
virtual void updateApproximateMonotonicTime() PURE;

/**
* Shutdown the dispatcher by clear dispatcher thread deletable.
*/
virtual void shutdown() PURE;
};

using DispatcherPtr = std::unique_ptr<Dispatcher>;
Expand Down
12 changes: 6 additions & 6 deletions source/common/common/scope_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@ namespace Envoy {
// A small class for managing the scope of a tracked object which is currently having
// work done in this thread.
//
// When created, it appends the tracked object to the dispatcher's stack of tracked objects, and
// when destroyed it pops the dispatcher's stack of tracked object, which should be the object it
// When created, it appends the tracked object to the tracker's stack of tracked objects, and
// when destroyed it pops the tracker's stack of tracked object, which should be the object it
// registered.
class ScopeTrackerScopeState {
public:
ScopeTrackerScopeState(const ScopeTrackedObject* object, Event::Dispatcher& dispatcher)
Comment thread
goaway marked this conversation as resolved.
Outdated
: registered_object_(object), dispatcher_(dispatcher) {
dispatcher_.pushTrackedObject(registered_object_);
: registered_object_(object), tracker_(tracker) {
tracker_.pushTrackedObject(registered_object_);
}

~ScopeTrackerScopeState() {
// If ScopeTrackerScopeState is always used for managing tracked objects,
// then the object popped off should be the object we registered.
dispatcher_.popTrackedObject(registered_object_);
tracker_.popTrackedObject(registered_object_);
}

// Make this object stack-only, it doesn't make sense for it
Expand All @@ -32,7 +32,7 @@ class ScopeTrackerScopeState {

private:
const ScopeTrackedObject* registered_object_;
Event::Dispatcher& dispatcher_;
Event::ScopeTracker& tracker_;
};

} // namespace Envoy