64 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			64 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
 | |
| #pragma once
 | |
| 
 | |
| #ifndef MIJIN_ASYNC_TASK_MUTEX_HPP_INCLUDED
 | |
| #define MIJIN_ASYNC_TASK_MUTEX_HPP_INCLUDED 1
 | |
| 
 | |
| #include "./coroutine.hpp"
 | |
| 
 | |
| namespace mijin
 | |
| {
 | |
| class [[nodiscard]] TaskMutexLock
 | |
| {
 | |
| private:
 | |
|     class TaskMutex* mutex_;
 | |
| 
 | |
| public:
 | |
|     explicit TaskMutexLock(class TaskMutex* mutex) noexcept : mutex_(mutex) {}
 | |
|     TaskMutexLock(const TaskMutexLock&) = delete;
 | |
|     TaskMutexLock(TaskMutexLock&& other) noexcept : mutex_(std::exchange(other.mutex_, nullptr)) {}
 | |
| 
 | |
|     TaskMutexLock& operator=(const TaskMutexLock&) = delete;
 | |
|     inline TaskMutexLock& operator=(TaskMutexLock&& other) noexcept;
 | |
|     inline ~TaskMutexLock() 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 noexcept { return locked_; }
 | |
| 
 | |
|     friend class TaskMutexLock;
 | |
| };
 | |
| 
 | |
| TaskMutexLock::~TaskMutexLock() noexcept
 | |
| {
 | |
|     if (mutex_)
 | |
|     {
 | |
|         mutex_->locked_ = false;
 | |
|     }
 | |
| }
 | |
| 
 | |
| TaskMutexLock& TaskMutexLock::operator=(TaskMutexLock&& other) noexcept
 | |
| {
 | |
|     if (mutex_)
 | |
|     {
 | |
|         mutex_->locked_ = false;
 | |
|     }
 | |
|     mutex_ = std::exchange(other.mutex_, nullptr);
 | |
|     return *this;
 | |
| }
 | |
| }
 | |
| 
 | |
| #endif // MIJIN_ASYNC_TASK_MUTEX_HPP_INCLUDED
 |