Boost logo

Boost :

From: Ruben Perez (rubenperez038_at_[hidden])
Date: 2024-06-06 16:52:54


> When you say:
>
> - The way it handles cancellation is not ideal - it should wait until both async operations finish before returning or throwing the relevant exception.
>
> which operations are you referring on? Read and Write?

When you call TimeoutSerial::read, two async operations are fired in parallel:
- A read operation (asio::async_read, in your case):
https://github.com/fedetft/serial-port/blob/291a7997a665a52bf37d15c615679445724cf453/2_with_timeout/TimeoutSerial.cpp#L198-L210
- A timer wait (https://github.com/fedetft/serial-port/blob/291a7997a665a52bf37d15c615679445724cf453/2_with_timeout/TimeoutSerial.cpp#L110-L111)

The idea is that you run both in parallel, and when the first one
finishes, the second one gets cancelled. However, even if you cancel
an Asio async operation, its completion handler gets called (with a
cancelled error code). The problem is that TimeoutSerial::read, upon
timeout, is cancelling the asio::async_read operation but not waiting
for the handler to be called:
https://github.com/fedetft/serial-port/blob/291a7997a665a52bf37d15c615679445724cf453/2_with_timeout/TimeoutSerial.cpp#L123-L125

This is being workarounded in these lines, but the workaround is not
taking OSX into account:
https://github.com/fedetft/serial-port/blob/291a7997a665a52bf37d15c615679445724cf453/2_with_timeout/TimeoutSerial.cpp#L227-L241

Writing this cleanly requires a big refactor of the class. For a quick
workaround, you can try adding this line just after the ones I linked
to:

if (error == boost::asio::error::operation_aborted) return;

Ruben.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk