Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
104 changes: 56 additions & 48 deletions envoy/event/dispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,57 @@ class DispatcherBase {
public:
virtual ~DispatcherBase() = default;

/**
* 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;

/**
* 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 bool isThreadSafe() const PURE;
};

/**
* Minimal interface to support ScopeTrackedObjects.
*/
class ScopeTracker {
public:
virtual ~ScopeTracker() = default;

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

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

/**
* Whether the tracked object stack is empty.
*/
virtual bool trackedObjectStackIsEmpty() const PURE;
};

/**
* Abstract event dispatching loop.
*/
class Dispatcher : public DispatcherBase, public ScopeTracker {
public:
/**
* Returns the name that identifies this dispatcher, such as "worker_2" or "main_thread".
* @return const std::string& the name that identifies this dispatcher.
*/
virtual const std::string& name() PURE;

/**
* 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.).
Expand Down Expand Up @@ -103,48 +154,6 @@ class DispatcherBase {
*/
virtual Event::SchedulableCallbackPtr createSchedulableCallback(std::function<void()> cb) PURE;

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

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

/**
* Whether the tracked object stack is empty.
*/
virtual bool trackedObjectStackIsEmpty() const PURE;

/**
* 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 bool isThreadSafe() const PURE;

/**
* Returns a recently cached MonotonicTime value.
*/
virtual MonotonicTime approximateMonotonicTime() const PURE;
};

/**
* Abstract event dispatching loop.
*/
class Dispatcher : public DispatcherBase {
public:
/**
* Returns the name that identifies this dispatcher, such as "worker_2" or "main_thread".
* @return const std::string& the name that identifies this dispatcher.
*/
virtual const std::string& name() PURE;

/**
* Register a watchdog for this dispatcher. The dispatcher is responsible for touching the
* watchdog at least once per touch interval. Dispatcher implementations may choose to touch more
Expand All @@ -159,6 +168,11 @@ class Dispatcher : public DispatcherBase {
*/
virtual TimeSource& timeSource() PURE;

/**
* Returns a recently cached MonotonicTime value.
*/
virtual MonotonicTime approximateMonotonicTime() const PURE;

/**
* Initializes stats for this dispatcher. Note that this can't generally be done at construction
* time, since the main and worker thread dispatchers are constructed before
Expand Down Expand Up @@ -264,12 +278,6 @@ 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.
Expand Down
14 changes: 7 additions & 7 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)
: registered_object_(object), dispatcher_(dispatcher) {
dispatcher_.pushTrackedObject(registered_object_);
ScopeTrackerScopeState(const ScopeTrackedObject* object, Event::ScopeTracker& tracker)
: 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