diff --git a/Builds/CMake/CMakeFuncs.cmake b/Builds/CMake/CMakeFuncs.cmake index 764aa2e3a..0b2fe56b7 100644 --- a/Builds/CMake/CMakeFuncs.cmake +++ b/Builds/CMake/CMakeFuncs.cmake @@ -527,8 +527,7 @@ macro(setup_build_boilerplate) endif() if (APPLE) - add_definitions(-DBEAST_COMPILE_OBJECTIVE_CPP=1 - -DNO_LOG_UNHANDLED_EXCEPTIONS) + add_definitions(-DBEAST_COMPILE_OBJECTIVE_CPP=1) add_compile_options( -Wno-deprecated -Wno-deprecated-declarations -Wno-unused-variable -Wno-unused-function) endif() diff --git a/Builds/VisualStudio2015/RippleD.vcxproj b/Builds/VisualStudio2015/RippleD.vcxproj index 79b3d3493..dec8064b7 100644 --- a/Builds/VisualStudio2015/RippleD.vcxproj +++ b/Builds/VisualStudio2015/RippleD.vcxproj @@ -1465,10 +1465,6 @@ True True - - True - True - True True @@ -1513,8 +1509,6 @@ - - @@ -1581,6 +1575,11 @@ True + + True + + + @@ -1616,11 +1615,6 @@ - - True - - - True @@ -1937,7 +1931,7 @@ ..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories) ..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories) - + True True ..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories) @@ -1975,7 +1969,7 @@ - + @@ -4353,6 +4347,10 @@ True True + + True + True + True True @@ -4437,6 +4435,10 @@ True True + + True + True + True True diff --git a/Builds/VisualStudio2015/RippleD.vcxproj.filters b/Builds/VisualStudio2015/RippleD.vcxproj.filters index d44b329ba..5d3743569 100644 --- a/Builds/VisualStudio2015/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2015/RippleD.vcxproj.filters @@ -1980,9 +1980,6 @@ ripple\basics\impl - - ripple\basics\impl - ripple\basics\impl @@ -2043,9 +2040,6 @@ ripple\basics - - ripple\basics - ripple\basics @@ -2142,6 +2136,12 @@ ripple\beast\core + + ripple\beast\core + + + ripple\beast\core + ripple\beast\core @@ -2190,12 +2190,6 @@ ripple\beast\core - - ripple\beast\core - - - ripple\beast\core - ripple\beast\core @@ -2532,7 +2526,7 @@ ripple\core\impl - + ripple\core\impl @@ -2571,7 +2565,7 @@ ripple\core - + ripple\core @@ -5109,6 +5103,9 @@ test\beast + + test\beast + test\beast @@ -5172,6 +5169,9 @@ test\core + + test\core + test\core diff --git a/SConstruct b/SConstruct index e7ac3bd30..b65a50a97 100644 --- a/SConstruct +++ b/SConstruct @@ -392,8 +392,6 @@ def config_base(env): env.Prepend(LIBPATH=['%s/lib' % openssl]) except: pass - if not 'vcxproj' in COMMAND_LINE_TARGETS: - env.Append(CPPDEFINES=['NO_LOG_UNHANDLED_EXCEPTIONS']) # handle command-line arguments profile_jemalloc = ARGUMENTS.get('profile-jemalloc') @@ -965,7 +963,7 @@ def get_classic_sources(toolchain): append_sources(result, *list_sources('src/test/shamap', '.cpp')) append_sources(result, *list_sources('src/test/jtx', '.cpp')) - + if use_shp(toolchain): cc_flags = {'CCFLAGS': ['--system-header-prefix=rocksdb2']} else: diff --git a/src/ripple/app/ledger/impl/LedgerCleaner.cpp b/src/ripple/app/ledger/impl/LedgerCleaner.cpp index 597f5b5ed..7951c3ab0 100644 --- a/src/ripple/app/ledger/impl/LedgerCleaner.cpp +++ b/src/ripple/app/ledger/impl/LedgerCleaner.cpp @@ -22,9 +22,8 @@ #include #include #include -#include #include -#include +#include namespace ripple { namespace detail { @@ -243,13 +242,7 @@ private: void run () { - threadEntry ( - this, &LedgerCleanerImp::runImpl, "LedgerCleanerImp::run()"); - } - - void runImpl () - { - beast::Thread::setCurrentThreadName ("LedgerCleaner"); + beast::setCurrentThreadName ("LedgerCleaner"); JLOG (j_.debug()) << "Started"; init(); diff --git a/src/ripple/app/main/BasicApp.cpp b/src/ripple/app/main/BasicApp.cpp index e44c8384e..6380bb979 100644 --- a/src/ripple/app/main/BasicApp.cpp +++ b/src/ripple/app/main/BasicApp.cpp @@ -19,8 +19,7 @@ #include #include -#include -#include +#include BasicApp::BasicApp(std::size_t numberOfThreads) { @@ -30,13 +29,10 @@ BasicApp::BasicApp(std::size_t numberOfThreads) threads_.emplace_back( [this, numberOfThreads]() { - beast::Thread::setCurrentThreadName( + beast::setCurrentThreadName( std::string("io_service #") + std::to_string(numberOfThreads)); - - ripple::threadEntry (&io_service_, - &boost::asio::io_service::run, - "io_service::run"); + this->io_service_.run(); }); } diff --git a/src/ripple/app/main/LoadManager.cpp b/src/ripple/app/main/LoadManager.cpp index 2f84f5c37..4837f0bb6 100644 --- a/src/ripple/app/main/LoadManager.cpp +++ b/src/ripple/app/main/LoadManager.cpp @@ -23,9 +23,8 @@ #include #include #include -#include #include -#include +#include #include #include #include @@ -108,12 +107,7 @@ void LoadManager::onStop () void LoadManager::run () { - threadEntry (this, &LoadManager::runImpl, "LoadManager::run()"); -} - -void LoadManager::runImpl () -{ - beast::Thread::setCurrentThreadName ("LoadManager"); + beast::setCurrentThreadName ("LoadManager"); using clock_type = std::chrono::steady_clock; diff --git a/src/ripple/app/main/LoadManager.h b/src/ripple/app/main/LoadManager.h index ab6c8b53c..d5d57404b 100644 --- a/src/ripple/app/main/LoadManager.h +++ b/src/ripple/app/main/LoadManager.h @@ -97,7 +97,6 @@ public: private: void run (); - void runImpl (); private: Application& app_; diff --git a/src/ripple/app/main/Main.cpp b/src/ripple/app/main/Main.cpp index 46fa8aaa4..441b9e5fd 100644 --- a/src/ripple/app/main/Main.cpp +++ b/src/ripple/app/main/Main.cpp @@ -25,10 +25,9 @@ #include #include #include -#include #include #include -#include +#include #include #include #include @@ -37,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -190,7 +190,7 @@ int run (int argc, char** argv) using namespace std; - setCallingThreadName ("main"); + beast::setCurrentThreadName ("rippled: main"); po::variables_map vm; @@ -453,8 +453,7 @@ int run (int argc, char** argv) app->doStart(); // Block until we get a stop RPC. - ripple::threadEntry ( - app.get(), &Application::run, "Main::run()"); + app->run(); // Try to write out some entropy to use the next time we start. auto entropy = getEntropyFile (app->config()); @@ -465,7 +464,7 @@ int run (int argc, char** argv) } // We have an RPC command to process: - setCallingThreadName ("rpc"); + beast::setCurrentThreadName ("rippled: rpc"); return RPCCall::fromCommandLine ( *config, vm["parameters"].as>(), @@ -519,9 +518,8 @@ int main (int argc, char** argv) #endif atexit(&google::protobuf::ShutdownProtobufLibrary); -#ifndef NO_LOG_UNHANDLED_EXCEPTIONS + std::set_terminate(ripple::terminateHandler); -#endif auto const result (ripple::run (argc, argv)); diff --git a/src/ripple/app/misc/SHAMapStoreImp.cpp b/src/ripple/app/misc/SHAMapStoreImp.cpp index 758466027..d715a8a46 100644 --- a/src/ripple/app/misc/SHAMapStoreImp.cpp +++ b/src/ripple/app/misc/SHAMapStoreImp.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -298,13 +298,7 @@ SHAMapStoreImp::copyNode (std::uint64_t& nodeCount, void SHAMapStoreImp::run() { - threadEntry ( - this, &SHAMapStoreImp::runImpl, "SHAMapStoreImp::run()"); -} - -void -SHAMapStoreImp::runImpl() -{ + beast::setCurrentThreadName ("SHAMapStore"); LedgerIndex lastRotated = state_db_.getState().lastRotated; netOPs_ = &app_.getOPs(); ledgerMaster_ = &app_.getLedgerMaster(); diff --git a/src/ripple/app/misc/SHAMapStoreImp.h b/src/ripple/app/misc/SHAMapStoreImp.h index d05b9eae0..f4cb75a02 100644 --- a/src/ripple/app/misc/SHAMapStoreImp.h +++ b/src/ripple/app/misc/SHAMapStoreImp.h @@ -175,7 +175,6 @@ private: // callback for visitNodes bool copyNode (std::uint64_t& nodeCount, SHAMapAbstractNode const &node); void run(); - void runImpl(); void dbPaths(); std::shared_ptr makeBackendRotating ( std::string path = std::string()); diff --git a/src/ripple/basics/impl/Sustain.cpp b/src/ripple/basics/impl/Sustain.cpp index 57f49805a..a2bf917f8 100644 --- a/src/ripple/basics/impl/Sustain.cpp +++ b/src/ripple/basics/impl/Sustain.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include // For Sustain Linux variants @@ -103,7 +103,7 @@ std::string DoSustain () auto cc = std::to_string (childCount); if (pChild == 0) { - setCallingThreadName ("main"); + beast::setCurrentThreadName ("rippled: main"); signal (SIGINT, SIG_DFL); signal (SIGHUP, SIG_DFL); signal (SIGUSR1, SIG_DFL); @@ -111,7 +111,7 @@ std::string DoSustain () return "Launching child " + cc; } - setCallingThreadName (("#" + cc).c_str()); + beast::setCurrentThreadName (("rippled: #" + cc).c_str()); sleep (sleepBeforeWaiting); diff --git a/src/ripple/basics/impl/ThreadName.cpp b/src/ripple/basics/impl/ThreadName.cpp deleted file mode 100644 index 000eae77a..000000000 --- a/src/ripple/basics/impl/ThreadName.cpp +++ /dev/null @@ -1,106 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2012, 2013 Ripple Labs Inc. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#include - -#if _MSC_VER - -#include - -namespace ripple { - -// VFALCO TODO use beast::Thread::setCurrentThreadName() or something similar. - -void setCallingThreadName (char const* threadName) -{ - struct ThreadInfo - { - DWORD dwType; - LPCSTR szName; - DWORD dwThreadID; - DWORD dwFlags; - }; - - ThreadInfo info; - - info.dwType = 0x1000; - info.szName = threadName; - info.dwThreadID = GetCurrentThreadId (); - info.dwFlags = 0; - - __try - { - // This is a VisualStudio specific exception - RaiseException (0x406d1388, 0, sizeof (info) / sizeof (ULONG_PTR), (ULONG_PTR*) &info); - } - __except (EXCEPTION_CONTINUE_EXECUTION) - { - } -} - -} // ripple - -#else - -namespace ripple { - -#ifdef PR_SET_NAME -#define HAVE_NAME_THREAD -extern void setCallingThreadName (const char* n) -{ - static std::string pName; - - if (pName.empty ()) - { - std::ifstream cLine ("/proc/self/cmdline", std::ios::in); - cLine >> pName; - - if (pName.empty ()) - pName = "rippled"; - else - { - size_t zero = pName.find_first_of ('\0'); - - if ((zero != std::string::npos) && (zero != 0)) - pName = pName.substr (0, zero); - - size_t slash = pName.find_last_of ('/'); - - if (slash != std::string::npos) - pName = pName.substr (slash + 1); - } - - pName += " "; - } - - // VFALCO TODO Use beast::Thread::setCurrentThreadName here - // - prctl (PR_SET_NAME, (pName + n).c_str (), 0, 0, 0); -} -#endif - -#ifndef HAVE_NAME_THREAD -extern void setCallingThreadName (const char*) -{ -} -#endif - -} // ripple - -#endif diff --git a/src/ripple/basics/impl/UptimeTimer.cpp b/src/ripple/basics/impl/UptimeTimer.cpp index 8c15150fb..cba395700 100644 --- a/src/ripple/basics/impl/UptimeTimer.cpp +++ b/src/ripple/basics/impl/UptimeTimer.cpp @@ -19,7 +19,6 @@ #include #include -#include #include diff --git a/src/ripple/beast/core/CurrentThreadName.cpp b/src/ripple/beast/core/CurrentThreadName.cpp new file mode 100644 index 000000000..6962892d9 --- /dev/null +++ b/src/ripple/beast/core/CurrentThreadName.cpp @@ -0,0 +1,145 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Portions of this file are from JUCE. + Copyright (c) 2013 - Raw Material Software Ltd. + Please visit http://www.juce.com + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include +#include + +namespace beast { +namespace detail { + +static boost::thread_specific_ptr threadName; + +void saveThreadName (std::string name) +{ + threadName.reset (new std::string {std::move(name)}); +} + +} // detail + +boost::optional getCurrentThreadName () +{ + if (auto r = detail::threadName.get()) + return *r; + return boost::none; +} + +} // beast + +//------------------------------------------------------------------------------ + +#if BEAST_WINDOWS + +#include +#include +#include + +namespace beast { +namespace detail { + +void setCurrentThreadNameImpl (std::string const& name) +{ + #if BEAST_DEBUG && BEAST_MSVC + struct + { + DWORD dwType; + LPCSTR szName; + DWORD dwThreadID; + DWORD dwFlags; + } info; + + info.dwType = 0x1000; + info.szName = name.c_str (); + info.dwThreadID = GetCurrentThreadId(); + info.dwFlags = 0; + + __try + { + RaiseException (0x406d1388 /*MS_VC_EXCEPTION*/, 0, sizeof (info) / sizeof (ULONG_PTR), (ULONG_PTR*) &info); + } + __except (EXCEPTION_CONTINUE_EXECUTION) + {} + #else + (void) name; + #endif +} + +} // detail +} // beast + +//------------------------------------------------------------------------------ + +#else + +#include +#include +#include + +#include +#if BEAST_BSD + // ??? +#elif BEAST_MAC || BEAST_IOS +#include +#include +#import +namespace beast{ +#include +} + +#else +#include + +#endif + +namespace beast { +namespace detail { + +void setCurrentThreadNameImpl (std::string const& name) +{ + #if BEAST_IOS || (BEAST_MAC && defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) + BEAST_AUTORELEASEPOOL + { + [[NSThread currentThread] setName: stringToNS (name)]; + } + #elif BEAST_LINUX + #if (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2012 + pthread_setname_np (pthread_self(), name.c_str ()); + #else + prctl (PR_SET_NAME, name.c_str (), 0, 0, 0); + #endif + #endif +} + +} // detail +} // beast + +#endif + +namespace beast { + +void setCurrentThreadName (std::string name) +{ + detail::setCurrentThreadNameImpl (name); + detail::saveThreadName (std::move (name)); +} + +} // beast diff --git a/src/ripple/beast/core/CurrentThreadName.h b/src/ripple/beast/core/CurrentThreadName.h new file mode 100644 index 000000000..d114e075c --- /dev/null +++ b/src/ripple/beast/core/CurrentThreadName.h @@ -0,0 +1,48 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Portions of this file are from JUCE. + Copyright (c) 2013 - Raw Material Software Ltd. + Please visit http://www.juce.com + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef BEAST_CORE_CURRENT_THREAD_NAME_H_INCLUDED +#define BEAST_CORE_CURRENT_THREAD_NAME_H_INCLUDED + +#include +#include + +namespace beast { + +/** Changes the name of the caller thread. + Different OSes may place different length or content limits on this name. +*/ +void setCurrentThreadName (std::string newThreadName); + +/** Returns the name of the caller thread. + + The name returned is the name as set by a call to setCurrentThreadName(). + If the thread name is set by an external force, then that name change + will not be reported. If no name has ever been set, then boost::none + is returned. +*/ +boost::optional getCurrentThreadName (); + +} + +#endif diff --git a/src/ripple/beast/core/Thread.cpp b/src/ripple/beast/core/Thread.cpp deleted file mode 100644 index 65b5dd629..000000000 --- a/src/ripple/beast/core/Thread.cpp +++ /dev/null @@ -1,293 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Portions of this file are from JUCE. - Copyright (c) 2013 - Raw Material Software Ltd. - Please visit http://www.juce.com - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#include -#include -#include - -#include -#include - -namespace beast { - -Thread::Thread (std::string const& threadName_) - : threadName (threadName_), - threadHandle (nullptr), - shouldExit (false) -{ -} - -Thread::~Thread() -{ - /* If your thread class's destructor has been called without first stopping the thread, that - means that this partially destructed object is still performing some work - and that's - probably a Bad Thing! - - To avoid this type of nastiness, always make sure you call stopThread() before or during - your subclass's destructor. - */ - assert (! isThreadRunning()); - - stopThread (); -} - -//============================================================================== -void Thread::threadEntryPoint() -{ - if (!threadName.empty ()) - setCurrentThreadName (threadName); - - if (startSuspensionEvent.wait (10000)) - run(); - - closeThreadHandle(); -} - -// used to wrap the incoming call from the platform-specific code -void beast_threadEntryPoint (void* userData) -{ - static_cast (userData)->threadEntryPoint(); -} - -//============================================================================== -void Thread::startThread() -{ - std::lock_guard sl (startStopLock); - - shouldExit = false; - - if (threadHandle == nullptr) - { - launchThread(); - startSuspensionEvent.signal(); - } -} - -bool Thread::isThreadRunning() const -{ - return threadHandle != nullptr; -} - -//============================================================================== -void Thread::signalThreadShouldExit() -{ - shouldExit = true; -} - -void Thread::waitForThreadToExit () const -{ - while (isThreadRunning()) - std::this_thread::sleep_for (std::chrono::milliseconds (10)); -} - -void Thread::stopThread () -{ - std::lock_guard sl (startStopLock); - - if (isThreadRunning()) - { - signalThreadShouldExit(); - notify(); - waitForThreadToExit (); - } -} - -void Thread::stopThreadAsync () -{ - std::lock_guard sl (startStopLock); - - if (isThreadRunning()) - { - signalThreadShouldExit(); - notify(); - } -} - -//============================================================================== -bool Thread::wait (const int timeOutMilliseconds) const -{ - return defaultEvent.wait (timeOutMilliseconds); -} - -void Thread::notify() const -{ - defaultEvent.signal(); -} - -} - -//------------------------------------------------------------------------------ - -#if BEAST_WINDOWS - -#include -#include -#include - -namespace beast { - -HWND beast_messageWindowHandle = 0; // (this is used by other parts of the codebase) - -void beast_threadEntryPoint (void*); - -static unsigned int __stdcall threadEntryProc (void* userData) -{ - if (beast_messageWindowHandle != 0) - AttachThreadInput (GetWindowThreadProcessId (beast_messageWindowHandle, 0), - GetCurrentThreadId(), TRUE); - - beast_threadEntryPoint (userData); - - _endthreadex (0); - return 0; -} - -void Thread::launchThread() -{ - unsigned int newThreadId; - threadHandle = (void*) _beginthreadex (0, 0, &threadEntryProc, this, 0, &newThreadId); -} - -void Thread::closeThreadHandle() -{ - CloseHandle ((HANDLE) threadHandle); - threadHandle = 0; -} - -void Thread::setCurrentThreadName (std::string const& name) -{ - #if BEAST_DEBUG && BEAST_MSVC - struct - { - DWORD dwType; - LPCSTR szName; - DWORD dwThreadID; - DWORD dwFlags; - } info; - - info.dwType = 0x1000; - info.szName = name.c_str (); - info.dwThreadID = GetCurrentThreadId(); - info.dwFlags = 0; - - __try - { - RaiseException (0x406d1388 /*MS_VC_EXCEPTION*/, 0, sizeof (info) / sizeof (ULONG_PTR), (ULONG_PTR*) &info); - } - __except (EXCEPTION_CONTINUE_EXECUTION) - {} - #else - (void) name; - #endif -} - -} - -//------------------------------------------------------------------------------ - -#else - -#include -#include -#include - -#include -#if BEAST_BSD - // ??? -#elif BEAST_MAC || BEAST_IOS -#include -#include -#import -namespace beast{ -#include -} - -#else -#include - -#endif - -namespace beast { - -void beast_threadEntryPoint (void*); - -extern "C" void* threadEntryProcBeast (void*); -extern "C" void* threadEntryProcBeast (void* userData) -{ - BEAST_AUTORELEASEPOOL - { - #if BEAST_ANDROID - struct AndroidThreadScope - { - AndroidThreadScope() { threadLocalJNIEnvHolder.attach(); } - ~AndroidThreadScope() { threadLocalJNIEnvHolder.detach(); } - }; - - const AndroidThreadScope androidEnv; - #endif - - beast_threadEntryPoint (userData); - } - - return nullptr; -} - -void Thread::launchThread() -{ - threadHandle = 0; - pthread_t handle = 0; - - if (pthread_create (&handle, 0, threadEntryProcBeast, this) == 0) - { - pthread_detach (handle); - threadHandle = (void*) handle; - } -} - -void Thread::closeThreadHandle() -{ - threadHandle = 0; -} - -void Thread::setCurrentThreadName (std::string const& name) -{ - #if BEAST_IOS || (BEAST_MAC && defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) - BEAST_AUTORELEASEPOOL - { - [[NSThread currentThread] setName: stringToNS (name)]; - } - #elif BEAST_LINUX - #if (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2012 - pthread_setname_np (pthread_self(), name.c_str ()); - #else - prctl (PR_SET_NAME, name.c_str (), 0, 0, 0); - #endif - #endif -} - -} - -//------------------------------------------------------------------------------ - -#endif - diff --git a/src/ripple/beast/core/Thread.h b/src/ripple/beast/core/Thread.h deleted file mode 100644 index 7a4b5f5d1..000000000 --- a/src/ripple/beast/core/Thread.h +++ /dev/null @@ -1,187 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Portions of this file are from JUCE. - Copyright (c) 2013 - Raw Material Software Ltd. - Please visit http://www.juce.com - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef BEAST_THREADS_THREAD_H_INCLUDED -#define BEAST_THREADS_THREAD_H_INCLUDED - -#include - -#include -#include - -namespace beast { - -//============================================================================== -/** - Encapsulates a thread. - - Subclasses derive from Thread and implement the run() method, in which they - do their business. The thread can then be started with the startThread() method - and controlled with various other methods. - - @see WaitableEvent, Process, ThreadWithProgressWindow, - MessageManagerLock -*/ -class Thread -{ -public: - //============================================================================== - /** - Creates a thread. - - When first created, the thread is not running. Use the startThread() - method to start it. - */ - explicit Thread (std::string const& threadName); - - Thread (Thread const&) = delete; - Thread& operator= (Thread const&) = delete; - - /** Destructor. - - If the thread has not been stopped first, this will generate a fatal error. - */ - virtual ~Thread(); - - //============================================================================== - /** Must be implemented to perform the thread's actual code. - - Remember that the thread must regularly check the threadShouldExit() - method whilst running, and if this returns true it should return from - the run() method as soon as possible to avoid being forcibly killed. - - @see threadShouldExit, startThread - */ - virtual void run() = 0; - - //============================================================================== - // Thread control functions.. - - /** Starts the thread running. - - This will start the thread's run() method. - (if it's already started, startThread() won't do anything). - - @see stopThread - */ - void startThread(); - - /** Attempts to stop the thread running. - - This method will cause the threadShouldExit() method to return true - and call notify() in case the thread is currently waiting. - */ - void stopThread (); - - /** Stop the thread without blocking. - This calls signalThreadShouldExit followed by notify. - */ - void stopThreadAsync (); - - //============================================================================== - /** Returns true if the thread is currently active */ - bool isThreadRunning() const; - - /** Sets a flag to tell the thread it should stop. - - Calling this means that the threadShouldExit() method will then return true. - The thread should be regularly checking this to see whether it should exit. - - If your thread makes use of wait(), you might want to call notify() after calling - this method, to interrupt any waits that might be in progress, and allow it - to reach a point where it can exit. - - @see threadShouldExit - @see waitForThreadToExit - */ - void signalThreadShouldExit(); - - /** Checks whether the thread has been told to stop running. - - Threads need to check this regularly, and if it returns true, they should - return from their run() method at the first possible opportunity. - - @see signalThreadShouldExit - */ - inline bool threadShouldExit() const { return shouldExit; } - - /** Waits for the thread to stop. - - This will waits until isThreadRunning() is false. - */ - void waitForThreadToExit () const; - - //============================================================================== - /** Makes the thread wait for a notification. - - This puts the thread to sleep until either the timeout period expires, or - another thread calls the notify() method to wake it up. - - A negative time-out value means that the method will wait indefinitely. - - @returns true if the event has been signalled, false if the timeout expires. - */ - bool wait (int timeOutMilliseconds = -1) const; - - /** Wakes up the thread. - - If the thread has called the wait() method, this will wake it up. - - @see wait - */ - void notify() const; - - //============================================================================== - /** Returns the name of the thread. - - This is the name that gets set in the constructor. - */ - std::string const& getThreadName() const { return threadName; } - - /** Changes the name of the caller thread. - Different OSes may place different length or content limits on this name. - */ - static void setCurrentThreadName (std::string const& newThreadName); - - -private: - //============================================================================== - std::string const threadName; - void* volatile threadHandle; - std::recursive_mutex startStopLock; - WaitableEvent startSuspensionEvent, defaultEvent; - bool volatile shouldExit; - - #ifndef DOXYGEN - friend void beast_threadEntryPoint (void*); - #endif - - void launchThread(); - void closeThreadHandle(); - void threadEntryPoint(); -}; - -} - -#endif - diff --git a/src/ripple/beast/core/core.unity.cpp b/src/ripple/beast/core/core.unity.cpp index 9a7c99e24..83dd1dfca 100644 --- a/src/ripple/beast/core/core.unity.cpp +++ b/src/ripple/beast/core/core.unity.cpp @@ -190,9 +190,9 @@ #endif +#include #include #include -#include #include #include diff --git a/src/ripple/core/Job.h b/src/ripple/core/Job.h index e9ea70c70..e70ebc4d0 100644 --- a/src/ripple/core/Job.h +++ b/src/ripple/core/Job.h @@ -133,9 +133,6 @@ public: bool operator<= (const Job& j) const; bool operator>= (const Job& j) const; -private: - void doJobImpl(); - private: CancelCallback m_cancelCallback; JobType mType; diff --git a/src/ripple/core/SociDB.h b/src/ripple/core/SociDB.h index 19d014d1d..a4ba1e838 100644 --- a/src/ripple/core/SociDB.h +++ b/src/ripple/core/SociDB.h @@ -30,7 +30,6 @@ #include #include -#include #define SOCI_USE_BOOST #include #include diff --git a/src/ripple/basics/ThreadName.h b/src/ripple/core/TerminateHandler.h similarity index 80% rename from src/ripple/basics/ThreadName.h rename to src/ripple/core/TerminateHandler.h index e19d7a3b0..b1939ea6b 100644 --- a/src/ripple/basics/ThreadName.h +++ b/src/ripple/core/TerminateHandler.h @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ /* This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2012, 2013 Ripple Labs Inc. + Copyright (c) 2012 - 2017 Ripple Labs Inc. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -17,13 +17,13 @@ */ //============================================================================== -#ifndef RIPPLE_BASICS_THREADNAME_H_INCLUDED -#define RIPPLE_BASICS_THREADNAME_H_INCLUDED +#ifndef RIPPLE_CORE_TERMINATE_HANDLER_H_INCLUDED +#define RIPPLE_CORE_TERMINATE_HANDLER_H_INCLUDED -namespace ripple { +namespace ripple +{ -// VFALCO This should use the beast function -extern void setCallingThreadName (char const*); +void terminateHandler(); } // ripple diff --git a/src/ripple/core/ThreadEntry.h b/src/ripple/core/ThreadEntry.h deleted file mode 100644 index 1722218d4..000000000 --- a/src/ripple/core/ThreadEntry.h +++ /dev/null @@ -1,103 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2016, Ripple Labs Inc. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef RIPPLE_CORE_THREAD_ENTRY_H_INCLUDED -#define RIPPLE_CORE_THREAD_ENTRY_H_INCLUDED - -#include - -namespace ripple -{ - -#ifndef NO_LOG_UNHANDLED_EXCEPTIONS -namespace detail -{ -void setThreadName(std::string name); -} - -void terminateHandler(); -#endif - -/** -Report uncaught exceptions to DebugLog and cerr - -The actual reporting occurs in a terminate handler. This function -stores information about which thread is running in thread local -storage. That way the terminate handler can report not just the -exception, but also the thread the exception was thrown in. - -The idea is to use this routine at the top of a thread, since on -many platforms the stack trace for an uncaught exception on a thread -is almost useless. - -For those platforms where the stack trace from an uncaught exception is -useful (e.g., OS X) this routine is turned into a no-op (because the -preprocessor symbol NO_LOG_UNHANDLED_EXCEPTIONS is defined). - -Usage example - -#include -#include -#include -#include - -class ThreadedHandler -{ -public: - void operator() () - { - threadEntry ( - this, &ThreadedHandler::runImpl, "ThreadedHandler::operator()"); - } - - void runImpl() - { - // do stuff. - throw std::logic_error("logic_error: What was I thinking?"); - } -}; - -int main () -{ - using namespace std::chrono_literals; - - ThreadedHandler handler; - std::thread t {handler}; - std::this_thread::sleep_for (1s); - t.join(); - return 0; -} - -@param t Pointer to object to call. -@param threadTop Pointer to member function of t to call. -@param name Name of function to log. -*/ -template -void threadEntry ( - T* t, R (T::*threadTop) (), std::string name) -{ -#ifndef NO_LOG_UNHANDLED_EXCEPTIONS - detail::setThreadName (std::move(name)); -#endif - ((t)->*(threadTop)) (); -} - -} // namespace ripple - -#endif diff --git a/src/ripple/core/impl/DeadlineTimer.cpp b/src/ripple/core/impl/DeadlineTimer.cpp index 8c385a4bb..5673fc4e9 100644 --- a/src/ripple/core/impl/DeadlineTimer.cpp +++ b/src/ripple/core/impl/DeadlineTimer.cpp @@ -19,8 +19,8 @@ #include #include -#include #include +#include #include #include #include @@ -132,14 +132,9 @@ public: } void run () - { - threadEntry ( - this, &Manager::runImpl, "DeadlineTimer::Manager::run()"); - } - - void runImpl () { using namespace std::chrono; + beast::setCurrentThreadName ("DeadlineTimer"); bool shouldExit = true; do diff --git a/src/ripple/core/impl/Job.cpp b/src/ripple/core/impl/Job.cpp index 3fa158304..717ce2343 100644 --- a/src/ripple/core/impl/Job.cpp +++ b/src/ripple/core/impl/Job.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include namespace ripple { @@ -77,12 +77,15 @@ bool Job::shouldCancel () const void Job::doJob () { - std::stringstream ss; - ss << "Job::doJob(); Job name: " - << mName << "; Job type: " << mType - << "; Job info: " << mJob.target_type ().name (); + beast::setCurrentThreadName ("doJob: " + mName); + m_loadEvent->start (); + m_loadEvent->reName (mName); - threadEntry (this, &Job::doJobImpl, ss.str()); + mJob (*this); + + // Destroy the lambda, otherwise we won't include + // its duration in the time measurement + mJob = nullptr; } void Job::rename (std::string const& newName) @@ -134,16 +137,4 @@ bool Job::operator<= (const Job& j) const return mJobIndex <= j.mJobIndex; } -void Job::doJobImpl () -{ - m_loadEvent->start (); - m_loadEvent->reName (mName); - - mJob (*this); - - // Destroy the lambda, otherwise we won't include - // its duration in the time measurement - mJob = std::function(); -} - } diff --git a/src/ripple/core/impl/JobQueue.cpp b/src/ripple/core/impl/JobQueue.cpp index 3949889d8..66f7dee3c 100644 --- a/src/ripple/core/impl/JobQueue.cpp +++ b/src/ripple/core/impl/JobQueue.cpp @@ -461,7 +461,6 @@ JobQueue::processTask () } type = job.getType(); JobTypeData& data(getJobTypeData(type)); - beast::Thread::setCurrentThreadName (data.name ()); JLOG(m_journal.trace()) << "Doing " << data.name () << " job"; on_dequeue (job.getType (), start_time - job.queue_time ()); job.doJob (); diff --git a/src/ripple/core/impl/SNTPClock.cpp b/src/ripple/core/impl/SNTPClock.cpp index 60ce9067a..3f9b0f844 100644 --- a/src/ripple/core/impl/SNTPClock.cpp +++ b/src/ripple/core/impl/SNTPClock.cpp @@ -20,10 +20,8 @@ #include #include #include -#include #include -#include -#include +#include #include #include #include @@ -203,13 +201,8 @@ public: void doRun () { - setCallingThreadName("SNTPClock"); - - // Get the address of an overloaded asio method - using Pio_service_mem = std::size_t (boost::asio::io_service::*)(); - Pio_service_mem pRun = &boost::asio::io_service::run; - - threadEntry (&io_service_, pRun, "SNTPClientImp::doRun()"); + beast::setCurrentThreadName("rippled: SNTPClock"); + io_service_.run(); } void diff --git a/src/ripple/core/impl/ThreadEntry.cpp b/src/ripple/core/impl/TerminateHandler.cpp similarity index 61% rename from src/ripple/core/impl/ThreadEntry.cpp rename to src/ripple/core/impl/TerminateHandler.cpp index 97efdae9c..337022c2a 100644 --- a/src/ripple/core/impl/ThreadEntry.cpp +++ b/src/ripple/core/impl/TerminateHandler.cpp @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ /* This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2012, 2013 Ripple Labs Inc. + Copyright (c) 2012 - 2017 Ripple Labs Inc. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -18,61 +18,52 @@ //============================================================================== #include -#include +#include #include +#include #include -#include #include #include +#include namespace ripple { -#ifndef NO_LOG_UNHANDLED_EXCEPTIONS -static boost::thread_specific_ptr threadName; - -namespace detail { -void setThreadName(std::string name) -{ - try - { - threadName.reset(new std::string{std::move(name)}); - } - catch(...) - { - } -} -} - void terminateHandler() { if (std::current_exception()) { - std::string const name = threadName.get() ? *threadName.get() : "Unknown"; + auto const thName = + beast::getCurrentThreadName().value_or("Unknown"); try { throw; } catch (const std::exception& e) { - std::cerr << name << ": " << e.what () << '\n'; + auto exName = typeid (e).name(); + std::cerr + << "Terminating thread " << thName << ": unhandled " + << exName << " '" << e.what () << "'\n"; JLOG(debugLog().fatal()) - << name << ": " << e.what () << '\n'; + << "Terminating thread " << thName << ": unhandled " + << exName << " '" << e.what () << "'\n"; } catch (boost::coroutines::detail::forced_unwind const&) { - std::cerr << name << ": forced_unwind\n"; + std::cerr + << "Terminating thread " << thName << ": forced_unwind\n"; JLOG(debugLog().fatal()) - << name << ": forced_unwind\n"; + << "Terminating thread " << thName << ": forced_unwind\n"; } catch (...) { - std::cerr << name << ": unknown exception\n"; - JLOG (debugLog ().fatal ()) - << name << ": unknown exception\n"; + std::cerr + << "Terminating thread " << thName << ": unknown exception\n"; + JLOG (debugLog().fatal()) + << "Terminating thread " << thName << ": unknown exception\n"; } } } -#endif } diff --git a/src/ripple/core/impl/Workers.cpp b/src/ripple/core/impl/Workers.cpp index f9a363477..8b55634af 100644 --- a/src/ripple/core/impl/Workers.cpp +++ b/src/ripple/core/impl/Workers.cpp @@ -18,7 +18,7 @@ //============================================================================== #include -#include +#include #include namespace ripple { @@ -170,18 +170,7 @@ void Workers::Worker::notify () wakeup_.notify_one(); } -static void setInactiveThreadName (std::string const& threadName) -{ - beast::Thread::setCurrentThreadName ("(" + threadName + ")"); -} - void Workers::Worker::run () -{ - setInactiveThreadName (threadName_); - threadEntry (this, &Workers::Worker::runImpl, threadName_); -} - -void Workers::Worker::runImpl () { bool shouldExit = true; do @@ -194,6 +183,9 @@ void Workers::Worker::runImpl () for (;;) { + // Put the name back in case the callback changed it + beast::setCurrentThreadName (threadName_); + // Acquire a task or "internal task." // m_workers.m_semaphore.wait (); @@ -226,9 +218,6 @@ void Workers::Worker::runImpl () ++m_workers.m_runningTaskCount; m_workers.m_callback.processTask (); --m_workers.m_runningTaskCount; - - // Put the name back in case the callback changed it - beast::Thread::setCurrentThreadName (threadName_); } // Any worker that goes into the paused list must @@ -243,7 +232,8 @@ void Workers::Worker::runImpl () if (--m_workers.m_activeCount == 0) m_workers.m_allPaused.signal (); - setInactiveThreadName (threadName_); + // Set inactive thread name. + beast::setCurrentThreadName ("(" + threadName_ + ")"); // [1] We will be here when the paused list is popped // diff --git a/src/ripple/core/impl/Workers.h b/src/ripple/core/impl/Workers.h index 0a475f0cd..6730e4cd5 100644 --- a/src/ripple/core/impl/Workers.h +++ b/src/ripple/core/impl/Workers.h @@ -21,8 +21,8 @@ #define RIPPLE_CORE_WORKERS_H_INCLUDED #include -#include #include +#include #include #include #include @@ -131,7 +131,6 @@ private: private: void run (); - void runImpl (); private: Workers& m_workers; diff --git a/src/ripple/nodestore/backend/RocksDBFactory.cpp b/src/ripple/nodestore/backend/RocksDBFactory.cpp index 65a3dd534..0ec7c6261 100644 --- a/src/ripple/nodestore/backend/RocksDBFactory.cpp +++ b/src/ripple/nodestore/backend/RocksDBFactory.cpp @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include @@ -70,7 +70,7 @@ public: std::size_t const id (++n); std::stringstream ss; ss << "rocksdb #" << id; - beast::Thread::setCurrentThreadName (ss.str()); + beast::setCurrentThreadName (ss.str()); (*f)(a); } diff --git a/src/ripple/nodestore/backend/RocksDBQuickFactory.cpp b/src/ripple/nodestore/backend/RocksDBQuickFactory.cpp index abd9459c5..16bd1d465 100644 --- a/src/ripple/nodestore/backend/RocksDBQuickFactory.cpp +++ b/src/ripple/nodestore/backend/RocksDBQuickFactory.cpp @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include @@ -69,7 +69,7 @@ public: std::size_t const id (++n); std::stringstream ss; ss << "rocksdb #" << id; - beast::Thread::setCurrentThreadName (ss.str()); + beast::setCurrentThreadName (ss.str()); (*f)(a); } diff --git a/src/ripple/nodestore/impl/DatabaseImp.h b/src/ripple/nodestore/impl/DatabaseImp.h index 52dd9ff60..0fc637540 100644 --- a/src/ripple/nodestore/impl/DatabaseImp.h +++ b/src/ripple/nodestore/impl/DatabaseImp.h @@ -26,11 +26,10 @@ #include #include #include -#include #include #include #include -#include +#include #include #include #include @@ -335,17 +334,10 @@ public: //------------------------------------------------------------------------------ - // Uncaught exception handling for async read threads + // Entry point for async read threads void threadEntry () { - ::ripple::threadEntry ( - this, &DatabaseImp::threadEntryImpl, "DatabaseImp::threadEntry()"); - } - - // Entry point for async read threads - void threadEntryImpl () - { - beast::Thread::setCurrentThreadName ("prefetch"); + beast::setCurrentThreadName ("prefetch"); while (1) { uint256 hash; diff --git a/src/ripple/resource/impl/ResourceManager.cpp b/src/ripple/resource/impl/ResourceManager.cpp index 823945c0b..61febfa7e 100644 --- a/src/ripple/resource/impl/ResourceManager.cpp +++ b/src/ripple/resource/impl/ResourceManager.cpp @@ -22,8 +22,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -114,13 +113,7 @@ public: private: void run () { - threadEntry ( - this, &ManagerImp::runImpl, "Resource::Manager::run()"); - } - - void runImpl () - { - beast::Thread::setCurrentThreadName ("Resource::Manager"); + beast::setCurrentThreadName ("Resource::Manager"); for(;;) { logic_.periodicActivity(); diff --git a/src/ripple/server/impl/ServerImpl.h b/src/ripple/server/impl/ServerImpl.h index 69bf38253..081351fb2 100644 --- a/src/ripple/server/impl/ServerImpl.h +++ b/src/ripple/server/impl/ServerImpl.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -99,7 +98,7 @@ private: std::vector>> list_; int high_ = 0; std::array hist_; - + io_list ios_; public: diff --git a/src/ripple/unity/basics.cpp b/src/ripple/unity/basics.cpp index 8903eb5b4..e24eab78d 100644 --- a/src/ripple/unity/basics.cpp +++ b/src/ripple/unity/basics.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include #include diff --git a/src/ripple/unity/core.cpp b/src/ripple/unity/core.cpp index 8c995bfe1..b7e5f8846 100644 --- a/src/ripple/unity/core.cpp +++ b/src/ripple/unity/core.cpp @@ -28,7 +28,7 @@ #include #include #include +#include #include -#include #include diff --git a/src/test/beast/beast_CurrentThreadName_test.cpp b/src/test/beast/beast_CurrentThreadName_test.cpp new file mode 100644 index 000000000..7b5055354 --- /dev/null +++ b/src/test/beast/beast_CurrentThreadName_test.cpp @@ -0,0 +1,88 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2017 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include +#include +#include +#include +#include + +namespace ripple { +namespace test { + +class CurrentThreadName_test : public beast::unit_test::suite +{ +private: + static void exerciseName ( + std::string myName, std::atomic* stop, std::atomic* state) + { + // Verify that upon creation a thread has no name. + auto const initialThreadName = beast::getCurrentThreadName(); + + // Set the new name. + beast::setCurrentThreadName (myName); + + // Indicate to caller that the name is set. + *state = 1; + + // If there is an initial thread name then we failed. + if (initialThreadName) + return; + + // Wait until all threads have their names. + while (! *stop); + + // Make sure the thread name that we set before is still there + // (not overwritten by, for instance, another thread). + if (beast::getCurrentThreadName() == myName) + *state = 2; + } + +public: + void + run() override + { + // Make two different threads with two different names. Make sure + // that the expected thread names are still there when the thread + // exits. + std::atomic stop {false}; + + std::atomic stateA {0}; + std::thread tA (exerciseName, "tA", &stop, &stateA); + + std::atomic stateB {0}; + std::thread tB (exerciseName, "tB", &stop, &stateB); + + // Wait until both threads have set their names. + while (stateA == 0 || stateB == 0); + + stop = true; + tA.join(); + tB.join(); + + // Both threads should still have the expected name when they exit. + BEAST_EXPECT (stateA == 2); + BEAST_EXPECT (stateB == 2); + } +}; + +BEAST_DEFINE_TESTSUITE(CurrentThreadName,core,beast); + +} // test +} // ripple diff --git a/src/test/core/TerminateHandler_test.cpp b/src/test/core/TerminateHandler_test.cpp new file mode 100644 index 000000000..003e55e04 --- /dev/null +++ b/src/test/core/TerminateHandler_test.cpp @@ -0,0 +1,153 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2016 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace ripple { +namespace test { + +class TerminateHandler_test : public beast::unit_test::suite +{ +private: + // Allow cerr to be redirected. Destructor restores old cerr streambuf. + class CerrRedirect + { + public: + CerrRedirect (std::stringstream& sStream) + : old_ (std::cerr.rdbuf (sStream.rdbuf())) + { } + + ~CerrRedirect() + { + std::cerr.rdbuf (old_); + } + + private: + std::streambuf* const old_; + }; + + // Set a new current thread name. Destructor restores the old thread name. + class ThreadNameGuard + { + public: + ThreadNameGuard (std::string const& newName) + : old_ (beast::getCurrentThreadName ()) + { + beast::setCurrentThreadName (newName); + } + + ~ThreadNameGuard() + { + std::string oldName; + if (old_) + oldName = std::move (*old_); + + beast::setCurrentThreadName (oldName); + } + + private: + boost::optional old_; + }; + +public: + void + run() override + { + // Set the current thread name, but restore the old name on exit. + std::string const threadName {"terminateHandler_test"}; + ThreadNameGuard nameGuard {threadName}; + { + // Test terminateHandler() with a std::exception. + + // The terminateHandler() output goes to std::cerr. Capture that. + std::stringstream cerrCapture; + CerrRedirect cerrRedirect {cerrCapture}; + + try + { + throw std::range_error ("Out of range"); + } + catch (...) + { + terminateHandler(); + } + { + std::string result = cerrCapture.str(); + BEAST_EXPECT (result.find (threadName) != std::string::npos); + BEAST_EXPECT ( + result.find ("Out of range") != std::string::npos); + } + } + + { + // Verify terminateHnadler() handles forced_unwind correctly. + std::stringstream cerrCapture; + CerrRedirect cerrRedirect {cerrCapture}; + + try + { + throw boost::coroutines::detail::forced_unwind(); + } + catch (...) + { + terminateHandler(); + } + { + std::string result = cerrCapture.str(); + BEAST_EXPECT (result.find (threadName) != std::string::npos); + BEAST_EXPECT ( + result.find ("forced_unwind") != std::string::npos); + } + } + + { + // Verify terminatHandler()'s handling of non-standard exceptions. + std::stringstream cerrCapture; + CerrRedirect cerrRedirect {cerrCapture}; + + try + { + throw 7; + } + catch (...) + { + terminateHandler(); + } + { + std::string result = cerrCapture.str(); + BEAST_EXPECT (result.find (threadName) != std::string::npos); + BEAST_EXPECT ( + result.find ("unknown exception") != std::string::npos); + } + } + } +}; + +BEAST_DEFINE_TESTSUITE(TerminateHandler,core,ripple); + +} // test +} // ripple diff --git a/src/test/overlay/short_read_test.cpp b/src/test/overlay/short_read_test.cpp index 92a6cbdcc..7d2f99550 100644 --- a/src/test/overlay/short_read_test.cpp +++ b/src/test/overlay/short_read_test.cpp @@ -19,13 +19,13 @@ #include #include -#include +#include #include +#include #include #include #include #include -#include #include #include #include @@ -552,7 +552,7 @@ public: : work_(boost::in_place(std::ref(io_service_))) , thread_(std::thread([this]() { - beast::Thread::setCurrentThreadName("io_service"); + beast::setCurrentThreadName("io_service"); this->io_service_.run(); })) , context_(make_SSLContext("")) diff --git a/src/test/unity/beast_test_unity.cpp b/src/test/unity/beast_test_unity.cpp index cb5c8cd1c..d799f3de9 100644 --- a/src/test/unity/beast_test_unity.cpp +++ b/src/test/unity/beast_test_unity.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/src/test/unity/core_test_unity.cpp b/src/test/unity/core_test_unity.cpp index 468e61450..a143d58e5 100644 --- a/src/test/unity/core_test_unity.cpp +++ b/src/test/unity/core_test_unity.cpp @@ -23,4 +23,5 @@ #include #include #include +#include #include \ No newline at end of file