diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters index 21784efacd..fd67ab9a46 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters @@ -1347,9 +1347,6 @@ [1] Ripple\ripple_app\_misc - - [1] Ripple\ripple_app\_misc - [1] Ripple\ripple_app\_misc @@ -1533,6 +1530,9 @@ [1] Ripple\ripple_app\_transactions + + [1] Ripple\ripple_app\_main + diff --git a/TODO.txt b/TODO.txt index 3ac57e7186..b4dde7a2ea 100644 --- a/TODO.txt +++ b/TODO.txt @@ -31,6 +31,10 @@ WEBSOCKET TODO RIPPLE TODO -------------------------------------------------------------------------------- +- Remove dependence on JobQueue, LoadFeeTrack, and NetworkOPs from LoadManager + by providing an observer (beast::ListenerList or Listeners). This way + LoadManager does not need stopThread() function. + - Move everything in src/cpp/ripple into ripple_app and sort them into subdirectories within the module as per the project filters. * Make sure there are no pending commits from David diff --git a/src/cpp/ripple/ripple_Application.cpp b/src/cpp/ripple/ripple_Application.cpp index 2d8fdef005..f6e0997653 100644 --- a/src/cpp/ripple/ripple_Application.cpp +++ b/src/cpp/ripple/ripple_Application.cpp @@ -266,7 +266,20 @@ private: }; Application::Application () +// +// VFALCO NOTE Change this to control whether or not the Application +// object is destroyed on exit +// +#if 1 + // Application object will be deleted on exit. If the code doesn't exit + // cleanly this could cause hangs or crashes on exit. + // : SharedSingleton (SingletonLifetime::persistAfterCreation) +#else + // This will make it so that the Application object is not deleted on exit. + // + : SharedSingleton (SingletonLifetime::neverDestroyed) +#endif , mIOService ((theConfig.NODE_SIZE >= 2) ? 2 : 1) , mIOWork (mIOService) , mAuxWork (mAuxService) @@ -308,6 +321,21 @@ Application::Application () HashMaps::getInstance ().initializeNonce (); } +Application::~Application () +{ + // VFALCO TODO Wrap these in ScopedPointer + delete mTxnDB; + delete mLedgerDB; + delete mWalletDB; + delete mHashNodeDB; + delete mNetNodeDB; + delete mPathFindDB; + delete mHashNodeLDB; + + if (mEphemeralLDB != nullptr) + delete mEphemeralLDB; +} + // VFALCO TODO Tidy these up into some class with accessors. // extern const char* RpcDBInit[], *TxnDBInit[], *LedgerDBInit[], *WalletDBInit[], *HashNodeDBInit[], @@ -666,10 +694,18 @@ void Application::run () if (mWSPrivateDoor) mWSPrivateDoor->stop (); - getApp().getLoadManager().stopThread(); + // VFALCO TODO Try to not have to do this early, by using observers to + // eliminate LoadManager's dependency inversions. + // + // This deletes the object and therefore, stops the thread. + m_loadManager = nullptr; + mSweepTimer.cancel(); WriteLog (lsINFO, Application) << "Done."; + + // 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)); } @@ -705,21 +741,6 @@ void Application::sweep () mSweepTimer.async_wait (BIND_TYPE (&Application::sweep, this)); } -Application::~Application () -{ - // VFALCO TODO Wrap these in ScopedPointer - delete mTxnDB; - delete mLedgerDB; - delete mWalletDB; - delete mHashNodeDB; - delete mNetNodeDB; - delete mPathFindDB; - delete mHashNodeLDB; - - if (mEphemeralLDB != nullptr) - delete mEphemeralLDB; -} - void Application::startNewLedger () { // New stuff. diff --git a/src/cpp/ripple/ripple_ILoadManager.h b/src/cpp/ripple/ripple_ILoadManager.h index 002ad7814e..894f47c2f6 100644 --- a/src/cpp/ripple/ripple_ILoadManager.h +++ b/src/cpp/ripple/ripple_ILoadManager.h @@ -208,23 +208,27 @@ class ILoadManager public: /** Create a new manager. + The manager thread begins running immediately. + @note The thresholds for warnings and punishments are in the ctor-initializer */ static ILoadManager* New (); + /** Destroy the manager. + + The destructor returns only after the thread has stopped. + */ virtual ~ILoadManager () { } /** Start the associated thread. This is here to prevent the deadlock detector from activating during a lengthy program initialization. - - @note In stand-alone mode, this might not get called. */ // VFALCO TODO Simplify the two stage initialization to one stage (construction). + // NOTE In stand-alone mode the load manager thread isn't started virtual void startThread () = 0; - virtual void stopThread () = 0; /** Turn on deadlock detection. diff --git a/src/cpp/ripple/ripple_LoadManager.cpp b/src/cpp/ripple/ripple_LoadManager.cpp index 76163ad0d3..e9aefaf020 100644 --- a/src/cpp/ripple/ripple_LoadManager.cpp +++ b/src/cpp/ripple/ripple_LoadManager.cpp @@ -67,7 +67,6 @@ public: , mDebitWarn (-500) , mDebitLimit (-1000) , mArmed (false) - , mRunning (false) , mDeadLock (0) , mCosts (LT_MAX) { @@ -110,6 +109,8 @@ public: addCost (Cost (LT_RequestData, -5, flagDisk | flagNet)); addCost (Cost (LT_CheapQuery, -1, flagCpu)); + + UptimeTimer::getInstance ().beginManualUpdates (); } private: @@ -117,29 +118,12 @@ private: { UptimeTimer::getInstance ().endManualUpdates (); - if (mRunning) - { - m_thread.interrupt (); - m_thread.join (); - } + m_thread.interrupt (); } void startThread () { - UptimeTimer::getInstance ().beginManualUpdates (); - m_thread.start (this); - mRunning = true; - } - - void stopThread() - { - if (mRunning) - { - m_thread.interrupt (); - m_thread.join (); - mRunning = false; - } } void canonicalize (LoadSource& source, int now) const @@ -417,7 +401,7 @@ private: int mDebitWarn; // when a source drops below this, we warn int mDebitLimit; // when a source drops below this, we cut it off (should be negative) - bool mArmed, mRunning; + bool mArmed; int mDeadLock; // Detect server deadlocks