00001 #ifndef XRC_SID_H 00002 #define XRC_SID_H 00003 /******************************************************************************/ 00004 /* */ 00005 /* X r d C l i e n t S i d . h h */ 00006 /* */ 00007 /* Author: Fabrizio Furano (INFN Padova, 2005) */ 00008 /* */ 00009 /* This file is part of the XRootD software suite. */ 00010 /* */ 00011 /* XRootD is free software: you can redistribute it and/or modify it under */ 00012 /* the terms of the GNU Lesser General Public License as published by the */ 00013 /* Free Software Foundation, either version 3 of the License, or (at your */ 00014 /* option) any later version. */ 00015 /* */ 00016 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ 00017 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ 00018 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ 00019 /* License for more details. */ 00020 /* */ 00021 /* You should have received a copy of the GNU Lesser General Public License */ 00022 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ 00023 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */ 00024 /* */ 00025 /* The copyright holder's institutional names and contributor's names may not */ 00026 /* be used to endorse or promote products derived from this software without */ 00027 /* specific prior written permission of the institution or contributor. */ 00028 /******************************************************************************/ 00029 00031 // // 00032 // Utility classes to handle the mapping between xrootd streamids. // 00033 // A single streamid can have multiple "parallel" streamids. // 00034 // Their use is typically to support the client to submit multiple // 00035 // parallel requests (belonging to the same LogConnectionID), // 00036 // whose answers are to be processed asynchronously when they arrive. // 00037 // // 00039 00040 #include "XrdOuc/XrdOucRash.hh" 00041 #include "XProtocol/XProtocol.hh" 00042 #include "XrdClient/XrdClientProtocol.hh" 00043 #include "XrdClient/XrdClientVector.hh" 00044 #include "XrdSys/XrdSysPthread.hh" 00045 00046 struct SidInfo { 00047 kXR_unt16 fathersid; 00048 ClientRequest outstandingreq; 00049 long long reqbyteprogress; 00050 time_t sendtime; 00051 00052 kXR_unt16 rspstatuscode; 00053 kXR_unt32 rsperrno; 00054 char *rsperrmsg; 00055 }; 00056 00057 class XrdClientSid { 00058 00059 private: 00060 // Used to quickly get info about a sid being used 00061 // as a child of another sid. A child sid is used to parallely 00062 // interact with a server for the same logical connection using its father sid 00063 // Only child sids are inserted here. If a sid is not here but is not free, 00064 // then it's a father sid, i.e. normally a sid used for the non async xrootd traffic 00065 // Remember: for any child sid, it's mandatory to keep the request 00066 // which is outstanding for that stream. This struct can be used to 00067 // read data, but also for preparing many files in advance. 00068 XrdOucRash<kXR_unt16, struct SidInfo> childsidnfo; 00069 00070 // To quickly get a sid which is not being used 00071 // This one has constant time operations if the ops 00072 // are performed at the back of the vector 00073 // Remember: 0 is NOT a valid sid 00074 XrdClientVector<kXR_unt16> freesids; 00075 00076 XrdSysMutex fMutex; 00077 00078 public: 00079 XrdClientSid(); 00080 virtual ~XrdClientSid(); 00081 00082 // Gets an available sid 00083 // From now on it will be no more available. 00084 // A retval of 0 means that there are no more available sids 00085 kXR_unt16 GetNewSid(); 00086 00087 // Gets an available sid for a request which is to be outstanding 00088 // This means that this sid will be inserted into the Rash 00089 // The request gets inserted the new sid in the right place 00090 // Also the one passed as parameter gets the new sid, as should be expected 00091 kXR_unt16 GetNewSid(kXR_unt16 sid, ClientRequest *req); 00092 00093 00094 // Releases a sid. 00095 // It is re-inserted into the available set 00096 // Its info is rmeoved from the tree 00097 void ReleaseSid(kXR_unt16 sid); 00098 00099 // Releases a sid and all its childs 00100 void ReleaseSidTree(kXR_unt16 fathersid); 00101 00102 // Report the response for an outstanding request 00103 // Typically this is used to keep track of the received errors, expecially 00104 // for async writes 00105 void ReportSidResp(kXR_unt16 sid, kXR_unt16 statuscode, kXR_unt32 errcode, char *errmsg); 00106 00107 int GetFailedOutstandingWriteRequests(kXR_unt16 fathersid, XrdClientVector<ClientRequest> &reqvect); 00108 int GetAllOutstandingWriteRequests(kXR_unt16 fathersid, XrdClientVector<ClientRequest> &reqvect); 00109 int GetOutstandingWriteRequestCnt(kXR_unt16 fathersid); 00110 00111 // 0 if non existent as a child sid 00112 inline struct SidInfo *GetSidInfo(kXR_unt16 sid) { 00113 XrdSysMutexHelper l(fMutex); 00114 return (childsidnfo.Find(sid)); 00115 }; 00116 00117 inline bool JoinedSids(kXR_unt16 father, kXR_unt16 child) { 00118 XrdSysMutexHelper l(fMutex); 00119 00120 struct SidInfo *si = childsidnfo.Find(child); 00121 00122 if (!si) return false; 00123 return (si->fathersid == father); 00124 } 00125 00126 00127 // Useful for debugging 00128 void PrintoutOutstandingRequests(); 00129 }; 00130 #endif