1

I'm working on a async udp server for a multiplayer game. It is a personal project and for education. I'm using ASIO standalone and C++20, mainly relying on coroutines. For the past couple of days I've been trying to implement a function that works similarly to 'async_read' for example (already defined in ASIO). This function should give back control to the io_context if a queue (which is passed as a parameter) is empty, or take control back if the queue contains at least one element. I hope the code snippets clarify what I'm trying to do.

I want to use it this way:

asio::awaitable<void> udp_server::process() {
    // process messages from queue for the entire lifetime of the server
    while (true) {
        // pause here until there is a message in the queue
        // and do other work meanwhile (read from clients, compute stuff, etc)
        co_await async_wait_for_queue(coro_queue_in, asio::use_awaitable);
        
        // get the message in front of the queue
        auto& msg = coro_queue_in.front();
        coro_queue_in.pop();

        // and process it (for now, just print it)
        std::cout << msg << "\n";
        // and then repeat this all over again
    }
}

So while the server is running I want to have a bunch of tasks in the io_context queue which read data from each client and also a task which processes the incoming messages.

struct async_queue_implementation {
    std::queue<owned_message>& queue_;
    template<typename Self> void operator()(Self& self) {
        if (!queue_.empty()) {
            self.complete();
        }
    }
};

template<typename CompletionToken>
auto async_wait_for_queue(std::queue<owned_message>& queue,
    CompletionToken&& token) -> 
    decltype(asio::async_compose<CompletionToken, void()>
    (std::declval<async_queue_implementation>(), token))
{
    return asio::async_compose<CompletionToken, void()>
        (async_queue_implementation{ queue }, token);
}

I've tried this but it doesn't work. It compiles, it runs, but it doesn't ever get past line 3 from the previous code snippet. It's as if the task never resumes, but it should, because I can confirm that the queue receives new elements and so it is not empty.

Please help me implement such functionality using ASIO coroutines. I feel like I've gotten extremely close with the code above but something is still missing.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.