Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

boost asio single threaded post() doesn't post when poll() is used?

Everything is handle in a single thread

void GameClient::test()
{
   std::cout <<"called test" << std::endl;
    m_io_context.post([](){
        std::cout << "test" << std::endl;
    });
}

void GameClient::calledFromALoop()
{
    // Use poll instead of run to avoid blocking
    auto count = m_io_context.poll();
    std::cout << "polled: " << count << std::endl;
}

I want every async task to be handled in calledFromALoop() function.
It is called from a loop around 50 times per second.

This is the output:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

...
polled: 0
polled: 0
polled: 0
called test
polled: 0
polled: 0
polled: 0
...

Can you help me understand why the lambda in post isn’t executed ?
This is a minimal example, originally in the test function, I use async_resolve, but I have the same behavior.

I don’t want to use run() because I don’t want calledFromALoop() to block.

But then I don’t really understand when the async function is executed (not the handler).
For example I assume async_resolve need some work to set up the resolution, then some time to perform network operation, then the handler (callback). When do these steps are executed ?
I think the set up is done at the call of async_resolve, then network time, then the callback is called from poll(). Am I right ?
Using run() instead of poll() will block during the network time.

The weird behavior is if I change the position of this line auto count = m_io_context.poll();
like this:

void GameClient::test()
{
   std::cout <<"called test" << std::endl;
    m_io_context.post([](){
        std::cout << "test" << std::endl;
    });
    m_io_context.poll();
}

void GameClient::calledFromALoop()
{
    
}

I have called test test as expected !

>Solution :

Sure it does:

Live On Coliru

#include <boost/asio.hpp>
#include <iostream>
namespace asio = boost::asio;

int main() {
    asio::io_context ioc(1);

    post(ioc, [] { std::cout << "Hello, world!" << std::endl; });

    ioc.poll();
}

Prints

Hello, world!

Running Out Of Work

Like others commented, you might let the service run out of work. You must prevent that or reset() it.

asio::io_context ioc(1);

post(ioc, [] { std::cout << "Hello, world!" << std::endl; });
ioc.poll();

post(ioc, [] { std::cout << "Hello, world!" << std::endl; });
ioc.poll(); // doesn't print anything

However, e.g.:

auto work = make_work_guard(ioc);

post(ioc, [] { std::cout << "Hello, world!" << std::endl; });
ioc.poll();

post(ioc, [] { std::cout << "Hello, world!" << std::endl; });
ioc.poll(); // prints!
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading