#pragma once #ifndef MIJIN_ASYNC_TASK_MUTEX_HPP_INCLUDED #define MIJIN_ASYNC_TASK_MUTEX_HPP_INCLUDED 1 #include "./coroutine.hpp" #include "../internal/common.hpp" namespace mijin { class [[nodiscard]] TaskMutexLock { private: class TaskMutex* mutex_; public: explicit TaskMutexLock(class TaskMutex* mutex) MIJIN_NOEXCEPT : mutex_(mutex) {} TaskMutexLock(const TaskMutexLock&) = delete; TaskMutexLock(TaskMutexLock&& other) MIJIN_NOEXCEPT : mutex_(std::exchange(other.mutex_, nullptr)) {} TaskMutexLock& operator=(const TaskMutexLock&) = delete; inline TaskMutexLock& operator=(TaskMutexLock&& other) MIJIN_NOEXCEPT; inline ~TaskMutexLock() MIJIN_NOEXCEPT; }; class TaskMutex { private: bool locked_ = false; public: Task c_lock() { while (locked_) { co_await c_suspend(); } locked_ = true; co_return TaskMutexLock(this); } [[nodiscard]] inline bool isLocked() const MIJIN_NOEXCEPT { return locked_; } friend class TaskMutexLock; }; TaskMutexLock::~TaskMutexLock() MIJIN_NOEXCEPT { if (mutex_) { mutex_->locked_ = false; } } TaskMutexLock& TaskMutexLock::operator=(TaskMutexLock&& other) MIJIN_NOEXCEPT { if (mutex_) { mutex_->locked_ = false; } mutex_ = std::exchange(other.mutex_, nullptr); return *this; } } #endif // MIJIN_ASYNC_TASK_MUTEX_HPP_INCLUDED