diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index 6cdc0d0a..a7af0984 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -29,7 +29,7 @@ namespace data RequestedDestination::~RequestedDestination () { - if (m_RequestComplete) m_RequestComplete (nullptr); + InvokeRequestComplete (nullptr); } std::shared_ptr RequestedDestination::CreateRequestMessage (std::shared_ptr router, @@ -68,17 +68,23 @@ namespace data { m_ExcludedPeers.clear (); } + + void RequestedDestination::InvokeRequestComplete (std::shared_ptr r) + { + if (!m_RequestComplete.empty ()) + { + for (auto it: m_RequestComplete) + if (it != nullptr) it (r); + m_RequestComplete.clear (); + } + } void RequestedDestination::Success (std::shared_ptr r) { if (m_IsActive) { m_IsActive = false; - if (m_RequestComplete) - { - m_RequestComplete (r); - m_RequestComplete = nullptr; - } + InvokeRequestComplete (r); } } @@ -87,11 +93,7 @@ namespace data if (m_IsActive) { m_IsActive = false; - if (m_RequestComplete) - { - m_RequestComplete (nullptr); - m_RequestComplete = nullptr; - } + InvokeRequestComplete (nullptr); } } @@ -154,27 +156,22 @@ namespace data { // request RouterInfo directly auto dest = m_RequestedDestinationsPool.AcquireSharedMt (destination, isExploratory, direct); - dest->SetRequestComplete (requestComplete); + if (requestComplete) + dest->AddRequestComplete (requestComplete); { std::unique_lock l(m_RequestedDestinationsMutex); auto ret = m_RequestedDestinations.emplace (destination, dest); if (!ret.second) // not inserted { - dest->SetRequestComplete (nullptr); // don't call requestComplete in destructor + dest->ResetRequestComplete (); // don't call requestComplete in destructor dest = ret.first->second; // existing one - if (requestComplete && dest->IsActive ()) + if (requestComplete) { - auto prev = dest->GetRequestComplete (); - if (prev) // if already set - dest->SetRequestComplete ( - [requestComplete, prev](std::shared_ptr r) - { - prev (r); // call previous - requestComplete (r); // then new - }); + if (dest->IsActive ()) + dest->AddRequestComplete (requestComplete); else - dest->SetRequestComplete (requestComplete); - } + requestComplete (nullptr); + } return nullptr; } } diff --git a/libi2pd/NetDbRequests.h b/libi2pd/NetDbRequests.h index 903bdf76..d806b2e8 100644 --- a/libi2pd/NetDbRequests.h +++ b/libi2pd/NetDbRequests.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "Identity.h" #include "RouterInfo.h" #include "util.h" @@ -53,19 +54,22 @@ namespace data std::shared_ptr CreateRequestMessage (std::shared_ptr, std::shared_ptr replyTunnel); std::shared_ptr CreateRequestMessage (const IdentHash& floodfill); - void SetRequestComplete (const RequestComplete& requestComplete) { m_RequestComplete = requestComplete; }; - RequestComplete GetRequestComplete () const { return m_RequestComplete; }; - bool IsRequestComplete () const { return m_RequestComplete != nullptr; }; + void AddRequestComplete (const RequestComplete& requestComplete) { m_RequestComplete.push_back (requestComplete); }; + void ResetRequestComplete () { m_RequestComplete.clear (); }; void Success (std::shared_ptr r); void Fail (); + private: + + void InvokeRequestComplete (std::shared_ptr r); + private: IdentHash m_Destination; bool m_IsExploratory, m_IsDirect, m_IsActive; std::unordered_set m_ExcludedPeers; uint64_t m_CreationTime, m_LastRequestTime; // in seconds - RequestComplete m_RequestComplete; + std::list m_RequestComplete; int m_NumAttempts; };