How to use boost::asio to implement a synchronous operation with timeouts?

I'm trying to develop some function that will block until the protocol exchange finished or some error occur, or timeout.
In the boost official documents, the example of timeouts in asio is implements by asynchronous operations and a deadline_timer. But what I want is a synchronous operation with a timeout, but I search nearly all of the reference manual and find nothing about it.
In an other words, how can I used the asynchronous operations to simulate synchronous operations with timeouts.
Maybe I could launch an asynchronous operation and call io_service::run_one immediately, but I don't know whether it is safe when I call io_service::run_one in a complete callback function which is call by io_service::run?
Or there is any classic solution of this question.
Thank you.
I recommend asking this on the boost-users mailing list.
Basically, you will write a function ('CompletionCondition') to check if any of your three conditions have been met, along with a 'ReadHandler' which notifies your program that it no longer needs to "block" on the read. You then pass these to async_read() overload #2, the first one with a 'CompletionCondition', then wait for the notification from the 'ReadHandler'.

There are details about what 'CompletionCondition' should look like in the documentation for async_read() overload #4.

I'm not sure what your concern is regarding io_service. If you are calling io_service::run(), there is no need to call run_one() anywhere.

This will allow you to simulate synchronous operations with timeouts, but essentially just moves the code that would normally be in the 'ReadHandler' to the function that calls async_read() and waits for notification.

HTH
Last edited on
What I mean is a blocked function, when I invoke it, my thread block on it and wait any result happen.
But in asio, the thread is block on io_service::run, that maybe bother because if I want to input some command in a console and wait the protocol exchange result. The io_service can not wait console input, so what I do is sending the asynchronous operation and invoking io_service::run_one immediately. If there is more than one pair of protocol exchanges, I simply start an asynchronous operation and invoke io_service::run_one again in the ReadHandler callback.
And it seems work well on win32 platform. It seems not the normal usage and I don't know whether it is safe and protable.
You should spawn a thread to do the io_service::run() call.

You can then simulate blocking io in the main thread as described above, and you can get rid of the io_service::run_one() calls.

The way you're doing it now can start to cause problems if you exchange a lot of data. In your current design, io_service::run_one() will block, waiting for a handler to finish, but the handler calls run_one(), which again, won't return until a handler finishes. You effectively have a recursive call to run_one() where the base case is 'no more protocol exchanges'.

If you're happy with the design, and it's not for large exchanges, you can continue to use it. To simulate blocking io, exchange your current asynchronous operations with the async_read() detailed in my first reply.
Last edited on
Topic archived. No new replies allowed.