Skip to content

Commit

Permalink
[XrdCl] Fix potential stream timeout when a new request is sent to an…
Browse files Browse the repository at this point in the history
… idle stream
  • Loading branch information
smithdh authored and amadio committed Jun 30, 2023
1 parent 78f8d9d commit b7be027
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 5 deletions.
18 changes: 18 additions & 0 deletions src/XrdCl/XrdClSIDManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

#include "XrdCl/XrdClSIDManager.hh"

#include <algorithm>

namespace XrdCl
{
//----------------------------------------------------------------------------
Expand Down Expand Up @@ -48,6 +50,7 @@ namespace XrdCl
}

memcpy( sid, &allocSID, 2 );
pAllocTime[allocSID] = time(0);
return Status();
}

Expand All @@ -60,6 +63,7 @@ namespace XrdCl
uint16_t relSID = 0;
memcpy( &relSID, sid, 2 );
pFreeSIDs.push_back( relSID );
pAllocTime.erase( relSID );
}

//----------------------------------------------------------------------------
Expand All @@ -71,6 +75,20 @@ namespace XrdCl
uint16_t tiSID = 0;
memcpy( &tiSID, sid, 2 );
pTimeOutSIDs.insert( tiSID );
pAllocTime.erase( tiSID );
}

//----------------------------------------------------------------------------
// Check if any SID was allocated at or before a given time
//----------------------------------------------------------------------------
bool SIDManager::IsAnySIDOldAs( const time_t tlim ) const
{
XrdSysMutexHelper scopedLock( pMutex );
return std::any_of( pAllocTime.begin(), pAllocTime.end(),
[tlim](const auto& p)
{
return p.second <= tlim;
} );
}

//----------------------------------------------------------------------------
Expand Down
6 changes: 6 additions & 0 deletions src/XrdCl/XrdClSIDManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ namespace XrdCl
//------------------------------------------------------------------------
void TimeOutSID( uint8_t sid[2] );

//----------------------------------------------------------------------------
//! Check if any SID was allocated at or before a given time
//----------------------------------------------------------------------------
bool IsAnySIDOldAs( const time_t tlim ) const;

//------------------------------------------------------------------------
//! Check if a SID is timed out
//------------------------------------------------------------------------
Expand Down Expand Up @@ -113,6 +118,7 @@ namespace XrdCl
uint16_t GetNumberOfAllocatedSIDs() const;

private:
std::unordered_map<uint16_t, time_t> pAllocTime;
std::list<uint16_t> pFreeSIDs;
std::set<uint16_t> pTimeOutSIDs;
uint16_t pSIDCeiling;
Expand Down
12 changes: 7 additions & 5 deletions src/XrdCl/XrdClXRootDTransport.cc
Original file line number Diff line number Diff line change
Expand Up @@ -795,20 +795,22 @@ namespace XrdCl

XrdSysMutexHelper scopedLock( info->mutex );

uint16_t allocatedSIDs = info->sidManager->GetNumberOfAllocatedSIDs();
const time_t now = time(0);
const bool anySID =
info->sidManager->IsAnySIDOldAs( now - streamTimeout );

log->Dump( XRootDTransportMsg, "[%s] Stream inactive since %d seconds, "
"stream timeout: %d, allocated SIDs: %d, wait barrier: %s",
"stream timeout: %d, any SID: %d, wait barrier: %s",
info->streamName.c_str(), inactiveTime, streamTimeout,
allocatedSIDs, Utils::TimeToString(info->waitBarrier).c_str() );
anySID, Utils::TimeToString(info->waitBarrier).c_str() );

if( inactiveTime < streamTimeout )
return Status();

if( time(0) < info->waitBarrier )
if( now < info->waitBarrier )
return Status();

if( !allocatedSIDs )
if( !anySID )
return Status();

return Status( stError, errSocketTimeout );
Expand Down

0 comments on commit b7be027

Please sign in to comment.