fixed race condition

This commit is contained in:
orignal 2016-01-25 13:34:04 -05:00
parent 3f0b595085
commit 30f68759ff
2 changed files with 21 additions and 17 deletions

View File

@ -100,7 +100,7 @@ namespace garlic
if (ts >= it->second->tagsCreationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT) if (ts >= it->second->tagsCreationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
{ {
if (m_Owner) if (m_Owner)
m_Owner->RemoveCreatedSession (it->first); m_Owner->RemoveDeliveryStatusSession (it->first);
delete it->second; delete it->second;
it = m_UnconfirmedTagsMsgs.erase (it); it = m_UnconfirmedTagsMsgs.erase (it);
} }
@ -553,10 +553,13 @@ namespace garlic
std::shared_ptr<GarlicRoutingSession> GarlicDestination::GetRoutingSession ( std::shared_ptr<GarlicRoutingSession> GarlicDestination::GetRoutingSession (
std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet) std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet)
{ {
auto it = m_Sessions.find (destination->GetIdentHash ()); GarlicRoutingSessionPtr session;
std::shared_ptr<GarlicRoutingSession> session; {
if (it != m_Sessions.end ()) std::unique_lock<std::mutex> l(m_SessionsMutex);
session = it->second; auto it = m_Sessions.find (destination->GetIdentHash ());
if (it != m_Sessions.end ())
session = it->second;
}
if (!session) if (!session)
{ {
session = std::make_shared<GarlicRoutingSession> (this, destination, session = std::make_shared<GarlicRoutingSession> (this, destination,
@ -582,25 +585,25 @@ namespace garlic
} }
} }
void GarlicDestination::RemoveCreatedSession (uint32_t msgID) void GarlicDestination::RemoveDeliveryStatusSession (uint32_t msgID)
{ {
m_CreatedSessions.erase (msgID); m_DeliveryStatusSessions.erase (msgID);
} }
void GarlicDestination::DeliveryStatusSent (std::shared_ptr<GarlicRoutingSession> session, uint32_t msgID) void GarlicDestination::DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID)
{ {
m_CreatedSessions[msgID] = session; m_DeliveryStatusSessions[msgID] = session;
} }
void GarlicDestination::HandleDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg) void GarlicDestination::HandleDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg)
{ {
uint32_t msgID = bufbe32toh (msg->GetPayload ()); uint32_t msgID = bufbe32toh (msg->GetPayload ());
{ {
auto it = m_CreatedSessions.find (msgID); auto it = m_DeliveryStatusSessions.find (msgID);
if (it != m_CreatedSessions.end ()) if (it != m_DeliveryStatusSessions.end ())
{ {
it->second->MessageConfirmed (msgID); it->second->MessageConfirmed (msgID);
m_CreatedSessions.erase (it); m_DeliveryStatusSessions.erase (it);
LogPrint (eLogDebug, "Garlic: message ", msgID, " acknowledged"); LogPrint (eLogDebug, "Garlic: message ", msgID, " acknowledged");
} }
} }

View File

@ -118,7 +118,8 @@ namespace garlic
// for HTTP only // for HTTP only
size_t GetNumOutgoingTags () const { return m_SessionTags.size (); }; size_t GetNumOutgoingTags () const { return m_SessionTags.size (); };
}; };
using GarlicRoutingSessionPtr = std::shared_ptr<GarlicRoutingSession>;
class GarlicDestination: public i2p::data::LocalDestination class GarlicDestination: public i2p::data::LocalDestination
{ {
public: public:
@ -129,13 +130,13 @@ namespace garlic
void SetNumTags (int numTags) { m_NumTags = numTags; }; void SetNumTags (int numTags) { m_NumTags = numTags; };
std::shared_ptr<GarlicRoutingSession> GetRoutingSession (std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet); std::shared_ptr<GarlicRoutingSession> GetRoutingSession (std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet);
void CleanupRoutingSessions (); void CleanupRoutingSessions ();
void RemoveCreatedSession (uint32_t msgID); void RemoveDeliveryStatusSession (uint32_t msgID);
std::shared_ptr<I2NPMessage> WrapMessage (std::shared_ptr<const i2p::data::RoutingDestination> destination, std::shared_ptr<I2NPMessage> WrapMessage (std::shared_ptr<const i2p::data::RoutingDestination> destination,
std::shared_ptr<I2NPMessage> msg, bool attachLeaseSet = false); std::shared_ptr<I2NPMessage> msg, bool attachLeaseSet = false);
void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag
virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread
void DeliveryStatusSent (std::shared_ptr<GarlicRoutingSession> session, uint32_t msgID); void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID);
virtual void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg); virtual void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
virtual void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg); virtual void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
@ -161,12 +162,12 @@ namespace garlic
// outgoing sessions // outgoing sessions
int m_NumTags; int m_NumTags;
std::mutex m_SessionsMutex; std::mutex m_SessionsMutex;
std::map<i2p::data::IdentHash, std::shared_ptr<GarlicRoutingSession> > m_Sessions; std::map<i2p::data::IdentHash, GarlicRoutingSessionPtr> m_Sessions;
// incoming // incoming
std::map<SessionTag, std::shared_ptr<i2p::crypto::CBCDecryption>> m_Tags; std::map<SessionTag, std::shared_ptr<i2p::crypto::CBCDecryption>> m_Tags;
uint32_t m_LastTagsCleanupTime; uint32_t m_LastTagsCleanupTime;
// DeliveryStatus // DeliveryStatus
std::map<uint32_t, std::shared_ptr<GarlicRoutingSession> > m_CreatedSessions; // msgID -> session std::map<uint32_t, GarlicRoutingSessionPtr> m_DeliveryStatusSessions; // msgID -> session
public: public: