mijin2/source/mijin/async/task_mutex.hpp

65 lines
1.4 KiB
C++

#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<TaskMutexLock> 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