mirror of
https://github.com/google/googletest.git
synced 2025-12-07 17:26:53 +08:00
70 lines
1.8 KiB
C++
70 lines
1.8 KiB
C++
#ifndef COROUTINES_INCLUDE_CORO_INTERNAL_COTEST_CORO_THREAD_H_
|
|
#define COROUTINES_INCLUDE_CORO_INTERNAL_COTEST_CORO_THREAD_H_
|
|
|
|
#include <condition_variable>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <set>
|
|
#include <thread>
|
|
|
|
#include "cotest-coro-common.h"
|
|
|
|
namespace coro_impl {
|
|
|
|
/**
|
|
* Implement stacky coroutines on C++ threads
|
|
*/
|
|
class CoroOnThread final : public ExteriorInterface, public InteriorInterface {
|
|
public:
|
|
// Rule of 5 but disallow copy and move. Immutable and non-nullable.
|
|
CoroOnThread() = delete;
|
|
CoroOnThread(const CoroOnThread &i) = delete;
|
|
CoroOnThread(CoroOnThread &&i) = delete;
|
|
CoroOnThread &operator=(const CoroOnThread &) = delete;
|
|
CoroOnThread &operator=(CoroOnThread &&) = delete;
|
|
~CoroOnThread();
|
|
|
|
CoroOnThread(BodyFunction cofn_, std::string name);
|
|
|
|
// ExteriorInterface
|
|
std::unique_ptr<Payload> Iterate(std::unique_ptr<Payload> &&to_coro) final;
|
|
std::unique_ptr<Payload> ThrowIn(std::exception_ptr in_ex) final;
|
|
void Cancel() final;
|
|
bool IsCoroutineExited() const final;
|
|
void SetName(std::string name_) final;
|
|
std::string GetName() const final;
|
|
|
|
// InteriorInterface
|
|
std::unique_ptr<Payload> Yield(std::unique_ptr<Payload> &&from_coro) final;
|
|
|
|
InteriorInterface *GetActive() final;
|
|
|
|
private:
|
|
enum class Phase { CoroutineRuns, MainRuns, CoroutineExited };
|
|
|
|
void ThreadRun();
|
|
void TrySetThreadName();
|
|
void NotifyPhase(Phase new_phase);
|
|
void WaitPhases(std::set<Phase> phases);
|
|
|
|
BodyFunction coro_run_function;
|
|
|
|
std::thread local_thread;
|
|
|
|
Phase phase = Phase::MainRuns;
|
|
mutable std::mutex phase_mutex;
|
|
|
|
std::condition_variable cv;
|
|
|
|
std::unique_ptr<Payload> payload;
|
|
std::exception_ptr payload_ex;
|
|
|
|
std::string name;
|
|
|
|
static InteriorInterface *active;
|
|
};
|
|
|
|
} // namespace coro_impl
|
|
|
|
#endif
|