summaryrefslogtreecommitdiffstats
path: root/src/rocksdb/util/single_thread_executor.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/rocksdb/util/single_thread_executor.h')
-rw-r--r--src/rocksdb/util/single_thread_executor.h56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/rocksdb/util/single_thread_executor.h b/src/rocksdb/util/single_thread_executor.h
new file mode 100644
index 000000000..c69f2a292
--- /dev/null
+++ b/src/rocksdb/util/single_thread_executor.h
@@ -0,0 +1,56 @@
+// Copyright (c) Meta Platforms, Inc. and affiliates.
+//
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+#pragma once
+
+#if USE_COROUTINES
+#include <atomic>
+
+#include "folly/CPortability.h"
+#include "folly/CppAttributes.h"
+#include "folly/Executor.h"
+#include "util/async_file_reader.h"
+
+namespace ROCKSDB_NAMESPACE {
+// Implements a simple executor that runs callback functions in the same
+// thread, unlike CPUThreadExecutor which may schedule the callback on
+// another thread. Runs in a tight loop calling the queued callbacks,
+// and polls for async IO completions when idle. The completions will
+// resume suspended coroutines and they get added to the queue, which
+// will get picked up by this loop.
+// Any possibility of deadlock is precluded because the file system
+// guarantees that async IO completion callbacks will not be scheduled
+// to run in this thread or this executor.
+class SingleThreadExecutor : public folly::Executor {
+ public:
+ explicit SingleThreadExecutor(AsyncFileReader& reader)
+ : reader_(reader), busy_(false) {}
+
+ void add(folly::Func callback) override {
+ auto& q = q_;
+ q.push(std::move(callback));
+ if (q.size() == 1 && !busy_) {
+ while (!q.empty()) {
+ q.front()();
+ q.pop();
+
+ if (q.empty()) {
+ // Prevent recursion, as the Wait may queue resumed coroutines
+ busy_ = true;
+ reader_.Wait();
+ busy_ = false;
+ }
+ }
+ }
+ }
+
+ private:
+ std::queue<folly::Func> q_;
+ AsyncFileReader& reader_;
+ bool busy_;
+};
+} // namespace ROCKSDB_NAMESPACE
+#endif // USE_COROUTINES