1
0
Fork 0
mirror of https://gitlab.com/niansa/libcrosscoro.git synced 2025-03-06 20:53:32 +01:00
libcrosscoro/examples/coro_shared_mutex.cpp
Josh Baldwin 475bcf6d8b
std::shared_ptr<executor_type> for coro::shared_mutex (#86)
* std::shared_ptr<executor_type> for coro::shared_mutex

* implement remaining types that leverage executor or io_scheduler
2021-05-22 22:36:57 -06:00

55 lines
2.2 KiB
C++

#include <coro/coro.hpp>
#include <iostream>
int main()
{
// Shared mutexes require an excutor type to be able to wake up multiple shared waiters when
// there is an exclusive lock holder releasing the lock. This example uses a single thread
// to also show the interleaving of coroutines acquiring the shared lock in shared and
// exclusive mode as they resume and suspend in a linear manner. Ideally the thread pool
// executor would have more than 1 thread to resume all shared waiters in parallel.
auto tp = std::make_shared<coro::thread_pool>(coro::thread_pool::options{.thread_count = 1});
coro::shared_mutex mutex{tp};
auto make_shared_task = [&](uint64_t i) -> coro::task<void> {
co_await tp->schedule();
{
std::cerr << "shared task " << i << " lock_shared()\n";
auto scoped_lock = co_await mutex.lock_shared();
std::cerr << "shared task " << i << " lock_shared() acquired\n";
/// Immediately yield so the other shared tasks also acquire in shared state
/// while this task currently holds the mutex in shared state.
co_await tp->yield();
std::cerr << "shared task " << i << " unlock_shared()\n";
}
co_return;
};
auto make_exclusive_task = [&]() -> coro::task<void> {
co_await tp->schedule();
std::cerr << "exclusive task lock()\n";
auto scoped_lock = co_await mutex.lock();
std::cerr << "exclusive task lock() acquired\n";
// Do the exclusive work..
std::cerr << "exclusive task unlock()\n";
co_return;
};
// Create 3 shared tasks that will acquire the mutex in a shared state.
const size_t num_tasks{3};
std::vector<coro::task<void>> tasks{};
for (size_t i = 1; i <= num_tasks; ++i)
{
tasks.emplace_back(make_shared_task(i));
}
// Create an exclusive task.
tasks.emplace_back(make_exclusive_task());
// Create 3 more shared tasks that will be blocked until the exclusive task completes.
for (size_t i = num_tasks + 1; i <= num_tasks * 2; ++i)
{
tasks.emplace_back(make_shared_task(i));
}
coro::sync_wait(coro::when_all(std::move(tasks)));
}