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;
|
fc::future<void> _request_time_task_done;
|
||||||
|
bool _shutting_down_ntp;
|
||||||
|
|
||||||
ntp_impl() :
|
ntp_impl() :
|
||||||
_ntp_thread("ntp"),
|
_ntp_thread("ntp"),
|
||||||
_request_interval_sec( 60*60 /* 1 hr */),
|
_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;
|
_last_ntp_delta_initialized = false;
|
||||||
_ntp_hosts.push_back( std::make_pair( "pool.ntp.org",123 ) );
|
_ntp_hosts.push_back( std::make_pair( "pool.ntp.org",123 ) );
|
||||||
|
|
@ -143,11 +145,16 @@ namespace fc
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
//don't restart read loop if we're destructing
|
||||||
|
if (_shutting_down_ntp)
|
||||||
|
return;
|
||||||
//swallow any other exception and restart loop
|
//swallow any other exception and restart loop
|
||||||
elog("unexpected exception in read_loop, going to restart it.");
|
elog("unexpected exception in read_loop, going to restart it.");
|
||||||
}
|
}
|
||||||
_sock.close();
|
_sock.close();
|
||||||
fc::usleep(fc::seconds(_request_interval_sec));
|
fc::usleep(fc::seconds(1));
|
||||||
|
if (_shutting_down_ntp)
|
||||||
|
return;
|
||||||
} //outer while loop
|
} //outer while loop
|
||||||
} //end read_loop()
|
} //end read_loop()
|
||||||
};
|
};
|
||||||
|
|
@ -165,6 +172,7 @@ namespace fc
|
||||||
ntp::~ntp()
|
ntp::~ntp()
|
||||||
{
|
{
|
||||||
my->_ntp_thread.async([=](){
|
my->_ntp_thread.async([=](){
|
||||||
|
my->_shutting_down_ntp = true;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
my->_request_time_task_done.cancel_and_wait("ntp object is destructing");
|
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" );
|
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
|
try
|
||||||
{
|
{
|
||||||
my->_read_loop_done.cancel_and_wait("ntp object is destructing");
|
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" );
|
wlog( "Exception thrown while shutting down NTP's read_loop, ignoring" );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}, "ntp_shutdown_task").wait();
|
}, "ntp_shutdown_task").wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue