Instead of canceling the read_loop, close the socket and wait for the read_loop to finish as a result. This prevents the receive_from from writing into the buffer (which is on the stack!) after the task is canceled. This caused nasty intermittent exception stack unwind errors.
This commit is contained in:
parent
881903c1be
commit
c79cbdae8e
1 changed files with 16 additions and 4 deletions
|
|
@ -30,11 +30,13 @@ namespace fc
|
|||
|
||||
|
||||
fc::future<void> _request_time_task_done;
|
||||
bool _shutting_down_ntp;
|
||||
|
||||
ntp_impl() :
|
||||
_ntp_thread("ntp"),
|
||||
_request_interval_sec( 60*60 /* 1 hr */),
|
||||
_last_ntp_delta_microseconds(0)
|
||||
_last_ntp_delta_microseconds(0),
|
||||
_shutting_down_ntp(false)
|
||||
{
|
||||
_last_ntp_delta_initialized = false;
|
||||
_ntp_hosts.push_back( std::make_pair( "pool.ntp.org",123 ) );
|
||||
|
|
@ -143,11 +145,16 @@ namespace fc
|
|||
}
|
||||
catch (...)
|
||||
{
|
||||
//don't restart read loop if we're destructing
|
||||
if (_shutting_down_ntp)
|
||||
return;
|
||||
//swallow any other exception and restart loop
|
||||
elog("unexpected exception in read_loop, going to restart it.");
|
||||
}
|
||||
_sock.close();
|
||||
fc::usleep(fc::seconds(_request_interval_sec));
|
||||
fc::usleep(fc::seconds(1));
|
||||
if (_shutting_down_ntp)
|
||||
return;
|
||||
} //outer while loop
|
||||
} //end read_loop()
|
||||
};
|
||||
|
|
@ -165,6 +172,7 @@ namespace fc
|
|||
ntp::~ntp()
|
||||
{
|
||||
my->_ntp_thread.async([=](){
|
||||
my->_shutting_down_ntp = true;
|
||||
try
|
||||
{
|
||||
my->_request_time_task_done.cancel_and_wait("ntp object is destructing");
|
||||
|
|
@ -177,7 +185,11 @@ namespace fc
|
|||
{
|
||||
wlog( "Exception thrown while shutting down NTP's request_time_task, ignoring" );
|
||||
}
|
||||
|
||||
//instead of canceling task, we close the socket and wait for the task to end because receive_from will throw
|
||||
//if we just canceled the task, the receive_from would likely complete after the recv_buf was gone and we would get a random write into our stack.
|
||||
my->_sock.close();
|
||||
my->_read_loop_done.wait(); //wait for socket to close
|
||||
#if 0
|
||||
try
|
||||
{
|
||||
my->_read_loop_done.cancel_and_wait("ntp object is destructing");
|
||||
|
|
@ -190,7 +202,7 @@ namespace fc
|
|||
{
|
||||
wlog( "Exception thrown while shutting down NTP's read_loop, ignoring" );
|
||||
}
|
||||
|
||||
#endif
|
||||
}, "ntp_shutdown_task").wait();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue