diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index d3d3dd129..6ad4b5d87 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -26,7 +26,7 @@ Main::Main(QWidget *parent) : setWindowFlags(Qt::Window); ui->setupUi(this); g_logPost = [=](std::string const& s, char const* c) { simpleDebugOut(s, c); ui->log->addItem(QString::fromStdString(s)); }; - m_client = new Client("AlethZero"); + m_client.reset(new Client("AlethZero")); readSettings(); refresh(); @@ -63,7 +63,6 @@ Main::~Main() { g_logPost = simpleDebugOut; writeSettings(); - delete ui; } void Main::on_about_triggered() diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 02d3506c4..e1cb44e65 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -54,9 +54,9 @@ private: eth::u256 total() const; eth::u256 value() const; - Ui::Main *ui; + std::unique_ptr ui; - eth::Client* m_client; + std::unique_ptr m_client; QByteArray m_peers; QMutex m_guiLock; diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 5f811d1bc..c30de604f 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -33,7 +33,8 @@ Client::Client(std::string const& _clientVersion, Address _us, std::string const m_bc(_dbPath), m_stateDB(State::openDB(_dbPath)), m_preMine(_us, m_stateDB), - m_postMine(_us, m_stateDB) + m_postMine(_us, m_stateDB), + m_workState(Active) { Defaults::setDBPath(_dbPath); @@ -45,26 +46,28 @@ Client::Client(std::string const& _clientVersion, Address _us, std::string const static const char* c_threadName = "eth"; - m_work = new thread([&](){ + m_work.reset(new thread([&](){ setThreadName(c_threadName); - - while (m_workState != Deleting) work(); m_workState = Deleted; - }); + while (m_workState.load(std::memory_order_acquire) != Deleting) + work(); + m_workState.store(Deleted, std::memory_order_release); + })); } Client::~Client() { - if (m_workState == Active) - m_workState = Deleting; - while (m_workState != Deleted) + if (m_workState.load(std::memory_order_acquire) == Active) + m_workState.store(Deleting, std::memory_order_release); + while (m_workState.load(std::memory_order_acquire) != Deleted) this_thread::sleep_for(chrono::milliseconds(10)); + m_work->join(); } void Client::startNetwork(unsigned short _listenPort, std::string const& _seedHost, unsigned short _port, NodeMode _mode, unsigned _peers, string const& _publicIP, bool _upnp) { - if (m_net) + if (m_net.get()) return; - m_net = new PeerServer(m_clientVersion, m_bc, 0, _listenPort, _mode, _publicIP, _upnp); + m_net.reset(new PeerServer(m_clientVersion, m_bc, 0, _listenPort, _mode, _publicIP, _upnp)); m_net->setIdealPeerCount(_peers); if (_seedHost.size()) connect(_seedHost, _port); @@ -72,15 +75,14 @@ void Client::startNetwork(unsigned short _listenPort, std::string const& _seedHo void Client::connect(std::string const& _seedHost, unsigned short _port) { - if (!m_net) + if (!m_net.get()) return; m_net->connect(_seedHost, _port); } void Client::stopNetwork() { - delete m_net; - m_net = nullptr; + m_net.reset(nullptr); } void Client::startMining() diff --git a/libethereum/Client.h b/libethereum/Client.h index 5c9b64b0f..ab377d73d 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -23,6 +23,7 @@ #include #include +#include #include "Common.h" #include "BlockChain.h" #include "TransactionQueue.h" @@ -52,6 +53,13 @@ private: Client* m_client; }; +enum ClientWorkState +{ + Active = 0, + Deleting, + Deleted +}; + class Client { public: @@ -112,7 +120,7 @@ public: /// Stop the network subsystem. void stopNetwork(); /// Get access to the peer server object. This will be null if the network isn't online. - PeerServer* peerServer() const { return m_net; } + PeerServer* peerServer() const { return m_net.get(); } // Mining stuff: @@ -134,14 +142,14 @@ private: BlockChain m_bc; ///< Maintains block database. TransactionQueue m_tq; ///< Maintains list of incoming transactions not yet on the block chain. Overlay m_stateDB; ///< Acts as the central point for the state database, so multiple States can share it. - State m_preMine; ///< The present state of the client. - State m_postMine; ///< The state of the client which we're mining (i.e. it'll have all the rewards added). - PeerServer* m_net = nullptr; ///< Should run in background and send us events when blocks found and allow us to send blocks as required. + State m_preMine; ///< The present state of the client. + State m_postMine; ///< The state of the client which we're mining (i.e. it'll have all the rewards added). + std::unique_ptr m_net; ///< Should run in background and send us events when blocks found and allow us to send blocks as required. - std::thread* m_work; ///< The work thread. + std::unique_ptr m_work;///< The work thread. std::recursive_mutex m_lock; - enum { Active = 0, Deleting, Deleted } m_workState = Active; + std::atomic m_workState; bool m_doMine = false; ///< Are we supposed to be mining? MineProgress m_mineProgress; mutable bool m_restartMining = false; diff --git a/libethereum/UPnP.cpp b/libethereum/UPnP.cpp index 9f6ed4e95..6008bc7de 100644 --- a/libethereum/UPnP.cpp +++ b/libethereum/UPnP.cpp @@ -33,8 +33,8 @@ using namespace eth; UPnP::UPnP() { - m_urls = new UPNPUrls; - m_data = new IGDdatas; + m_urls.reset(new UPNPUrls); + m_data.reset(new IGDdatas); m_ok = false; @@ -43,8 +43,8 @@ UPnP::UPnP() char* descXML; int descXMLsize = 0; int upnperror = 0; - memset(m_urls, 0, sizeof(struct UPNPUrls)); - memset(m_data, 0, sizeof(struct IGDdatas)); + memset(m_urls.get(), 0, sizeof(struct UPNPUrls)); + memset(m_data.get(), 0, sizeof(struct IGDdatas)); devlist = upnpDiscover(2000, NULL/*multicast interface*/, NULL/*minissdpd socket path*/, 0/*sameport*/, 0/*ipv6*/, &upnperror); if (devlist) { @@ -66,12 +66,12 @@ UPnP::UPnP() #endif if (descXML) { - parserootdesc (descXML, descXMLsize, m_data); + parserootdesc (descXML, descXMLsize, m_data.get()); free (descXML); descXML = 0; #if MINIUPNPC_API_VERSION >= 9 - GetUPNPUrls (m_urls, m_data, dev->descURL, 0); + GetUPNPUrls (m_urls.get(), m_data.get(), dev->descURL, 0); #else - GetUPNPUrls (m_urls, m_data, dev->descURL); + GetUPNPUrls (m_urls.get(), m_data.get(), dev->descURL); #endif m_ok = true; } diff --git a/libethereum/UPnP.h b/libethereum/UPnP.h index bb51c96d1..8713e1d2b 100644 --- a/libethereum/UPnP.h +++ b/libethereum/UPnP.h @@ -45,8 +45,8 @@ public: std::set m_reg; bool m_ok; - struct UPNPUrls* m_urls; - struct IGDdatas* m_data; + std::unique_ptr m_urls; + std::unique_ptr m_data; }; }