mirror of
https://gitlab.com/niansa/libcrosscoro.git
synced 2025-03-06 20:53:32 +01:00
* std::shared_ptr<executor_type> for coro::shared_mutex * implement remaining types that leverage executor or io_scheduler
55 lines
2.2 KiB
C++
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)));
|
|
}
|