diff --git a/Subtrees/beast/modules/beast_core/threads/beast_Thread.h b/Subtrees/beast/modules/beast_core/threads/beast_Thread.h index e0d28b64ae..0dda1f9c48 100644 --- a/Subtrees/beast/modules/beast_core/threads/beast_Thread.h +++ b/Subtrees/beast/modules/beast_core/threads/beast_Thread.h @@ -150,7 +150,7 @@ public: is less than zero, it will wait forever. @returns true if the thread exits, or false if the timeout expires first. */ - bool waitForThreadToExit (int timeOutMilliseconds) const; + bool waitForThreadToExit (int timeOutMilliseconds = -1) const; //============================================================================== /** Changes the thread's priority. diff --git a/modules/ripple_app/network/WSDoor.cpp b/modules/ripple_app/network/WSDoor.cpp index ba6a3423e6..968e1cdbaa 100644 --- a/modules/ripple_app/network/WSDoor.cpp +++ b/modules/ripple_app/network/WSDoor.cpp @@ -21,9 +21,35 @@ SETUP_LOG (WSDoor) // // VFALCO NOTE NetworkOPs isn't used here... // -void WSDoor::startListening () + +WSDoor::WSDoor (std::string const& strIp, int iPort, bool bPublic) + : Thread ("websocket") + , mPublic (bPublic) + , mIp (strIp) + , mPort (iPort) { - setCallingThreadName ("websocket"); +} + +WSDoor::~WSDoor () +{ + { + CriticalSection::ScopedLockType lock (m_endpointLock); + + if (m_endpoint != nullptr) + m_endpoint->stop (); + } + + m_thread.signalThreadShouldExit (); + m_thread.waitForThreadToExit (); +} + +void WSDoor::run () +{ + WriteLog (lsINFO, WSDoor) << boost::str (boost::format ("Websocket: %s: Listening: %s %d ") + % (mPublic ? "Public" : "Private") + % mIp + % mPort); + // Generate a single SSL context for use by all connections. boost::shared_ptr mCtx; mCtx = boost::make_shared (boost::asio::ssl::context::sslv23); @@ -35,11 +61,13 @@ void WSDoor::startListening () SSL_CTX_set_tmp_dh_callback (mCtx->native_handle (), handleTmpDh); - // Construct a single handler for all requests. websocketpp::server_autotls::handler::ptr handler (new WSServerHandler (mCtx, mPublic)); - // Construct a websocket server. - mSEndpoint = new websocketpp::server_autotls (handler); + { + CriticalSection::ScopedLockType lock (m_endpointLock); + + m_endpoint = new websocketpp::server_autotls (handler); + } // mEndpoint->alog().unset_level(websocketpp::log::alevel::ALL); // mEndpoint->elog().unset_level(websocketpp::log::elevel::ALL); @@ -47,7 +75,7 @@ void WSDoor::startListening () // Call the main-event-loop of the websocket server. try { - mSEndpoint->listen ( + m_endpoint->listen ( boost::asio::ip::tcp::endpoint ( boost::asio::ip::address ().from_string (mIp), mPort)); } @@ -60,7 +88,7 @@ void WSDoor::startListening () // https://github.com/zaphoyd/websocketpp/issues/98 try { - mSEndpoint->get_io_service ().run (); + m_endpoint->get_io_service ().run (); break; } catch (websocketpp::exception& e) @@ -70,32 +98,18 @@ void WSDoor::startListening () } } - delete mSEndpoint; -} - -WSDoor* WSDoor::createWSDoor (const std::string& strIp, const int iPort, bool bPublic) -{ - WSDoor* wdpResult = new WSDoor (strIp, iPort, bPublic); - - WriteLog (lsINFO, WSDoor) << - boost::str (boost::format ("Websocket: %s: Listening: %s %d ") - % (bPublic ? "Public" : "Private") - % strIp - % iPort); - - wdpResult->mThread = new boost::thread (BIND_TYPE (&WSDoor::startListening, wdpResult)); - - return wdpResult; + delete m_endpoint; } void WSDoor::stop () { - if (mThread) { - if (mSEndpoint) - mSEndpoint->stop (); + CriticalSection::ScopedLockType lock (m_endpointLock); - - mThread->join (); + if (m_endpoint != nullptr) + m_endpoint->stop (); } + + m_thread.signalThreadShouldExit (); + m_thread.waitForThreadToExit (); } diff --git a/modules/ripple_app/network/WSDoor.h b/modules/ripple_app/network/WSDoor.h index 068cd61ce3..567a9cea22 100644 --- a/modules/ripple_app/network/WSDoor.h +++ b/modules/ripple_app/network/WSDoor.h @@ -7,28 +7,24 @@ #ifndef RIPPLE_WSDOOR_RIPPLEHEADER #define RIPPLE_WSDOOR_RIPPLEHEADER -class WSDoor : LeakChecked +class WSDoor : protected Thread, LeakChecked { -private: - websocketpp::server_autotls* mSEndpoint; +public: + WSDoor (std::string const& strIp, int iPort, bool bPublic); - boost::thread* mThread; + ~WSDoor (); + + void stop (); + +private: + void run (); + +private: + ScopedPointer m_endpoint; + CriticalSection m_endpointLock; bool mPublic; std::string mIp; int mPort; - - void startListening (); - -public: - - WSDoor (const std::string& strIp, int iPort, bool bPublic) : mSEndpoint (0), mThread (0), mPublic (bPublic), mIp (strIp), mPort (iPort) - { - ; - } - - void stop (); - - static WSDoor* createWSDoor (const std::string& strIp, const int iPort, bool bPublic); }; #endif