XRootD
XrdClSIDManager.cc
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
2 // Copyright (c) 2011-2012 by European Organization for Nuclear Research (CERN)
3 // Author: Lukasz Janyst <ljanyst@cern.ch>
4 //------------------------------------------------------------------------------
5 // XRootD is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // XRootD is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with XRootD. If not, see <http://www.gnu.org/licenses/>.
17 //------------------------------------------------------------------------------
18 
19 #include "XrdCl/XrdClSIDManager.hh"
20 
21 #include <algorithm>
22 
23 namespace XrdCl
24 {
25  //----------------------------------------------------------------------------
26  // Allocate a SID
27  //---------------------------------------------------------------------------
28  Status SIDManager::AllocateSID( uint8_t sid[2] )
29  {
30  XrdSysMutexHelper scopedLock( pMutex );
31 
32  uint16_t allocSID = 1;
33 
34  //--------------------------------------------------------------------------
35  // Get a SID from the list of free SIDs if it's not empty
36  //--------------------------------------------------------------------------
37  if( !pFreeSIDs.empty() )
38  {
39  allocSID = pFreeSIDs.front();
40  pFreeSIDs.pop_front();
41  }
42  //--------------------------------------------------------------------------
43  // Allocate a new SID if possible
44  //--------------------------------------------------------------------------
45  else
46  {
47  if( pSIDCeiling == 0xffff )
48  return Status( stError, errNoMoreFreeSIDs );
49  allocSID = pSIDCeiling++;
50  }
51 
52  memcpy( sid, &allocSID, 2 );
53  pAllocTime[allocSID] = time(0);
54  return Status();
55  }
56 
57  //----------------------------------------------------------------------------
58  // Release the SID that is no longer needed
59  //----------------------------------------------------------------------------
60  void SIDManager::ReleaseSID( uint8_t sid[2] )
61  {
62  XrdSysMutexHelper scopedLock( pMutex );
63  uint16_t relSID = 0;
64  memcpy( &relSID, sid, 2 );
65  pFreeSIDs.push_back( relSID );
66  pAllocTime.erase( relSID );
67  }
68 
69  //----------------------------------------------------------------------------
70  // Register a SID of a request that timed out
71  //----------------------------------------------------------------------------
72  void SIDManager::TimeOutSID( uint8_t sid[2] )
73  {
74  XrdSysMutexHelper scopedLock( pMutex );
75  uint16_t tiSID = 0;
76  memcpy( &tiSID, sid, 2 );
77  pTimeOutSIDs.insert( tiSID );
78  pAllocTime.erase( tiSID );
79  }
80 
81  //----------------------------------------------------------------------------
82  // Check if any SID was allocated at or before a given time
83  //----------------------------------------------------------------------------
84  bool SIDManager::IsAnySIDOldAs( const time_t tlim ) const
85  {
86  XrdSysMutexHelper scopedLock( pMutex );
87  return std::any_of( pAllocTime.begin(), pAllocTime.end(),
88  [tlim](const auto& p)
89  {
90  return p.second <= tlim;
91  } );
92  }
93 
94  //----------------------------------------------------------------------------
95  // Check if a SID is timed out
96  //----------------------------------------------------------------------------
97  bool SIDManager::IsTimedOut( uint8_t sid[2] )
98  {
99  XrdSysMutexHelper scopedLock( pMutex );
100  uint16_t tiSID = 0;
101  memcpy( &tiSID, sid, 2 );
102  std::set<uint16_t>::iterator it = pTimeOutSIDs.find( tiSID );
103  if( it != pTimeOutSIDs.end() )
104  return true;
105  return false;
106  }
107 
108  //----------------------------------------------------------------------------
109  // Release a timed out SID
110  //-----------------------------------------------------------------------------
111  void SIDManager::ReleaseTimedOut( uint8_t sid[2] )
112  {
113  XrdSysMutexHelper scopedLock( pMutex );
114  uint16_t tiSID = 0;
115  memcpy( &tiSID, sid, 2 );
116  pTimeOutSIDs.erase( tiSID );
117  pFreeSIDs.push_back( tiSID );
118  }
119 
120  //------------------------------------------------------------------------
121  // Release all timed out SIDs
122  //------------------------------------------------------------------------
124  {
125  XrdSysMutexHelper scopedLock( pMutex );
126  std::set<uint16_t>::iterator it;
127  for( it = pTimeOutSIDs.begin(); it != pTimeOutSIDs.end(); ++it )
128  pFreeSIDs.push_back( *it );
129  pTimeOutSIDs.clear();
130  }
131 
132  //----------------------------------------------------------------------------
133  // Get number of allocated SIDs
134  //----------------------------------------------------------------------------
136  {
137  XrdSysMutexHelper scopedLock( pMutex );
138  return pSIDCeiling - pFreeSIDs.size() - pTimeOutSIDs.size() - 1;
139  }
140 
141  //----------------------------------------------------------------------------
142  // Returns a pointer to the SIDManager object
143  //----------------------------------------------------------------------------
144  std::shared_ptr<SIDManager> SIDMgrPool::GetSIDMgr( const URL &url )
145  {
146  //--------------------------------------------------------------------------
147  // Look for an instance of SID manager in the pool
148  //--------------------------------------------------------------------------
149  XrdSysMutexHelper lck1( mtx );
150  SIDManager *mgr = 0;
151  auto itr = pool.find( url.GetChannelId() );
152  if( itr == pool.end() )
153  {
154  mgr = new SIDManager();
155  pool[url.GetChannelId()] = mgr;
156  }
157  else mgr = itr->second;
158 
159  //--------------------------------------------------------------------------
160  // Update the reference counter
161  //--------------------------------------------------------------------------
162  XrdSysMutexHelper lck2( mgr->pMutex );
163  ++mgr->pRefCount;
164 
165  //--------------------------------------------------------------------------
166  // Create a shared pointer that will recycle the SID manager
167  //--------------------------------------------------------------------------
168  RecycleSidMgr deleter;
169  std::shared_ptr<SIDManager> ptr( mgr, deleter );
170 
171  return ptr;
172  }
173 
175  {
176  //--------------------------------------------------------------------------
177  // Lock the pool, we need to do it in the same order as in 'GetSIDMgr'
178  //--------------------------------------------------------------------------
179  XrdSysMutexHelper lck1( mtx );
180 
181  //--------------------------------------------------------------------------
182  // Lock the SID manager object
183  //--------------------------------------------------------------------------
184  XrdSysMutexHelper lck2( mgr->pMutex );
185  --mgr->pRefCount;
186 
187  if( !mgr->pRefCount )
188  {
189  //------------------------------------------------------------------------
190  // Remove the SID manager from the pool
191  //------------------------------------------------------------------------
192  auto itr = pool.begin();
193  for( ; itr != pool.end() ; ++itr )
194  if( itr->second == mgr )
195  {
196  pool.erase( itr );
197  break;
198  }
199 
200  lck2.UnLock();
201  delete mgr;
202  }
203  }
204 }
Handle XRootD stream IDs.
void ReleaseTimedOut(uint8_t sid[2])
Release a timed out SID.
uint16_t GetNumberOfAllocatedSIDs() const
Number of allocated streams.
void TimeOutSID(uint8_t sid[2])
Register a SID of a request that timed out.
bool IsAnySIDOldAs(const time_t tlim) const
Check if any SID was allocated at or before a given time.
bool IsTimedOut(uint8_t sid[2])
Check if a SID is timed out.
Status AllocateSID(uint8_t sid[2])
void ReleaseAllTimedOut()
Release all timed out SIDs.
void ReleaseSID(uint8_t sid[2])
Release the SID that is no longer needed.
void Recycle(SIDManager *mgr)
std::shared_ptr< SIDManager > GetSIDMgr(const URL &url)
URL representation.
Definition: XrdClURL.hh:31
std::string GetChannelId() const
Definition: XrdClURL.cc:505
const uint16_t stError
An error occurred that could potentially be retried.
Definition: XrdClStatus.hh:32
const uint16_t errNoMoreFreeSIDs
Definition: XrdClStatus.hh:97
Procedure execution status.
Definition: XrdClStatus.hh:115