boostorg / boostorg/cobalt

Racing a range of generators breaks generators in the range

Open
#281 6 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
347
Forks
47
Avg merge
3d 8h
Merged PRs (30d)
1

Description

Sometimes I have several generators and I want to wait for one of them to yield a result, so I race them. I may do this repeatedly: race the generators, handle the one that won the race, then race them again, handle the next winner, etc...

If I store my generators in a plain vector, that works fine.

If, however, I store my generators in something more complex and make a Range of them to pass to race, this only works once. The generator what wins the race is fine, but all other generators in the range are somehow damaged and attempting to await them (or put them in a race) causes an exception to be thrown saying a generator returned void.

Am I doing something wrong, or is this a bug?

Simple program to reproduce the issue:

```c++
// Compile with -std=c++23 -lboost_cobalt
#include
#include

#include
#include
#include
#include

namespace asio = boost::asio;
namespace cb = boost::cobalt;
namespace v = std::views;
using namespace std;

cb::generator generate(int start) {
asio::steady_timer tim{co_await asio::this_coro::executor,
std::chrono::milliseconds(start)};
try {
while (true) {
co_await tim.async_wait(cb::use_op);
co_yield start++;
}
} catch (const boost::system::system_error& e) {
if (e.code() != boost::asio::error::operation_aborted)
throw;
}

co_return 0;
}

cb::main co_main(int argc, char* argv[]) {
vector> storage;
storage.emplace_back(generate(1));
storage.emplace_back(generate(10));

// If we pass storage raw to race, it works fine
// If we instead pass a range view, things break
co_await cb::race(v::transform(storage, std::identity()));
// Index 0 should have won the race, so now let's await index 1. This throws.
co_await storage[1];

co_return 0;
}

```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.