adb: fdevent: move run queue to fdevent_context.
Make the run queue logic reusable between implementations of fdevent by
moving it to the abstract base class.
Test: adb_test
Change-Id: If2f72e3ddc8007304bca63aa75446fa117267b25
diff --git a/adb/fdevent/fdevent.h b/adb/fdevent/fdevent.h
index b46219c..5a2f2c6 100644
--- a/adb/fdevent/fdevent.h
+++ b/adb/fdevent/fdevent.h
@@ -21,10 +21,14 @@
#include <stdint.h>
#include <chrono>
+#include <deque>
#include <functional>
+#include <mutex>
#include <optional>
#include <variant>
+#include <android-base/thread_annotations.h>
+
#include "adb_unique_fd.h"
// Events that may be observed
@@ -48,6 +52,7 @@
std::string dump_fde(const fdevent* fde);
struct fdevent_context {
+ public:
virtual ~fdevent_context() = default;
// Allocate and initialize a new fdevent object.
@@ -68,17 +73,29 @@
virtual void SetTimeout(fdevent* fde, std::optional<std::chrono::milliseconds> timeout) = 0;
// Loop forever, handling events.
+ // Implementations should call FlushRunQueue on every iteration.
virtual void Loop() = 0;
// Assert that the caller is running on the context's main thread.
virtual void CheckMainThread() = 0;
// Queue an operation to be run on the main thread.
- virtual void Run(std::function<void()> fn) = 0;
+ void Run(std::function<void()> fn);
// Test-only functionality:
virtual void TerminateLoop() = 0;
virtual size_t InstalledCount() = 0;
+
+ protected:
+ // Interrupt the run loop.
+ virtual void Interrupt() = 0;
+
+ // Run all pending functions enqueued via Run().
+ void FlushRunQueue() EXCLUDES(run_queue_mutex_);
+
+ private:
+ std::mutex run_queue_mutex_;
+ std::deque<std::function<void()>> run_queue_ GUARDED_BY(run_queue_mutex_);
};
struct fdevent {