diff --git a/coio.cpp b/coio.cpp index 33084da..6f261f3 100644 --- a/coio.cpp +++ b/coio.cpp @@ -324,3 +324,28 @@ coio_active_throw() throw std::logic_error("Not inside coroutine"); } } + +CoioMutex::CoioMutex() { + owner = nullptr; +} + +void +CoioMutex::lock() { + if (owner == nullptr) { + owner = coio_current; + } else { + waiting.push_back(coio_current); + coio_delay(-1); + } +} + +void +CoioMutex::unlock() { + if (!waiting.empty()) { + owner = waiting.back(); + waiting.pop_back(); + coio_ready(owner); + } else { + owner = nullptr; + } +} diff --git a/coio.h b/coio.h index 3d726db..b58b4f7 100644 --- a/coio.h +++ b/coio.h @@ -17,6 +17,7 @@ #define COIO_H #include +#include typedef struct CoioTask CoioTask; typedef std::function coio_func; @@ -44,4 +45,18 @@ coio_active(); void coio_active_throw(); +class CoioMutex { + CoioTask* owner; + std::vector waiting; +public: + CoioMutex(); + ~CoioMutex() = default; + + CoioMutex(const CoioMutex&) = delete; + CoioMutex& operator=(const CoioMutex&) = delete; + + void lock(); + void unlock(); +}; + #endif