From a57e4263d72d4ea24425ebaf34ea8e6cd82d0615 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Mon, 16 Jun 2014 10:05:11 -0700 Subject: [PATCH] Fix MSVC workaround in basic_seconds_clock --- src/beast/beast/chrono/basic_seconds_clock.h | 79 ++++++++----------- .../beast/module/sqdb/source/session.cpp | 8 -- src/ripple/module/app/main/Application.cpp | 2 +- src/ripple/module/app/main/LoadManager.cpp | 2 + src/ripple/module/app/misc/Validations.cpp | 4 +- src/ripple/unity/app.cpp | 6 +- 6 files changed, 43 insertions(+), 58 deletions(-) diff --git a/src/beast/beast/chrono/basic_seconds_clock.h b/src/beast/beast/chrono/basic_seconds_clock.h index bc8154f44..227e3de43 100644 --- a/src/beast/beast/chrono/basic_seconds_clock.h +++ b/src/beast/beast/chrono/basic_seconds_clock.h @@ -20,41 +20,14 @@ #ifndef BEAST_CHRONO_BASIC_SECONDS_CLOCK_H_INCLUDED #define BEAST_CHRONO_BASIC_SECONDS_CLOCK_H_INCLUDED +#include + #include #include -#include - -#ifndef BEAST_BASIC_SECONDS_CLOCK_BOOST_WORKAROUND -# ifdef _MSC_VER -// Visual Studio 2012, 2013 have a bug in std::thread that -// causes a hang on exit, in the library function atexit() -# if BEAST_USE_BOOST_FEATURES -# define BEAST_BASIC_SECONDS_CLOCK_BOOST_WORKAROUND 1 -# else -# define BEAST_BASIC_SECONDS_CLOCK_BOOST_WORKAROUND 0 -# endif -# else -# define BEAST_BASIC_SECONDS_CLOCK_BOOST_WORKAROUND 0 -# endif -#endif - -#if BEAST_BASIC_SECONDS_CLOCK_BOOST_WORKAROUND -#include -# if BOOST_VERSION >= 105500 -#include -#include -#include -#include -# else -# error "Boost version 1.55.0 or later is required" -# endif -#else #include #include #include -#endif - -#include +#include namespace beast { @@ -72,15 +45,6 @@ public: class seconds_clock_thread { public: -#if BEAST_BASIC_SECONDS_CLOCK_BOOST_WORKAROUND - typedef boost::mutex mutex; - typedef boost::condition_variable cond_var; - typedef boost::lock_guard lock_guard; - typedef boost::unique_lock unique_lock; - typedef boost::chrono::steady_clock clock_type; - typedef boost::chrono::seconds seconds; - typedef boost::thread thread; -#else typedef std::mutex mutex; typedef std::condition_variable cond_var; typedef std::lock_guard lock_guard; @@ -88,7 +52,6 @@ public: typedef std::chrono::steady_clock clock_type; typedef std::chrono::seconds seconds; typedef std::thread thread; -#endif typedef std::vector workers; bool m_stop; @@ -106,12 +69,7 @@ public: ~seconds_clock_thread () { - { - lock_guard lock (m_mutex); - m_stop = true; - } - m_cond.notify_all(); - m_thread.join (); + stop(); } void add (seconds_clock_worker& w) @@ -127,7 +85,20 @@ public: m_workers.begin (), m_workers.end(), &w)); } - void run () + void stop() + { + if (m_thread.joinable()) + { + { + lock_guard lock (m_mutex); + m_stop = true; + } + m_cond.notify_all(); + m_thread.join(); + } + } + + void run() { unique_lock lock (m_mutex);; @@ -157,6 +128,20 @@ public: //------------------------------------------------------------------------------ +/** Called before main exits to terminate the utility thread. + This is a workaround for Visual Studio 2013: + http://connect.microsoft.com/VisualStudio/feedback/details/786016/creating-a-global-c-object-that-used-thread-join-in-its-destructor-causes-a-lockup + http://stackoverflow.com/questions/10915233/stdthreadjoin-hangs-if-called-after-main-exits-when-using-vs2012-rc +*/ +inline +void +basic_seconds_clock_main_hook() +{ +#ifdef _MSC_VER + detail::seconds_clock_thread::instance().stop(); +#endif +} + /** A clock whose minimum resolution is one second. The purpose of this class is to optimize the performance of the now() member function call. It uses a dedicated thread that wakes up at least diff --git a/src/beast/beast/module/sqdb/source/session.cpp b/src/beast/beast/module/sqdb/source/session.cpp index c4f8f93f0..1e14d16c3 100644 --- a/src/beast/beast/module/sqdb/source/session.cpp +++ b/src/beast/beast/module/sqdb/source/session.cpp @@ -114,14 +114,6 @@ Error session::clone() return open(m_fileName, m_connectString); } -/* -static int infiniteBusyHandler (void* data, int tries) -{ - boost::this_thread::sleep (boost::posix_time::seconds(1)); - return 1; // try again -} -*/ - Error session::open(String fileName, std::string options) { Error err; diff --git a/src/ripple/module/app/main/Application.cpp b/src/ripple/module/app/main/Application.cpp index 647ddce7b..4f3e503dd 100644 --- a/src/ripple/module/app/main/Application.cpp +++ b/src/ripple/module/app/main/Application.cpp @@ -1021,7 +1021,7 @@ public: // VFALCO NOTE This is a sign that something is wrong somewhere, it // shouldn't be necessary to sleep until some flag is set. while (mShutdown) - boost::this_thread::sleep (boost::posix_time::milliseconds (100)); + std::this_thread::sleep_for (std::chrono::milliseconds (100)); } } diff --git a/src/ripple/module/app/main/LoadManager.cpp b/src/ripple/module/app/main/LoadManager.cpp index 77e93c480..edd58861a 100644 --- a/src/ripple/module/app/main/LoadManager.cpp +++ b/src/ripple/module/app/main/LoadManager.cpp @@ -17,6 +17,8 @@ */ //============================================================================== +#include + namespace ripple { class LoadManagerImp diff --git a/src/ripple/module/app/misc/Validations.cpp b/src/ripple/module/app/misc/Validations.cpp index 53cd09fb9..7dc5dc489 100644 --- a/src/ripple/module/app/misc/Validations.cpp +++ b/src/ripple/module/app/misc/Validations.cpp @@ -17,6 +17,8 @@ */ //============================================================================== +#include + namespace ripple { class ValidationsImp; @@ -406,7 +408,7 @@ private: while (mWriting) { ScopedUnlockType sul (mLock); - boost::this_thread::sleep (boost::posix_time::milliseconds (100)); + std::this_thread::sleep_for (std::chrono::milliseconds (100)); } WriteLog (lsDEBUG, Validations) << "Validations flushed"; diff --git a/src/ripple/unity/app.cpp b/src/ripple/unity/app.cpp index 482a4762b..7630a2bc5 100644 --- a/src/ripple/unity/app.cpp +++ b/src/ripple/unity/app.cpp @@ -102,5 +102,9 @@ int main (int argc, char** argv) beast::SharedSingleton ::get (); - return ripple::run (argc, argv); + auto const result (ripple::run (argc, argv)); + + beast::basic_seconds_clock_main_hook(); + + return result; }