I need to know how to read (sync or async doesn't matters) with a timeout. I want to check if a device is connected with a serial port or not.
For that I use asio::write
and then I wait for the response of the device.
If a device is connected asio::read(serial, boost::asio::buffer(&r,1))
works fine but if there is no device the program stops, which is is why I need the timeout
I know that I need a deadline_timer
but I have no idea how to use it in the async_read
function.
An example of how it works would be really helpful.
I know that there are many similar threads and I read lot of them but I can't find a solution that helps me solving my problem!
You don't use
deadline_timer
inasync_read
. But you can start two async processes:async_read
process on serial port. boost::asio::serial_port has a cancel method that cancels all async operations on it.deadline_timer
you cancancel
the serial port. This should close theasync_read
operation and call its completion handler with an error.Code:
The code posted by Igor R. did not compile for me. Here is my improved version of his code, which works perfectly. It uses lambdas to get rid of the
set_result
helper function.Once upon a time, the library author proposed the following way to read synchronously with timeout (this example involves
tcp::socket
, but you can use serial port instead):There's no one or easy answer per se, since even if you do an async read, the callback never gets called and you now have a loose thread somewhere around.
You're right in assuming that
deadline_timer
is one of the possible solutions, but it takes some fiddling and shared state. There's the blocking TCP example, but that's forasync_connect
and there's a cool thing about it returning when it has nothing to do.read
won't do that, worst case scenario -- it'll crash & burn 'cause of the invalid resource. So thedeadline timer
thing is one of your options, but there's actually an easier one, that goes somewhat like this:Basically, do the read in another thread and kill it off if it times out. You should read up on Boost.Threads.
If you interrupt it, make sure the resources are all closed.