diff --git a/include/fc/crypto/city.hpp b/include/fc/crypto/city.hpp index 7e42f37..7047ae8 100644 --- a/include/fc/crypto/city.hpp +++ b/include/fc/crypto/city.hpp @@ -47,9 +47,9 @@ namespace fc { -class uint128; template class array; +class uint128; // Hash function for a byte array. uint64_t city_hash64(const char *buf, size_t len); @@ -72,4 +72,5 @@ uint64_t city_hash_crc_64(const char *buf, size_t len); uint128 city_hash_crc_128(const char *s, size_t len); array city_hash_crc_256(const char *s, size_t len); + } // namespace fc diff --git a/src/rpc/json_connection.cpp b/src/rpc/json_connection.cpp index cd1d6b4..bde046a 100644 --- a/src/rpc/json_connection.cpp +++ b/src/rpc/json_connection.cpp @@ -68,6 +68,7 @@ namespace fc { namespace rpc { void handle_message( const variant_object& obj ) { wlog( "recv: ${msg}", ("msg", obj) ); + fc::exception_ptr eptr; try { auto m = obj.find("method"); @@ -158,6 +159,7 @@ namespace fc { namespace rpc { } else if( e != obj.end() ) //if error response { + fc::exception_ptr eptr; try { auto err = e->value().get_object(); @@ -173,8 +175,9 @@ namespace fc { namespace rpc { catch ( fc::exception& e ) { elog( "Error parsing exception: ${e}", ("e", e.to_detail_string() ) ); - await->second->set_exception( e.dynamic_copy_exception() ); + eptr = e.dynamic_copy_exception(); } + if( eptr ) await->second->set_exception( eptr ); } else // id found without error, result, nor method field { @@ -191,12 +194,14 @@ namespace fc { namespace rpc { { fc_elog( _logger, "json rpc exception: ${exception}", ("exception",e )); elog( "json rpc exception: ${exception}", ("exception",e )); - close(e.dynamic_copy_exception()); + eptr = e.dynamic_copy_exception(); } + if( eptr ) { close(eptr); } } void read_loop() { + fc::exception_ptr eptr; try { fc::string line; @@ -211,16 +216,17 @@ namespace fc { namespace rpc { catch ( eof_exception& eof ) { _eof = true; - close( eof.dynamic_copy_exception() ); + eptr = eof.dynamic_copy_exception(); } catch ( exception& e ) { - close( e.dynamic_copy_exception() ); + eptr = e.dynamic_copy_exception(); } catch ( ... ) { - close( fc::exception_ptr(new FC_EXCEPTION( unhandled_exception, "json connection read error" )) ); + eptr = fc::exception_ptr(new FC_EXCEPTION( unhandled_exception, "json connection read error" )); } + if( eptr ) close( eptr ); } void close( fc::exception_ptr e ) diff --git a/src/thread/future.cpp b/src/thread/future.cpp index d0b5252..1950086 100644 --- a/src/thread/future.cpp +++ b/src/thread/future.cpp @@ -62,16 +62,14 @@ namespace fc { } _enqueue_thread(); } - try - { - thread::current().wait_until( ptr(this,true), timeout_us ); - } - catch (...) - { - _dequeue_thread(); - throw; - } + std::exception_ptr e; + try { thread::current().wait_until( ptr(this,true), timeout_us ); } + catch (...) { e = std::current_exception(); } + _dequeue_thread(); + + if( e ) std::rethrow_exception(e); + if( _ready ) { if( _exceptp ) diff --git a/src/thread/mutex.cpp b/src/thread/mutex.cpp index 0ebd834..9f3f9ba 100644 --- a/src/thread/mutex.cpp +++ b/src/thread/mutex.cpp @@ -118,13 +118,18 @@ namespace fc { cc->next_blocked_mutex = m_blist; m_blist = cc; } // end lock scope + + + std::exception_ptr e; try { fc::thread::current().my->yield_until( abs_time, false ); return( 0 == cc->next_blocked_mutex ); } catch (...) { - cleanup( *this, m_blist_lock, m_blist, cc); - throw; + e = std::current_exception(); } + assert(e); + cleanup( *this, m_blist_lock, m_blist, cc); + std::rethrow_exception(e); } void mutex::lock() { @@ -166,6 +171,7 @@ namespace fc { #endif } + std::exception_ptr e; // cleanup calls yield so we need to move the exception outside of the catch block try { fc::thread::current().yield(false); @@ -174,17 +180,13 @@ namespace fc { assert(recursive_lock_count == 0); recursive_lock_count = 1; } - catch ( exception& e ) - { - wlog( "lock threw: ${e}", ("e", e)); - cleanup( *this, m_blist_lock, m_blist, current_context); - FC_RETHROW_EXCEPTION(e, warn, "lock threw: ${e}", ("e", e)); - } catch ( ... ) { - wlog( "lock threw unexpected exception" ); + e = std::current_exception(); + } + if( e ) { cleanup( *this, m_blist_lock, m_blist, current_context); - throw; + std::rethrow_exception(e); } } diff --git a/src/thread/task.cpp b/src/thread/task.cpp index 7f45522..b081872 100644 --- a/src/thread/task.cpp +++ b/src/thread/task.cpp @@ -56,7 +56,7 @@ namespace fc { } catch ( ... ) { - set_exception( std::make_shared( FC_LOG_MESSAGE( warn, "unhandled exception: ${diagnostic}", ("diagnostic",boost::current_exception_diagnostic_information()) ) ) ); + set_exception( std::make_shared( FC_LOG_MESSAGE( warn, "unhandled exception: ${diagnostic}", ("diagnostic",boost::current_exception_diagnostic_information()) ) ) ); } } diff --git a/src/thread/thread_d.hpp b/src/thread/thread_d.hpp index bb7370f..941b2fa 100644 --- a/src/thread/thread_d.hpp +++ b/src/thread/thread_d.hpp @@ -474,10 +474,7 @@ namespace fc { { self->process_tasks(); } - catch ( canceled_exception& ) - { - // allowed exception... - } + catch ( canceled_exception& ) { /* allowed exception */ } catch ( ... ) { elog( "fiber ${name} exited with uncaught exception: ${e}", ("e",fc::except_str())("name", self->name) );