00001 ////////////////////////////////////////////////////////////////////////// 00002 // // 00003 // XrdClientMessage // 00004 // // 00005 // Author: Fabrizio Furano (INFN Padova, 2005) // 00006 // // 00007 // Utility classes to handle the mapping between xrootd streamids. // 00008 // A single streamid can have multiple "parallel" streamids. // 00009 // Their use is typically to support the client to submit multiple // 00010 // parallel requests (belonging to the same LogConnectionID), // 00011 // whose answers are to be processed asynchronously when they arrive. // 00012 // // 00013 ////////////////////////////////////////////////////////////////////////// 00014 00015 00016 // $Id: XrdClientSid.hh 29874 2009-08-21 16:56:04Z ganis $ 00017 00018 00019 00020 #ifndef XRC_SID_H 00021 #define XRC_SID_H 00022 00023 #include "XrdOuc/XrdOucRash.hh" 00024 #include "XProtocol/XProtocol.hh" 00025 #include "XrdClient/XrdClientProtocol.hh" 00026 #include "XrdClient/XrdClientVector.hh" 00027 #include "XrdSys/XrdSysPthread.hh" 00028 00029 struct SidInfo { 00030 kXR_unt16 fathersid; 00031 ClientRequest outstandingreq; 00032 long long reqbyteprogress; 00033 time_t sendtime; 00034 00035 kXR_unt16 rspstatuscode; 00036 kXR_unt32 rsperrno; 00037 char *rsperrmsg; 00038 }; 00039 00040 class XrdClientSid { 00041 00042 private: 00043 // Used to quickly get info about a sid being used 00044 // as a child of another sid. A child sid is used to parallely 00045 // interact with a server for the same logical connection using its father sid 00046 // Only child sids are inserted here. If a sid is not here but is not free, 00047 // then it's a father sid, i.e. normally a sid used for the non async xrootd traffic 00048 // Remember: for any child sid, it's mandatory to keep the request 00049 // which is outstanding for that stream. This struct can be used to 00050 // read data, but also for preparing many files in advance. 00051 XrdOucRash<kXR_unt16, struct SidInfo> childsidnfo; 00052 00053 // To quickly get a sid which is not being used 00054 // This one has constant time operations if the ops 00055 // are performed at the back of the vector 00056 // Remember: 0 is NOT a valid sid 00057 XrdClientVector<kXR_unt16> freesids; 00058 00059 XrdSysMutex fMutex; 00060 00061 public: 00062 XrdClientSid(); 00063 virtual ~XrdClientSid(); 00064 00065 // Gets an available sid 00066 // From now on it will be no more available. 00067 // A retval of 0 means that there are no more available sids 00068 kXR_unt16 GetNewSid(); 00069 00070 // Gets an available sid for a request which is to be outstanding 00071 // This means that this sid will be inserted into the Rash 00072 // The request gets inserted the new sid in the right place 00073 // Also the one passed as parameter gets the new sid, as should be expected 00074 kXR_unt16 GetNewSid(kXR_unt16 sid, ClientRequest *req); 00075 00076 00077 // Releases a sid. 00078 // It is re-inserted into the available set 00079 // Its info is rmeoved from the tree 00080 void ReleaseSid(kXR_unt16 sid); 00081 00082 // Releases a sid and all its childs 00083 void ReleaseSidTree(kXR_unt16 fathersid); 00084 00085 // Report the response for an outstanding request 00086 // Typically this is used to keep track of the received errors, expecially 00087 // for async writes 00088 void ReportSidResp(kXR_unt16 sid, kXR_unt16 statuscode, kXR_unt32 errcode, char *errmsg); 00089 00090 int GetFailedOutstandingWriteRequests(kXR_unt16 fathersid, XrdClientVector<ClientRequest> &reqvect); 00091 int GetAllOutstandingWriteRequests(kXR_unt16 fathersid, XrdClientVector<ClientRequest> &reqvect); 00092 int GetOutstandingWriteRequestCnt(kXR_unt16 fathersid); 00093 00094 // 0 if non existent as a child sid 00095 inline struct SidInfo *GetSidInfo(kXR_unt16 sid) { 00096 XrdSysMutexHelper l(fMutex); 00097 return (childsidnfo.Find(sid)); 00098 }; 00099 00100 inline bool JoinedSids(kXR_unt16 father, kXR_unt16 child) { 00101 XrdSysMutexHelper l(fMutex); 00102 00103 struct SidInfo *si = childsidnfo.Find(child); 00104 00105 if (!si) return false; 00106 return (si->fathersid == father); 00107 } 00108 00109 00110 // Useful for debugging 00111 void PrintoutOutstandingRequests(); 00112 }; 00113 00114 00115 00116 00117 00118 00119 00120 00121 #endif