add support for async mutex
Add support for async mutex for synchronizing coroutines/tasks using
sender receiver framework. Also, add lock_guard support which provides a
RAII wrapper for mutex to own it for the duration of a scoped block.
Tested: Add Unit Test using gtest
```
1/1 test_async_mutex OK 2.01s
Ok: 1
Expected Fail: 0
Fail: 0
Unexpected Pass: 0
Skipped: 0
Timeout: 0
```
Change-Id: I691528885a94b9cf55d4b7f2fb0c1e0e6d0ab84f
Signed-off-by: Jagpal Singh Gill <paligill@gmail.com>
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
diff --git a/src/async/mutex.cpp b/src/async/mutex.cpp
new file mode 100644
index 0000000..44694c6
--- /dev/null
+++ b/src/async/mutex.cpp
@@ -0,0 +1,54 @@
+#include <sdbusplus/async/mutex.hpp>
+
+namespace sdbusplus::async
+{
+
+mutex::mutex(const std::string& name) : name(name) {}
+
+void mutex::unlock()
+{
+ std::unique_lock l{lock};
+ if (waitingTasks.empty())
+ {
+ auto wasLocked = std::exchange(locked, false);
+ if (!wasLocked)
+ {
+ try
+ {
+ throw std::runtime_error("mutex is not locked!");
+ }
+ catch (...)
+ {
+ std::terminate();
+ }
+ }
+ return;
+ }
+ // Wake up the next waiting task
+ auto completion = std::move(waitingTasks.front());
+ waitingTasks.pop();
+ l.unlock();
+ completion->complete();
+}
+
+namespace mutex_ns
+{
+
+void mutex_completion::arm() noexcept
+{
+ std::unique_lock l{mutexInstance.lock};
+
+ auto wasLocked = std::exchange(mutexInstance.locked, true);
+ if (!wasLocked)
+ {
+ l.unlock();
+ complete();
+ return;
+ }
+
+ mutexInstance.waitingTasks.push(this);
+}
+
+} // namespace mutex_ns
+
+} // namespace sdbusplus::async