In the recent development of my project have I used std::future
with async_read_some
so that caller, say user thread, can wait for specific duration on asynchronous I/O and appear like a synchronous procedure. But call to get std::future object async_read_some function yields never returns in case that the remote connecting peer corrupts. It seems that system error in asynchronous operation is not propagated as stated at all.
std::future<size_t> result=socket.async_read_some(boost::asio::buffer(data, size), boost::asio::use_future);
std::future_status status=result.wait_for(std::chrono::millisecond(1000));
switch(status){
case std::future_status::ready:
try{
bytes=result.get(); /* never returns in case of peer disconnection */
}catch(std::system_error & error){
/* print something only if error is caught */
}
break;
case std::future_status::timeout:
...
case std::future_status::deferred:
...
};
when program runs in according scenario, the process "sinks" - it appears exactly like there is deadlock in asio implementation. A trace stops in implementation of std::future::get()
/// Wait for the state to be ready and rethrow any stored exception
__result_type
_M_get_result() const
{
_State_base::_S_check(_M_state);
_Result_base& __res = _M_state->wait();
if (!(__res._M_error == 0))
--> rethrow_exception(__res._M_error); <-- //deepest trace with available source
return static_cast<__result_type>(__res);
}
After investigating into documentation, I found very few words
std::future<std::size_t> my_future = my_socket.async_read_some(my_buffer, boost::asio::use_future);
The initiating function (async_read_some in the above example) returns a future that will receive the result of the operation. If the operation completes with an error_code indicating failure, it is converted into a system_error and passed back to the caller via the future.
However, there is NOTHING my program catches around result.get()
.
PS: linux 3.8.0-37-generic #53~precise1-Ubuntu SMP Wed Feb 19 21:39:14 UTC 2014 i686 i686 i386 GNU/Linux