00001 //------------------------------------------------------------------------------ 00002 // Copyright (c) 2011-2012 by European Organization for Nuclear Research (CERN) 00003 // Author: Lukasz Janyst <ljanyst@cern.ch> 00004 //------------------------------------------------------------------------------ 00005 // XRootD is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU Lesser General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // XRootD is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with XRootD. If not, see <http://www.gnu.org/licenses/>. 00017 //------------------------------------------------------------------------------ 00018 00019 #ifndef __XRD_CL_SID_MANAGER_HH__ 00020 #define __XRD_CL_SID_MANAGER_HH__ 00021 00022 #include <list> 00023 #include <set> 00024 #include <memory> 00025 #include <unordered_map> 00026 #include <string> 00027 #include <stdint.h> 00028 #include "XrdSys/XrdSysPthread.hh" 00029 #include "XrdCl/XrdClStatus.hh" 00030 #include "XrdCl/XrdClURL.hh" 00031 00032 namespace XrdCl 00033 { 00034 //---------------------------------------------------------------------------- 00035 // We need the forward declaration for the friendship to work properly 00036 //---------------------------------------------------------------------------- 00037 class SIDMgrPool; 00038 00039 //---------------------------------------------------------------------------- 00041 //---------------------------------------------------------------------------- 00042 class SIDManager 00043 { 00044 friend class SIDMgrPool; 00045 00046 private: 00047 00048 //------------------------------------------------------------------------ 00050 //------------------------------------------------------------------------ 00051 SIDManager(): pSIDCeiling(1), pRefCount(0) { } 00052 00053 #if __cplusplus < 201103L 00054 //------------------------------------------------------------------------ 00055 // For older complilers we have to make the destructor public, although 00056 // the shared_pointer is using a custom deleter. It will go away once 00057 // we drop SLC6 support. 00058 //------------------------------------------------------------------------ 00059 public: 00060 #endif 00061 //------------------------------------------------------------------------ 00063 //------------------------------------------------------------------------ 00064 ~SIDManager() { } 00065 00066 public: 00067 00068 //------------------------------------------------------------------------ 00073 //------------------------------------------------------------------------ 00074 Status AllocateSID( uint8_t sid[2] ); 00075 00076 //------------------------------------------------------------------------ 00078 //------------------------------------------------------------------------ 00079 void ReleaseSID( uint8_t sid[2] ); 00080 00081 //------------------------------------------------------------------------ 00083 //------------------------------------------------------------------------ 00084 void TimeOutSID( uint8_t sid[2] ); 00085 00086 //------------------------------------------------------------------------ 00088 //------------------------------------------------------------------------ 00089 bool IsTimedOut( uint8_t sid[2] ); 00090 00091 //------------------------------------------------------------------------ 00093 //------------------------------------------------------------------------ 00094 void ReleaseTimedOut( uint8_t sid[2] ); 00095 00096 //------------------------------------------------------------------------ 00098 //------------------------------------------------------------------------ 00099 void ReleaseAllTimedOut(); 00100 00101 //------------------------------------------------------------------------ 00103 //------------------------------------------------------------------------ 00104 uint32_t NumberOfTimedOutSIDs() const 00105 { 00106 XrdSysMutexHelper scopedLock( pMutex ); 00107 return pTimeOutSIDs.size(); 00108 } 00109 00110 //------------------------------------------------------------------------ 00112 //------------------------------------------------------------------------ 00113 uint16_t GetNumberOfAllocatedSIDs() const; 00114 00115 private: 00116 std::list<uint16_t> pFreeSIDs; 00117 std::set<uint16_t> pTimeOutSIDs; 00118 uint16_t pSIDCeiling; 00119 mutable XrdSysMutex pMutex; 00120 mutable size_t pRefCount; 00121 }; 00122 00123 //---------------------------------------------------------------------------- 00125 //---------------------------------------------------------------------------- 00126 class SIDMgrPool 00127 { 00128 public: 00129 00130 //------------------------------------------------------------------------ 00132 //------------------------------------------------------------------------ 00133 static SIDMgrPool& Instance() 00134 { 00135 //---------------------------------------------------------------------- 00136 // We could also use a nifty counter but this is simpler and will do! 00137 //---------------------------------------------------------------------- 00138 static SIDMgrPool *instance = new SIDMgrPool(); 00139 return *instance; 00140 } 00141 00142 //------------------------------------------------------------------------ 00144 //------------------------------------------------------------------------ 00145 ~SIDMgrPool() { } 00146 00147 //------------------------------------------------------------------------ 00150 // a custom deleter that will return the object to the pool 00151 //------------------------------------------------------------------------ 00152 std::shared_ptr<SIDManager> GetSIDMgr( const URL &url ); 00153 00154 //------------------------------------------------------------------------ 00156 //------------------------------------------------------------------------ 00157 void Recycle( SIDManager *mgr ); 00158 00159 private: 00160 00161 //------------------------------------------------------------------------ 00163 //------------------------------------------------------------------------ 00164 struct RecycleSidMgr 00165 { 00166 inline void operator()( SIDManager *mgr ) 00167 { 00168 SIDMgrPool &pool = SIDMgrPool::Instance(); 00169 pool.Recycle( mgr ); 00170 } 00171 }; 00172 00173 //------------------------------------------------------------------------ 00175 //------------------------------------------------------------------------ 00176 SIDMgrPool() { } 00177 00178 //------------------------------------------------------------------------ 00180 //------------------------------------------------------------------------ 00181 SIDMgrPool( const SIDMgrPool& ) = delete; 00182 SIDMgrPool( SIDMgrPool&& ) = delete; 00183 00184 //------------------------------------------------------------------------ 00186 //------------------------------------------------------------------------ 00187 SIDMgrPool& operator=( const SIDMgrPool& ) = delete; 00188 SIDMgrPool& operator=( SIDMgrPool&& ) = delete; 00189 00190 XrdSysMutex mtx; 00191 std::unordered_map<std::string, SIDManager*> pool; 00192 }; 00193 } 00194 00195 #endif // __XRD_CL_SID_MANAGER_HH__