| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- // 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 <queue>
- #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
|