diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 5d31b980..66abe779 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -23,27 +23,23 @@ namespace i2p { namespace transport { - template - EphemeralKeysSupplier::EphemeralKeysSupplier (int size): + X25519KeysPairSupplier::X25519KeysPairSupplier (int size): m_QueueSize (size), m_IsRunning (false) { } - template - EphemeralKeysSupplier::~EphemeralKeysSupplier () + X25519KeysPairSupplier::~X25519KeysPairSupplier () { Stop (); } - template - void EphemeralKeysSupplier::Start () + void X25519KeysPairSupplier::Start () { m_IsRunning = true; - m_Thread.reset (new std::thread (std::bind (&EphemeralKeysSupplier::Run, this))); + m_Thread.reset (new std::thread (std::bind (&X25519KeysPairSupplier::Run, this))); } - template - void EphemeralKeysSupplier::Stop () + void X25519KeysPairSupplier::Stop () { { std::unique_lock l(m_AcquiredMutex); @@ -58,29 +54,36 @@ namespace transport if (!m_Queue.empty ()) { // clean up queue - std::queue > tmp; + std::list > tmp; std::swap (m_Queue, tmp); } m_KeysPool.CleanUpMt (); } - template - void EphemeralKeysSupplier::Run () + void X25519KeysPairSupplier::Run () { i2p::util::SetThreadName("Ephemerals"); + int num = 0; while (m_IsRunning) { - int num, total = 0; - while ((num = m_QueueSize - (int)m_Queue.size ()) > 0 && total < m_QueueSize) + if (num <= 0) { - CreateEphemeralKeys (num); + std::unique_lock l(m_AcquiredMutex); + num = m_QueueSize - (int)m_Queue.size (); + } + int total = 0; + while (num > 0 && total < m_QueueSize) + { + auto queueSize = CreateEphemeralKeys (num); total += num; + num = m_QueueSize - (int)queueSize; } if (total > m_QueueSize) { LogPrint (eLogWarning, "Transports: ", total, " ephemeral keys generated at the time"); std::this_thread::sleep_for (std::chrono::seconds(1)); // take a break + num = 0; } else { @@ -88,34 +91,41 @@ namespace transport std::unique_lock l(m_AcquiredMutex); if (!m_IsRunning) break; m_Acquired.wait (l); // wait for element gets acquired + num = m_QueueSize - (int)m_Queue.size (); } } } - template - void EphemeralKeysSupplier::CreateEphemeralKeys (int num) + size_t X25519KeysPairSupplier::CreateEphemeralKeys (int num) { if (num > 0) { + std::list > newKeys; for (int i = 0; i < num; i++) { auto pair = m_KeysPool.AcquireSharedMt (); pair->GenerateKeys (); - std::unique_lock l(m_AcquiredMutex); - m_Queue.push (pair); + newKeys.push_back (pair); } + std::unique_lock l(m_AcquiredMutex); + m_Queue.splice (m_Queue.end (), newKeys); + return m_Queue.size (); + } + else + { + std::unique_lock l(m_AcquiredMutex); + return m_Queue.size (); } } - template - std::shared_ptr EphemeralKeysSupplier::Acquire () + std::shared_ptr X25519KeysPairSupplier::Acquire () { { std::unique_lock l(m_AcquiredMutex); if (!m_Queue.empty ()) { auto pair = m_Queue.front (); - m_Queue.pop (); + m_Queue.pop_front (); m_Acquired.notify_one (); return pair; } @@ -126,14 +136,13 @@ namespace transport return pair; } - template - void EphemeralKeysSupplier::Return (std::shared_ptr pair) + void X25519KeysPairSupplier::Return (std::shared_ptr pair) { if (pair) { std::unique_lock l(m_AcquiredMutex); if ((int)m_Queue.size () < 2*m_QueueSize) - m_Queue.push (pair); + m_Queue.push_back (pair); } else LogPrint(eLogError, "Transports: Return null keys"); diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 1d824b69..3643f105 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -35,36 +35,33 @@ namespace i2p { namespace transport { - template - class EphemeralKeysSupplier + class X25519KeysPairSupplier { - // called from this file only, so implementation is in Transports.cpp public: - EphemeralKeysSupplier (int size); - ~EphemeralKeysSupplier (); + X25519KeysPairSupplier (int size); + ~X25519KeysPairSupplier (); void Start (); void Stop (); - std::shared_ptr Acquire (); - void Return (std::shared_ptr pair); + std::shared_ptr Acquire (); + void Return (std::shared_ptr pair); private: void Run (); - void CreateEphemeralKeys (int num); + size_t CreateEphemeralKeys (int num); // return new queue size private: const int m_QueueSize; - i2p::util::MemoryPoolMt m_KeysPool; - std::queue > m_Queue; + i2p::util::MemoryPoolMt m_KeysPool; + std::list > m_Queue; bool m_IsRunning; std::unique_ptr m_Thread; std::condition_variable m_Acquired; std::mutex m_AcquiredMutex; }; - typedef EphemeralKeysSupplier X25519KeysPairSupplier; const int PEER_ROUTER_INFO_UPDATE_INTERVAL = 31*60; // in seconds const int PEER_ROUTER_INFO_UPDATE_INTERVAL_VARIANCE = 7*60; // in seconds