I am working on a boost asio project, where I have a bunch of stackful coroutines (https://www.boost.org/doc/libs/1_82_0/doc/html/boost_asio/overview/composition/spawn.html), performing asynchronous operations, and I use a strand to synchronize access to critical sections like so:
io_context ioctx;
io_context::strand my_strand{ioctx};
void my_coroutine(yield_context yield) {
while (true) {
post(my_strand, yield);
// Critical section, where one coroutine is supposed to have access
post(ioctx, yield);
}
}
However, I began to suspect that mutual exclusion was not happening, and wrote a small test to test out my hypothesis:
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
using namespace boost::asio;
io_context ioctx;
io_context::strand my_strand{ioctx};
std::atomic_int cnt{0};
void my_coroutine(yield_context yield) {
while (true) {
post(my_strand, yield);
cnt++;
assert(cnt == 1);
assert(my_strand.running_in_this_thread());
cnt--;
post(ioctx, yield);
}
}
int main() {
spawn(ioctx, [&](yield_context yield) { my_coroutine(yield); });
spawn(ioctx, [&](yield_context yield) { my_coroutine(yield); });
for (int i = 0; i < 5; ++i) {
std::thread([] { ioctx.run(); }).detach();
}
getchar();
}
As I suspected, both assertions fail when the program runs. I am not sure where the issue is.
Most surprisingly, commenting out one of the spawn calls still causes the running_in_this_thread
assertion to fail!
I am using Boost v1.81.0 on linux.