Browse Source

fixed race condition

pull/102/head
orignal 10 years ago
parent
commit
f34680134a
  1. 34
      Tunnel.cpp
  2. 1
      Tunnel.h
  3. 3
      TunnelPool.cpp
  4. 4
      TunnelPool.h

34
Tunnel.cpp

@ -243,7 +243,6 @@ namespace tunnel
Tunnel * Tunnels::GetPendingTunnel (uint32_t replyMsgID) Tunnel * Tunnels::GetPendingTunnel (uint32_t replyMsgID)
{ {
std::unique_lock<std::mutex> l(m_PendingTunnelsMutex);
auto it = m_PendingTunnels.find(replyMsgID); auto it = m_PendingTunnels.find(replyMsgID);
if (it != m_PendingTunnels.end () && it->second->GetState () == eTunnelStatePending) if (it != m_PendingTunnels.end () && it->second->GetState () == eTunnelStatePending)
{ {
@ -298,19 +297,7 @@ namespace tunnel
void Tunnels::DeleteTunnelPool (TunnelPool * pool) void Tunnels::DeleteTunnelPool (TunnelPool * pool)
{ {
if (pool) if (pool) pool->SetDeleted ();
{
{
std::unique_lock<std::mutex> l(m_PoolsMutex);
m_Pools.erase (pool->GetIdentHash ());
}
{
std::unique_lock<std::mutex> l(m_PendingTunnelsMutex);
for (auto it: m_PendingTunnels)
if (it.second->GetTunnelPool () == pool) it.second->SetTunnelPool (nullptr);
}
delete pool;
}
} }
void Tunnels::AddTransitTunnel (TransitTunnel * tunnel) void Tunnels::AddTransitTunnel (TransitTunnel * tunnel)
@ -394,7 +381,6 @@ namespace tunnel
{ {
// check pending tunnel. delete failed or timeout // check pending tunnel. delete failed or timeout
uint64_t ts = i2p::util::GetSecondsSinceEpoch (); uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
std::unique_lock<std::mutex> l(m_PendingTunnelsMutex);
for (auto it = m_PendingTunnels.begin (); it != m_PendingTunnels.end ();) for (auto it = m_PendingTunnels.begin (); it != m_PendingTunnels.end ();)
{ {
auto tunnel = it->second; auto tunnel = it->second;
@ -546,10 +532,22 @@ namespace tunnel
void Tunnels::ManageTunnelPools () void Tunnels::ManageTunnelPools ()
{ {
std::unique_lock<std::mutex> l(m_PoolsMutex); std::unique_lock<std::mutex> l(m_PoolsMutex);
for (auto& it: m_Pools) for (auto it = m_Pools.begin (); it != m_Pools.end ();)
{ {
it.second->CreateTunnels (); TunnelPool * pool = it->second;
it.second->TestTunnels (); if (!pool->IsDeleted ())
{
pool->CreateTunnels ();
pool->TestTunnels ();
it++;
}
else
{
it = m_Pools.erase (it);
for (auto it1: m_PendingTunnels)
if (it1.second->GetTunnelPool () == pool) it1.second->SetTunnelPool (nullptr);
delete pool;
}
} }
} }

1
Tunnel.h

@ -148,7 +148,6 @@ namespace tunnel
bool m_IsRunning; bool m_IsRunning;
std::thread * m_Thread; std::thread * m_Thread;
std::mutex m_PendingTunnelsMutex;
std::map<uint32_t, Tunnel *> m_PendingTunnels; // by replyMsgID std::map<uint32_t, Tunnel *> m_PendingTunnels; // by replyMsgID
std::mutex m_InboundTunnelsMutex; std::mutex m_InboundTunnelsMutex;
std::map<uint32_t, InboundTunnel *> m_InboundTunnels; std::map<uint32_t, InboundTunnel *> m_InboundTunnels;

3
TunnelPool.cpp

@ -11,7 +11,8 @@ namespace i2p
namespace tunnel namespace tunnel
{ {
TunnelPool::TunnelPool (i2p::garlic::GarlicDestination& localDestination, int numHops, int numTunnels): TunnelPool::TunnelPool (i2p::garlic::GarlicDestination& localDestination, int numHops, int numTunnels):
m_LocalDestination (localDestination), m_NumHops (numHops), m_NumTunnels (numTunnels) m_LocalDestination (localDestination), m_NumHops (numHops), m_NumTunnels (numTunnels),
m_IsDeleted (false)
{ {
} }

4
TunnelPool.h

@ -48,6 +48,9 @@ namespace tunnel
void TestTunnels (); void TestTunnels ();
void ProcessDeliveryStatus (I2NPMessage * msg); void ProcessDeliveryStatus (I2NPMessage * msg);
bool IsDeleted () const { return m_IsDeleted; };
void SetDeleted () { m_IsDeleted = true; }
private: private:
void CreateInboundTunnel (); void CreateInboundTunnel ();
@ -68,6 +71,7 @@ namespace tunnel
mutable std::mutex m_OutboundTunnelsMutex; mutable std::mutex m_OutboundTunnelsMutex;
std::set<OutboundTunnel *, TunnelCreationTimeCmp> m_OutboundTunnels; std::set<OutboundTunnel *, TunnelCreationTimeCmp> m_OutboundTunnels;
std::map<uint32_t, std::pair<OutboundTunnel *, InboundTunnel *> > m_Tests; std::map<uint32_t, std::pair<OutboundTunnel *, InboundTunnel *> > m_Tests;
bool m_IsDeleted;
public: public:

Loading…
Cancel
Save