Cleanly destroy Application on exit

This commit is contained in:
Vinnie Falco
2013-06-30 04:21:07 -07:00
parent 68179cfce3
commit 0deaeb1000
42 changed files with 949 additions and 926 deletions

View File

@@ -7,18 +7,18 @@
// VFALCO TODO Clean this global up
volatile bool doShutdown = false;
// VFALCO TODO Wrap this up in something neater.
//IApplication* theApp = nullptr;
ScopedPointer <IApplication> theApp;
class Application;
SETUP_LOG (Application)
// VFALCO TODO Move the function definitions into the class declaration
class Application : public IApplication
class Application
: public IApplication
, LeakChecked <Application>
{
public:
class Holder;
Application ();
~Application ();
@@ -249,10 +249,10 @@ private:
leveldb::DB* mHashNodeLDB;
leveldb::DB* mEphemeralLDB;
PeerDoor* mPeerDoor;
RPCDoor* mRPCDoor;
WSDoor* mWSPublicDoor;
WSDoor* mWSPrivateDoor;
ScopedPointer <PeerDoor> mPeerDoor;
ScopedPointer <RPCDoor> mRPCDoor;
ScopedPointer <WSDoor> mWSPublicDoor;
ScopedPointer <WSDoor> mWSPrivateDoor;
boost::asio::deadline_timer mSweepTimer;
@@ -460,14 +460,14 @@ void Application::setup ()
if (!mHashedObjectStore.isLevelDB ())
{
theApp->getHashNodeDB ()->getDB ()->executeSQL (boost::str (boost::format ("PRAGMA cache_size=-%d;") %
getApp().getHashNodeDB ()->getDB ()->executeSQL (boost::str (boost::format ("PRAGMA cache_size=-%d;") %
(theConfig.getSize (siHashNodeDBCache) * 1024)));
theApp->getHashNodeDB ()->getDB ()->setupCheckpointing (&mJobQueue);
getApp().getHashNodeDB ()->getDB ()->setupCheckpointing (&mJobQueue);
}
theApp->getLedgerDB ()->getDB ()->executeSQL (boost::str (boost::format ("PRAGMA cache_size=-%d;") %
getApp().getLedgerDB ()->getDB ()->executeSQL (boost::str (boost::format ("PRAGMA cache_size=-%d;") %
(theConfig.getSize (siLgrDBCache) * 1024)));
theApp->getTxnDB ()->getDB ()->executeSQL (boost::str (boost::format ("PRAGMA cache_size=-%d;") %
getApp().getTxnDB ()->getDB ()->executeSQL (boost::str (boost::format ("PRAGMA cache_size=-%d;") %
(theConfig.getSize (siTxnDBCache) * 1024)));
mTxnDB->getDB ()->setupCheckpointing (&mJobQueue);
@@ -490,7 +490,7 @@ void Application::setup ()
if (!loadOldLedger (theConfig.START_LEDGER))
{
theApp->stop ();
getApp().stop ();
exit (-1);
}
}
@@ -505,7 +505,7 @@ void Application::setup ()
else
startNewLedger ();
mOrderBookDB.setup (theApp->getLedgerMaster ().getCurrentLedger ());
mOrderBookDB.setup (getApp().getLedgerMaster ().getCurrentLedger ());
//
// Begin validation and ip maintenance.
@@ -647,7 +647,7 @@ void Application::run ()
// VFALCO NOTE This seems unnecessary. If we properly refactor the load
// manager then the deadlock detector can just always be "armed"
//
theApp->getLoadManager ().activateDeadlockDetector ();
getApp().getLoadManager ().activateDeadlockDetector ();
}
mIOService.run (); // This blocks
@@ -670,7 +670,7 @@ void Application::sweep ()
if (space.available < (512 * 1024 * 1024))
{
WriteLog (lsFATAL, Application) << "Remaining free disk space is less than 512MB";
theApp->stop ();
getApp().stop ();
}
// VFALCO NOTE Does the order of calls matter?
@@ -809,37 +809,39 @@ bool serverOkay (std::string& reason)
if (!theConfig.ELB_SUPPORT)
return true;
/*
if (!theApp)
{
reason = "Server has not started";
return false;
}
*/
if (theApp->isShutdown ())
if (getApp().isShutdown ())
{
reason = "Server is shutting down";
return false;
}
if (theApp->getOPs ().isNeedNetworkLedger ())
if (getApp().getOPs ().isNeedNetworkLedger ())
{
reason = "Not synchronized with network yet";
return false;
}
if (theApp->getOPs ().getOperatingMode () < NetworkOPs::omSYNCING)
if (getApp().getOPs ().getOperatingMode () < NetworkOPs::omSYNCING)
{
reason = "Not synchronized with network";
return false;
}
if (theApp->getFeeTrack ().isLoaded ())
if (getApp().getFeeTrack ().isLoaded ())
{
reason = "Too much load";
return false;
}
if (theApp->getOPs ().isFeatureBlocked ())
if (getApp().getOPs ().isFeatureBlocked ())
{
reason = "Server version too old";
return false;
@@ -882,12 +884,12 @@ static bool schemaHas (DatabaseCon* dbc, const std::string& dbName, int line, co
static void addTxnSeqField ()
{
if (schemaHas (theApp->getTxnDB (), "AccountTransactions", 0, "TxnSeq"))
if (schemaHas (getApp().getTxnDB (), "AccountTransactions", 0, "TxnSeq"))
return;
Log (lsWARNING) << "Transaction sequence field is missing";
Database* db = theApp->getTxnDB ()->getDB ();
Database* db = getApp().getTxnDB ()->getDB ();
std::vector< std::pair<uint256, int> > txIDs;
txIDs.reserve (300000);
@@ -957,18 +959,18 @@ static void addTxnSeqField ()
void Application::updateTables (bool ldbImport)
{
// perform any needed table updates
assert (schemaHas (theApp->getTxnDB (), "AccountTransactions", 0, "TransID"));
assert (!schemaHas (theApp->getTxnDB (), "AccountTransactions", 0, "foobar"));
assert (schemaHas (getApp().getTxnDB (), "AccountTransactions", 0, "TransID"));
assert (!schemaHas (getApp().getTxnDB (), "AccountTransactions", 0, "foobar"));
addTxnSeqField ();
if (schemaHas (theApp->getTxnDB (), "AccountTransactions", 0, "PRIMARY"))
if (schemaHas (getApp().getTxnDB (), "AccountTransactions", 0, "PRIMARY"))
{
Log (lsFATAL) << "AccountTransactions database should not have a primary key";
StopSustain ();
exit (1);
}
if (theApp->getHashedObjectStore ().isLevelDB ())
if (getApp().getHashedObjectStore ().isLevelDB ())
{
boost::filesystem::path hashPath = theConfig.DATA_DIR / "hashnode.db";
@@ -977,7 +979,7 @@ void Application::updateTables (bool ldbImport)
if (theConfig.LDB_IMPORT)
{
Log (lsWARNING) << "Importing SQLite -> LevelDB";
theApp->getHashedObjectStore ().import (hashPath.string ());
getApp().getHashedObjectStore ().import (hashPath.string ());
Log (lsWARNING) << "Remove or remname the hashnode.db file";
}
else
@@ -991,8 +993,39 @@ void Application::updateTables (bool ldbImport)
}
}
IApplication* IApplication::New ()
{
return new Application;
}
//------------------------------------------------------------------------------
// Since its an global with static storage duration
// it has to be wrapped in a SharedSingleton.
//
class Application::Holder : public SharedSingleton <Application::Holder>
{
public:
Holder ()
: SharedSingleton <Holder> (SingletonLifetime::persistAfterCreation)
, m_application (new Application)
{
}
~Holder ()
{
}
static Holder* createInstance ()
{
return new Holder;
}
IApplication& getApp ()
{
return *m_application;
}
private:
ScopedPointer <IApplication> m_application;
};
IApplication& getApp ()
{
return Application::Holder::getInstance ()->getApp ();
}