Replace some boost::thread with beast::thread

This commit is contained in:
Vinnie Falco
2013-07-29 01:39:09 -07:00
parent ae4071d1e0
commit e9a7f6f81a
9 changed files with 300 additions and 269 deletions

View File

@@ -40,6 +40,10 @@ David Feature:
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
- Consolidate databases
- Figure out why we need WAL sqlite mode if we no longer use sqlite for the node store
- Add "skipped" field to beginTestCase() to disable a test but still record - Add "skipped" field to beginTestCase() to disable a test but still record
that it was skipped in the output. Like for mdb import. that it was skipped in the output. Like for mdb import.

View File

@@ -33,8 +33,11 @@ SqliteStatement::~SqliteStatement ()
sqlite3_finalize (statement); sqlite3_finalize (statement);
} }
//------------------------------------------------------------------------------
SqliteDatabase::SqliteDatabase (const char* host) SqliteDatabase::SqliteDatabase (const char* host)
: Database (host) : Database (host)
, m_thread ("sqlitedb")
, mWalQ (NULL) , mWalQ (NULL)
, walRunning (false) , walRunning (false)
{ {
@@ -290,9 +293,13 @@ void SqliteDatabase::doHook (const char* db, int pages)
} }
if (mWalQ) if (mWalQ)
{
mWalQ->addJob (jtWAL, std::string ("WAL:") + mHost, BIND_TYPE (&SqliteDatabase::runWal, this)); mWalQ->addJob (jtWAL, std::string ("WAL:") + mHost, BIND_TYPE (&SqliteDatabase::runWal, this));
}
else else
boost::thread (BIND_TYPE (&SqliteDatabase::runWal, this)).detach (); {
m_thread.call (&SqliteDatabase::runWal, this);
}
} }
void SqliteDatabase::runWal () void SqliteDatabase::runWal ()

View File

@@ -57,6 +57,8 @@ public:
int getKBUsedAll (); int getKBUsedAll ();
private: private:
ThreadWithCallQueue m_thread;
sqlite3* mConnection; sqlite3* mConnection;
// VFALCO TODO Why do we need an "aux" connection? Should just use a second SqliteDatabase object. // VFALCO TODO Why do we need an "aux" connection? Should just use a second SqliteDatabase object.
sqlite3* mAuxConnection; sqlite3* mAuxConnection;

View File

@@ -44,6 +44,13 @@ public:
// the dtor of m_threads will block until each thread exits. // the dtor of m_threads will block until each thread exits.
} }
// TEMPORARY HACK for compatibility with old code
void runExtraThreads ()
{
for (int i = 0; i < m_threads.size (); ++i)
m_threads [i]->start ();
}
// Run on the callers thread. // Run on the callers thread.
// This will block until stop is issued. // This will block until stop is issued.
void run () void run ()
@@ -92,7 +99,7 @@ public:
: Thread (name) : Thread (name)
, m_service (service) , m_service (service)
{ {
startThread (); //startThread ();
} }
~ServiceThread () ~ServiceThread ()
@@ -102,6 +109,11 @@ public:
stopThread (-1); // wait forever stopThread (-1); // wait forever
} }
void start ()
{
startThread ();
}
void run () void run ()
{ {
m_service.run (); m_service.run ();
@@ -149,7 +161,6 @@ public:
, mTempNodeCache ("NodeCache", 16384, 90) , mTempNodeCache ("NodeCache", 16384, 90)
, mSLECache ("LedgerEntryCache", 4096, 120) , mSLECache ("LedgerEntryCache", 4096, 120)
, mSNTPClient (m_auxService) , mSNTPClient (m_auxService)
, mJobQueue (m_mainService)
// VFALCO New stuff // VFALCO New stuff
, m_nodeStore (NodeStore::New ( , m_nodeStore (NodeStore::New (
getConfig ().nodeDatabase, getConfig ().nodeDatabase,
@@ -360,119 +371,49 @@ public:
{ {
return mShutdown; return mShutdown;
} }
void setup ();
void run ();
void stop ();
void sweep ();
void doSweep (Job&);
private: //--------------------------------------------------------------------------
void updateTables ();
void startNewLedger ();
bool loadOldLedger (const std::string&, bool);
private: static DatabaseCon* openDatabaseCon (const char* fileName,
IoServiceThread m_mainService; const char* dbInit[],
IoServiceThread m_auxService; int dbCount)
{
return new DatabaseCon (fileName, dbInit, dbCount);
}
//boost::asio::io_service mIOService; void initSqliteDb (int index)
//boost::asio::io_service mAuxService; {
//boost::asio::io_service::work mIOWork; switch (index)
{
case 0: mRpcDB = openDatabaseCon ("rpc.db", RpcDBInit, RpcDBCount); break;
case 1: mTxnDB = openDatabaseCon ("transaction.db", TxnDBInit, TxnDBCount); break;
case 2: mLedgerDB = openDatabaseCon ("ledger.db", LedgerDBInit, LedgerDBCount); break;
case 3: mWalletDB = openDatabaseCon ("wallet.db", WalletDBInit, WalletDBCount); break;
};
}
MasterLockType mMasterLock; // VFALCO TODO Is it really necessary to init the dbs in parallel?
void initSqliteDbs ()
{
int const count = 4;
LocalCredentials m_localCredentials; ThreadGroup threadGroup (count);
LedgerMaster mLedgerMaster; ParallelFor (threadGroup).loop (count, &ApplicationImp::initSqliteDb, this);
InboundLedgers m_inboundLedgers; }
TransactionMaster mMasterTransaction;
ScopedPointer <NetworkOPs> mNetOps;
RPCServerHandler m_rpcServerHandler;
NodeCache mTempNodeCache;
SLECache mSLECache;
SNTPClient mSNTPClient;
JobQueue mJobQueue;
TXQueue mTxnQueue;
OrderBookDB mOrderBookDB;
// VFALCO Clean stuff
ScopedPointer <NodeStore> m_nodeStore;
ScopedPointer <Validators> m_validators;
ScopedPointer <IFeatures> mFeatures;
ScopedPointer <IFeeVote> mFeeVote;
ScopedPointer <ILoadFeeTrack> mFeeTrack;
ScopedPointer <IHashRouter> mHashRouter;
ScopedPointer <IValidations> mValidations;
ScopedPointer <UniqueNodeList> mUNL;
ScopedPointer <IProofOfWorkFactory> mProofOfWorkFactory;
ScopedPointer <IPeers> mPeers;
ScopedPointer <ILoadManager> m_loadManager;
// VFALCO End Clean stuff
DatabaseCon* mRpcDB;
DatabaseCon* mTxnDB;
DatabaseCon* mLedgerDB;
DatabaseCon* mWalletDB;
ScopedPointer <PeerDoor> mPeerDoor;
ScopedPointer <RPCDoor> mRPCDoor;
ScopedPointer <WSDoor> mWSPublicDoor;
ScopedPointer <WSDoor> mWSPrivateDoor;
boost::asio::deadline_timer mSweepTimer;
bool volatile mShutdown;
};
// VFALCO TODO Why do we even have this function?
// It could just be handled in the destructor.
//
void ApplicationImp::stop ()
{
WriteLog (lsINFO, Application) << "Received shutdown request";
StopSustain ();
mShutdown = true;
m_mainService.stop ();
m_nodeStore = nullptr;
mValidations->flush ();
m_auxService.stop ();
mJobQueue.shutdown ();
//WriteLog (lsINFO, Application) << "Stopped: " << mIOService.stopped
mShutdown = false;
}
static void InitDB (DatabaseCon** dbCon, const char* fileName, const char* dbInit[], int dbCount)
{
*dbCon = new DatabaseCon (fileName, dbInit, dbCount);
}
#ifdef SIGINT #ifdef SIGINT
void sigIntHandler (int) static void sigIntHandler (int)
{ {
doShutdown = true; doShutdown = true;
} }
#endif #endif
// VFALCO TODO Figure this out it looks like the wrong tool // VFALCO TODO Break this function up into many small initialization segments.
static void runAux (boost::asio::io_service& svc) // Or better yet refactor these initializations into RAII classes
{ // which are members of the Application object.
setCallingThreadName ("aux"); //
svc.run (); void setup ()
} {
static void runIO (boost::asio::io_service& io)
{
setCallingThreadName ("io");
io.run ();
}
// VFALCO TODO Break this function up into many small initialization segments.
// Or better yet refactor these initializations into RAII classes
// which are members of the Application object.
//
void ApplicationImp::setup ()
{
// VFALCO NOTE: 0 means use heuristics to determine the thread count. // VFALCO NOTE: 0 means use heuristics to determine the thread count.
mJobQueue.setThreadCount (0, getConfig ().RUN_STANDALONE); mJobQueue.setThreadCount (0, getConfig ().RUN_STANDALONE);
@@ -481,19 +422,19 @@ void ApplicationImp::setup ()
m_loadManager->startThread (); m_loadManager->startThread ();
#if ! BEAST_WIN32 #if ! BEAST_WIN32
#ifdef SIGINT #ifdef SIGINT
if (!getConfig ().RUN_STANDALONE) if (!getConfig ().RUN_STANDALONE)
{ {
struct sigaction sa; struct sigaction sa;
memset (&sa, 0, sizeof (sa)); memset (&sa, 0, sizeof (sa));
sa.sa_handler = sigIntHandler; sa.sa_handler = &ApplicationImp::sigIntHandler;
sigaction (SIGINT, &sa, NULL); sigaction (SIGINT, &sa, NULL);
} }
#endif #endif
#endif #endif
assert (mTxnDB == NULL); assert (mTxnDB == NULL);
@@ -509,17 +450,7 @@ void ApplicationImp::setup ()
if (!getConfig ().RUN_STANDALONE) if (!getConfig ().RUN_STANDALONE)
mSNTPClient.init (getConfig ().SNTP_SERVERS); mSNTPClient.init (getConfig ().SNTP_SERVERS);
// initSqliteDbs ();
// Construct databases.
//
boost::thread t1 (BIND_TYPE (&InitDB, &mRpcDB, "rpc.db", RpcDBInit, RpcDBCount));
boost::thread t2 (BIND_TYPE (&InitDB, &mTxnDB, "transaction.db", TxnDBInit, TxnDBCount));
boost::thread t3 (BIND_TYPE (&InitDB, &mLedgerDB, "ledger.db", LedgerDBInit, LedgerDBCount));
boost::thread t4 (BIND_TYPE (&InitDB, &mWalletDB, "wallet.db", WalletDBInit, WalletDBCount));
t1.join ();
t2.join ();
t3.join ();
t4.join ();
leveldb::Options options; leveldb::Options options;
options.create_if_missing = true; options.create_if_missing = true;
@@ -642,7 +573,7 @@ void ApplicationImp::setup ()
{ {
try try
{ {
mWSPrivateDoor = WSDoor::createWSDoor (getConfig ().WEBSOCKET_IP, getConfig ().WEBSOCKET_PORT, false); mWSPrivateDoor = new WSDoor (getConfig ().WEBSOCKET_IP, getConfig ().WEBSOCKET_PORT, false);
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
@@ -664,7 +595,7 @@ void ApplicationImp::setup ()
{ {
try try
{ {
mWSPublicDoor = WSDoor::createWSDoor (getConfig ().WEBSOCKET_PUBLIC_IP, getConfig ().WEBSOCKET_PUBLIC_PORT, true); mWSPublicDoor = new WSDoor (getConfig ().WEBSOCKET_PUBLIC_IP, getConfig ().WEBSOCKET_PUBLIC_PORT, true);
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
@@ -697,10 +628,98 @@ void ApplicationImp::setup ()
// //
mNetOps->setStateTimer (); mNetOps->setStateTimer ();
} }
}
void run ();
void stop ();
void sweep ();
void doSweep (Job&);
private:
void updateTables ();
void startNewLedger ();
bool loadOldLedger (const std::string&, bool);
private:
IoServiceThread m_mainService;
IoServiceThread m_auxService;
//boost::asio::io_service mIOService;
//boost::asio::io_service mAuxService;
//boost::asio::io_service::work mIOWork;
MasterLockType mMasterLock;
LocalCredentials m_localCredentials;
LedgerMaster mLedgerMaster;
InboundLedgers m_inboundLedgers;
TransactionMaster mMasterTransaction;
ScopedPointer <NetworkOPs> mNetOps;
RPCServerHandler m_rpcServerHandler;
NodeCache mTempNodeCache;
SLECache mSLECache;
SNTPClient mSNTPClient;
JobQueue mJobQueue;
TXQueue mTxnQueue;
OrderBookDB mOrderBookDB;
// VFALCO Clean stuff
ScopedPointer <NodeStore> m_nodeStore;
ScopedPointer <Validators> m_validators;
ScopedPointer <IFeatures> mFeatures;
ScopedPointer <IFeeVote> mFeeVote;
ScopedPointer <ILoadFeeTrack> mFeeTrack;
ScopedPointer <IHashRouter> mHashRouter;
ScopedPointer <IValidations> mValidations;
ScopedPointer <UniqueNodeList> mUNL;
ScopedPointer <IProofOfWorkFactory> mProofOfWorkFactory;
ScopedPointer <IPeers> mPeers;
ScopedPointer <ILoadManager> m_loadManager;
// VFALCO End Clean stuff
DatabaseCon* mRpcDB;
DatabaseCon* mTxnDB;
DatabaseCon* mLedgerDB;
DatabaseCon* mWalletDB;
ScopedPointer <PeerDoor> mPeerDoor;
ScopedPointer <RPCDoor> mRPCDoor;
ScopedPointer <WSDoor> mWSPublicDoor;
ScopedPointer <WSDoor> mWSPrivateDoor;
boost::asio::deadline_timer mSweepTimer;
bool volatile mShutdown;
};
// VFALCO TODO Why do we even have this function?
// It could just be handled in the destructor.
//
void ApplicationImp::stop ()
{
WriteLog (lsINFO, Application) << "Received shutdown request";
StopSustain ();
mShutdown = true;
m_mainService.stop ();
m_nodeStore = nullptr;
mValidations->flush ();
m_auxService.stop ();
mJobQueue.shutdown ();
//WriteLog (lsINFO, Application) << "Stopped: " << mIOService.stopped
mShutdown = false;
} }
void ApplicationImp::run () void ApplicationImp::run ()
{ {
// VFALCO TODO The unit tests crash if we try to
// run these threads in the IoService constructor
// so this hack makes them start later.
//
m_mainService.runExtraThreads ();
if (!getConfig ().RUN_STANDALONE) if (!getConfig ().RUN_STANDALONE)
{ {
// VFALCO NOTE This seems unnecessary. If we properly refactor the load // VFALCO NOTE This seems unnecessary. If we properly refactor the load

View File

@@ -28,6 +28,7 @@ WSDoor::WSDoor (std::string const& strIp, int iPort, bool bPublic)
, mIp (strIp) , mIp (strIp)
, mPort (iPort) , mPort (iPort)
{ {
startThread ();
} }
WSDoor::~WSDoor () WSDoor::~WSDoor ()
@@ -39,8 +40,8 @@ WSDoor::~WSDoor ()
m_endpoint->stop (); m_endpoint->stop ();
} }
m_thread.signalThreadShouldExit (); signalThreadShouldExit ();
m_thread.waitForThreadToExit (); waitForThreadToExit ();
} }
void WSDoor::run () void WSDoor::run ()
@@ -110,6 +111,6 @@ void WSDoor::stop ()
m_endpoint->stop (); m_endpoint->stop ();
} }
m_thread.signalThreadShouldExit (); signalThreadShouldExit ();
m_thread.waitForThreadToExit (); waitForThreadToExit ();
} }

View File

@@ -20,7 +20,7 @@ private:
void run (); void run ();
private: private:
ScopedPointer <websocketpp::server_autotls*> m_endpoint; ScopedPointer <websocketpp::server_autotls> m_endpoint;
CriticalSection m_endpointLock; CriticalSection m_endpointLock;
bool mPublic; bool mPublic;
std::string mIp; std::string mIp;

View File

@@ -60,8 +60,6 @@
#include <boost/unordered_set.hpp> #include <boost/unordered_set.hpp>
#include <boost/weak_ptr.hpp> #include <boost/weak_ptr.hpp>
//#include "../ripple_sqlite/ripple_sqlite.h" // for SqliteDatabase.cpp
#include "../ripple_core/ripple_core.h" #include "../ripple_core/ripple_core.h"
#include "beast/modules/beast_db/beast_db.h" #include "beast/modules/beast_db/beast_db.h"

View File

@@ -195,7 +195,7 @@ void JobQueue::setThreadCount (int c, bool const standaloneMode)
} }
else if (c == 0) else if (c == 0)
{ {
c = boost::thread::hardware_concurrency (); c = SystemStats::getNumCpus ();
// VFALCO NOTE According to boost, hardware_concurrency cannot return // VFALCO NOTE According to boost, hardware_concurrency cannot return
// negative numbers/ // negative numbers/

BIN
rippled.1

Binary file not shown.