diff --git a/libdevcore/TransientDirectory.cpp b/libdevcore/TransientDirectory.cpp index c632514ef..8b7aa4467 100644 --- a/libdevcore/TransientDirectory.cpp +++ b/libdevcore/TransientDirectory.cpp @@ -46,7 +46,7 @@ TransientDirectory::~TransientDirectory() { boost::system::error_code ec; boost::filesystem::remove_all(m_path, ec); - if (0 == ec) + if (!ec) return; // In some cases, antivirus runnig on Windows will scan all the newly created directories. @@ -57,6 +57,6 @@ TransientDirectory::~TransientDirectory() ec.clear(); boost::filesystem::remove_all(m_path, ec); - if (ec != 0) + if (!ec) cwarn << "Failed to delete directory '" << m_path << "': " << ec.message(); } diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index a50c1c706..4b8738301 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -120,7 +120,7 @@ void EthereumHost::maintainTransactions() for (auto const& i: ts) { bool unsent = !m_transactionsSent.count(i.first); - for (auto const& p: randomSelection(0, [&](EthereumPeer* p) { return p->m_requireTransactions || (unsent && !p->m_knownTransactions.count(i.first)); }).second) + for (auto const& p: get<1>(randomSelection(0, [&](EthereumPeer* p) { return p->m_requireTransactions || (unsent && !p->m_knownTransactions.count(i.first)); }))) peerTransactions[p].push_back(i.first); } for (auto const& t: ts) @@ -165,24 +165,32 @@ void EthereumHost::forEachPeerPtr(std::functioncap(c_oldProtocolVersion)); } -pair>, vector>> EthereumHost::randomSelection(unsigned _percent, std::function const& _allow) +tuple>, vector>, vector>> EthereumHost::randomSelection(unsigned _percent, std::function const& _allow) { - pair>, vector>> ret; - forEachPeerPtr([&](shared_ptr _p) + vector> chosen; + vector> allowed; + vector> sessions; + + auto const& ps = peerSessions(); + allowed.reserve(ps.size()); + for (auto const& j: ps) { - if (_p && _allow(_p.get())) - ret.second.push_back(_p); - }); + auto pp = j.first->cap(); + if (_allow(pp.get())) + { + allowed.push_back(move(pp)); + sessions.push_back(move(j.first)); + } + } - size_t size = (ret.second.size() * _percent + 99) / 100; - ret.second.reserve(size); - for (unsigned i = size; i-- && ret.second.size();) + chosen.reserve((ps.size() * _percent + 99) / 100); + for (unsigned i = (ps.size() * _percent + 99) / 100; i-- && allowed.size();) { - unsigned n = rand() % ret.second.size(); - ret.first.push_back(std::move(ret.second[n])); - ret.second.erase(ret.second.begin() + n); + unsigned n = rand() % allowed.size(); + chosen.push_back(std::move(allowed[n])); + allowed.erase(allowed.begin() + n); } - return ret; + return make_tuple(move(chosen), move(allowed), move(sessions)); } void EthereumHost::maintainBlocks(h256 const& _currentHash) @@ -200,7 +208,7 @@ void EthereumHost::maintainBlocks(h256 const& _currentHash) h256s blocks = get<0>(m_chain.treeRoute(m_latestBlockSent, _currentHash, false, false, true)); auto s = randomSelection(25, [&](EthereumPeer* p){ DEV_GUARDED(p->x_knownBlocks) return !p->m_knownBlocks.count(_currentHash); return false; }); - for (shared_ptr const& p: s.first) + for (shared_ptr const& p: get<0>(s)) for (auto const& b: blocks) { RLPStream ts; @@ -210,7 +218,7 @@ void EthereumHost::maintainBlocks(h256 const& _currentHash) p->sealAndSend(ts); p->m_knownBlocks.clear(); } - for (shared_ptr const& p: s.second) + for (shared_ptr const& p: get<1>(s)) { RLPStream ts; p->prep(ts, NewBlockHashesPacket, blocks.size()); diff --git a/libethereum/EthereumHost.h b/libethereum/EthereumHost.h index 497255034..f62a93bd9 100644 --- a/libethereum/EthereumHost.h +++ b/libethereum/EthereumHost.h @@ -90,8 +90,10 @@ public: BlockChain const& chain() { return m_chain; } static unsigned const c_oldProtocolVersion; + private: - std::pair>, std::vector>> randomSelection(unsigned _percent = 25, std::function const& _allow = [](EthereumPeer const*){ return true; }); + std::tuple>, std::vector>, std::vector>> randomSelection(unsigned _percent = 25, std::function const& _allow = [](EthereumPeer const*){ return true; }); + void forEachPeerPtr(std::function)> const& _f) const; void forEachPeer(std::function const& _f) const; diff --git a/libp2p/HostCapability.cpp b/libp2p/HostCapability.cpp index 9502d6b86..102465324 100644 --- a/libp2p/HostCapability.cpp +++ b/libp2p/HostCapability.cpp @@ -27,15 +27,15 @@ using namespace std; using namespace dev; using namespace dev::p2p; -std::vector,std::shared_ptr>> HostCapabilityFace::peerSessions() const +std::vector, std::shared_ptr>> HostCapabilityFace::peerSessions() const { return peerSessions(version()); } -std::vector,std::shared_ptr>> HostCapabilityFace::peerSessions(u256 const& _version) const +std::vector, std::shared_ptr>> HostCapabilityFace::peerSessions(u256 const& _version) const { RecursiveGuard l(m_host->x_sessions); - std::vector,std::shared_ptr>> ret; + std::vector, std::shared_ptr>> ret; for (auto const& i: m_host->m_sessions) if (std::shared_ptr s = i.second.lock()) if (s->m_capabilities.count(std::make_pair(name(), _version))) diff --git a/libp2p/HostCapability.h b/libp2p/HostCapability.h index 19b149085..48403bfdf 100644 --- a/libp2p/HostCapability.h +++ b/libp2p/HostCapability.h @@ -45,8 +45,8 @@ public: Host* host() const { return m_host; } - std::vector,std::shared_ptr>> peerSessions() const; - std::vector,std::shared_ptr>> peerSessions(u256 const& _version) const; + std::vector, std::shared_ptr>> peerSessions() const; + std::vector, std::shared_ptr>> peerSessions(u256 const& _version) const; protected: virtual std::string name() const = 0; diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 8f395158b..2a16007ca 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -319,10 +319,14 @@ void Session::send(bytes&& _msg) void Session::write() { - const bytes& bytes = m_writeQueue[0]; - m_io->writeSingleFramePacket(&bytes, m_writeQueue[0]); + bytes const* out; + DEV_GUARDED(x_writeQueue) + { + m_io->writeSingleFramePacket(&m_writeQueue[0], m_writeQueue[0]); + out = &m_writeQueue[0]; + } auto self(shared_from_this()); - ba::async_write(m_socket, ba::buffer(bytes), [this, self](boost::system::error_code ec, std::size_t /*length*/) + ba::async_write(m_socket, ba::buffer(*out), [this, self](boost::system::error_code ec, std::size_t /*length*/) { ThreadContext tc(info().id.abridged()); ThreadContext tc2(info().clientVersion); diff --git a/libp2p/UDP.h b/libp2p/UDP.h index ce2a570b2..474cb5442 100644 --- a/libp2p/UDP.h +++ b/libp2p/UDP.h @@ -99,7 +99,7 @@ struct UDPSocketFace */ struct UDPSocketEvents { - virtual void onDisconnected(UDPSocketFace*) {}; + virtual void onDisconnected(UDPSocketFace*) {} virtual void onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packetData) = 0; };