XRootD
Loading...
Searching...
No Matches
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
20
21#include <algorithm>
22
23namespace XrdCl
24{
26 {
27 //----------------------------------------------------------------------
28 // We could also use a nifty counter but this is simpler and will do!
29 //----------------------------------------------------------------------
30 static SIDMgrPool *instance = new SIDMgrPool();
31 return *instance;
32 }
33 //----------------------------------------------------------------------------
34 // Allocate a SID
35 //---------------------------------------------------------------------------
37 {
38 XrdSysMutexHelper scopedLock( pMutex );
39
40 uint16_t allocSID = 1;
41
42 //--------------------------------------------------------------------------
43 // Get a SID from the list of free SIDs if it's not empty
44 //--------------------------------------------------------------------------
45 if( !pFreeSIDs.empty() )
46 {
47 allocSID = pFreeSIDs.front();
48 pFreeSIDs.pop_front();
49 }
50 //--------------------------------------------------------------------------
51 // Allocate a new SID if possible
52 //--------------------------------------------------------------------------
53 else
54 {
55 if( pSIDCeiling == 0xffff )
57 allocSID = pSIDCeiling++;
58 }
59
60 memcpy( sid, &allocSID, 2 );
61 pAllocTime[allocSID] = time(0);
62 return Status();
63 }
64
65 //----------------------------------------------------------------------------
66 // Release the SID that is no longer needed
67 //----------------------------------------------------------------------------
68 void SIDManager::ReleaseSID( uint8_t sid[2] )
69 {
70 XrdSysMutexHelper scopedLock( pMutex );
71 uint16_t relSID = 0;
72 memcpy( &relSID, sid, 2 );
73 pFreeSIDs.push_back( relSID );
74 pAllocTime.erase( relSID );
75 }
76
77 //----------------------------------------------------------------------------
78 // Register a SID of a request that timed out
79 //----------------------------------------------------------------------------
80 void SIDManager::TimeOutSID( uint8_t sid[2] )
81 {
82 XrdSysMutexHelper scopedLock( pMutex );
83 uint16_t tiSID = 0;
84 memcpy( &tiSID, sid, 2 );
85 pTimeOutSIDs.insert( tiSID );
86 pAllocTime.erase( tiSID );
87 }
88
89 //----------------------------------------------------------------------------
90 // Check if any SID was allocated at or before a given time
91 //----------------------------------------------------------------------------
92 bool SIDManager::IsAnySIDOldAs( const time_t tlim ) const
93 {
94 XrdSysMutexHelper scopedLock( pMutex );
95 return std::any_of( pAllocTime.begin(), pAllocTime.end(),
96 [tlim](const auto& p)
97 {
98 return p.second <= tlim;
99 } );
100 }
101
102 //----------------------------------------------------------------------------
103 // Check if a SID is timed out
104 //----------------------------------------------------------------------------
105 bool SIDManager::IsTimedOut( uint8_t sid[2] )
106 {
107 XrdSysMutexHelper scopedLock( pMutex );
108 uint16_t tiSID = 0;
109 memcpy( &tiSID, sid, 2 );
110 std::set<uint16_t>::iterator it = pTimeOutSIDs.find( tiSID );
111 if( it != pTimeOutSIDs.end() )
112 return true;
113 return false;
114 }
115
116 //----------------------------------------------------------------------------
117 // Release a timed out SID
118 //-----------------------------------------------------------------------------
119 void SIDManager::ReleaseTimedOut( uint8_t sid[2] )
120 {
121 XrdSysMutexHelper scopedLock( pMutex );
122 uint16_t tiSID = 0;
123 memcpy( &tiSID, sid, 2 );
124 pTimeOutSIDs.erase( tiSID );
125 pFreeSIDs.push_back( tiSID );
126 }
127
128 //------------------------------------------------------------------------
129 // Release all timed out SIDs
130 //------------------------------------------------------------------------
132 {
133 XrdSysMutexHelper scopedLock( pMutex );
134 std::set<uint16_t>::iterator it;
135 for( it = pTimeOutSIDs.begin(); it != pTimeOutSIDs.end(); ++it )
136 pFreeSIDs.push_back( *it );
137 pTimeOutSIDs.clear();
138 }
139
140 //----------------------------------------------------------------------------
141 // Get number of allocated SIDs
142 //----------------------------------------------------------------------------
144 {
145 XrdSysMutexHelper scopedLock( pMutex );
146 return pSIDCeiling - pFreeSIDs.size() - pTimeOutSIDs.size() - 1;
147 }
148
149 //----------------------------------------------------------------------------
150 // Returns a pointer to the SIDManager object
151 //----------------------------------------------------------------------------
152 std::shared_ptr<SIDManager> SIDMgrPool::GetSIDMgr( const URL &url )
153 {
154 //--------------------------------------------------------------------------
155 // Look for an instance of SID manager in the pool
156 //--------------------------------------------------------------------------
157 XrdSysMutexHelper lck1( mtx );
158 SIDManager *mgr = 0;
159 auto itr = pool.find( url.GetChannelId() );
160 if( itr == pool.end() )
161 {
162 mgr = new SIDManager();
163 pool[url.GetChannelId()] = mgr;
164 }
165 else mgr = itr->second;
166
167 //--------------------------------------------------------------------------
168 // Update the reference counter
169 //--------------------------------------------------------------------------
170 XrdSysMutexHelper lck2( mgr->pMutex );
171 ++mgr->pRefCount;
172
173 //--------------------------------------------------------------------------
174 // Create a shared pointer that will recycle the SID manager
175 //--------------------------------------------------------------------------
176 RecycleSidMgr deleter;
177 std::shared_ptr<SIDManager> ptr( mgr, deleter );
178
179 return ptr;
180 }
181
183 {
184 //--------------------------------------------------------------------------
185 // Lock the pool, we need to do it in the same order as in 'GetSIDMgr'
186 //--------------------------------------------------------------------------
187 XrdSysMutexHelper lck1( mtx );
188
189 //--------------------------------------------------------------------------
190 // Lock the SID manager object
191 //--------------------------------------------------------------------------
192 XrdSysMutexHelper lck2( mgr->pMutex );
193 --mgr->pRefCount;
194
195 if( !mgr->pRefCount )
196 {
197 //------------------------------------------------------------------------
198 // Remove the SID manager from the pool
199 //------------------------------------------------------------------------
200 auto itr = pool.begin();
201 for( ; itr != pool.end() ; ++itr )
202 if( itr->second == mgr )
203 {
204 pool.erase( itr );
205 break;
206 }
207
208 lck2.UnLock();
209 delete mgr;
210 }
211 }
212}
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.
static SIDMgrPool & Instance()
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:512
const uint16_t stError
An error occurred that could potentially be retried.
const uint16_t errNoMoreFreeSIDs
Procedure execution status.