XRootD
XrdSsiRequest.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d S s i R e q u e s t . c c */
4 /* */
5 /* (c) 2016 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* Produced by Andrew Hanushevsky for Stanford University under contract */
7 /* DE-AC02-76-SFO0515 with the Department of Energy */
8 /* */
9 /* This file is part of the XRootD software suite. */
10 /* */
11 /* XRootD is free software: you can redistribute it and/or modify it under */
12 /* the terms of the GNU Lesser General Public License as published by the */
13 /* Free Software Foundation, either version 3 of the License, or (at your */
14 /* option) any later version. */
15 /* */
16 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19 /* License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24 /* */
25 /* The copyright holder's institutional names and contributor's names may not */
26 /* be used to endorse or promote products derived from this software without */
27 /* specific prior written permission of the institution or contributor. */
28 /******************************************************************************/
29 
30 #include <cerrno>
31 #include <cstdlib>
32 #include <cstring>
33 
34 #include "XrdSsi/XrdSsiRespInfo.hh"
36 #include "XrdSsi/XrdSsiRequest.hh"
37 #include "XrdSsi/XrdSsiStream.hh"
38 
39 #ifndef ENODATA
40 #define ENODATA ENOATTR
41 #endif
42 
43 /******************************************************************************/
44 /* S t a t i c M e m b e r s */
45 /******************************************************************************/
46 
47 namespace XrdSsi
48 {
50 }
51 
52 /******************************************************************************/
53 /* C o n s t r u c t o r */
54 /******************************************************************************/
55 
56 XrdSsiRequest::XrdSsiRequest(const char *reqid, uint16_t tmo)
57  : reqID(reqid), rrMutex(&XrdSsi::ubMutex),
58  theRespond(0), rsvd1(0), epNode(0),
59  detTTL(0), tOut(0), onClient(true), flags(0) {}
60 
61 /******************************************************************************/
62 /* Private: C l e a n U p */
63 /******************************************************************************/
64 
65 void XrdSsiRequest::CleanUp()
66 {
67 // Reinitialize the this object in case it is being reused. While we don't
68 // really need to get a lock, we do so just in case there is a coding error.
69 //
70  rrMutex->Lock();
71  Resp.Init();
72  errInfo.Clr();
73  epNode = 0;
74  XrdSsiMutex *mP = rrMutex;
75  rrMutex = &XrdSsi::ubMutex;
76  mP->UnLock();
77 }
78 
79 /******************************************************************************/
80 /* Private: C o p y D a t a */
81 /******************************************************************************/
82 
83 bool XrdSsiRequest::CopyData(char *buff, int blen)
84 {
85  bool last;
86 
87 // Make sure the buffer length is valid
88 //
89  if (blen <= 0)
90  {errInfo.Set("Buffer length invalid", EINVAL);
91  return false;
92  }
93 
94 // Check if we have any data here
95 //
96  rrMutex->Lock();
97  if (Resp.blen > 0)
98  {if (Resp.blen > blen) last = false;
99  else {blen = Resp.blen; last = true;}
100  memcpy(buff, Resp.buff, blen);
101  Resp.buff += blen; Resp.blen -= blen;
102  } else {blen = 0; last = true;}
103  rrMutex->UnLock();
104 
105 // Invoke the callback
106 //
107  ProcessResponseData(errInfo, buff, blen, last);
108  return true;
109 }
110 
111 /******************************************************************************/
112 /* F i n i s h e d */
113 /******************************************************************************/
114 
115 bool XrdSsiRequest::Finished(bool cancel)
116 {
117  XrdSsiResponder *respP;
118 
119 // Obtain the responder
120 //
121  rrMutex->Lock();
122  respP = theRespond;
123  theRespond = 0;
124  rrMutex->UnLock();
125 
126 // Tell any responder we are finished (we might not have one)
127 //
128  if (respP) respP->Finished(*this, Resp, cancel);
129 
130 // We are done. The object will be reiniialized when UnBindRequest() is
131 // called which will call UnBind() in this object. Since the timing is not
132 // known we can't touch anthing in this object at this point.
133 // Return false if there was no responder associated with this request.
134 //
135  return respP != 0;
136 }
137 
138 /******************************************************************************/
139 /* G e t E n d P o i n t */
140 /******************************************************************************/
141 
143 {
144  XrdSsiMutexMon lck(rrMutex);
145  std::string epName(epNode ? epNode : "");
146  return epName;
147 }
148 
149 /******************************************************************************/
150 /* G e t M e t a d a t a */
151 /******************************************************************************/
152 
153 const char *XrdSsiRequest::GetMetadata(int &dlen)
154 {
155  XrdSsiMutexMon lck(rrMutex);
156  if ((dlen = Resp.mdlen)) return Resp.mdata;
157  return 0;
158 }
159 
160 /******************************************************************************/
161 /* G e t R e s p o n s e D a t a */
162 /******************************************************************************/
163 
164 void XrdSsiRequest::GetResponseData(char *buff, int blen)
165 {
166  XrdSsiMutexMon mHelper(rrMutex);
167 
168 // If this is really a stream then just call the stream object to get the data.
169 // In the degenrate case, it's actually a data response, then we must copy it.
170 //
171  if (Resp.rType == XrdSsiRespInfo::isStream)
172  {if (Resp.strmP->SetBuff(errInfo, buff, blen)) return;}
173  else if (Resp.rType == XrdSsiRespInfo::isData)
174  {if (CopyData(buff, blen)) return;}
175  else errInfo.Set("Not a stream", ENODATA);
176 
177 // If we got here then an error occurred during the setup, reflect the error
178 // via the callback (in the future we will schedule a new thread).
179 //
180  ProcessResponseData(errInfo, buff, -1, true);
181 }
182 
183 /******************************************************************************/
184 /* R e l e a s e R e q u e s t B u f f e r */
185 /******************************************************************************/
186 
188 {
189  XrdSsiMutexMon lck(rrMutex);
191 }
192 
193 /******************************************************************************/
194 /* S e t R e t r y */
195 /******************************************************************************/
196 
197 void XrdSsiRequest::SetRetry(bool onoff)
198 {
199 
200 // Set flag as needed
201 //
202 if (onoff) flags |= isaRetry;
203  else flags &= ~isaRetry;
204 }
#define ENODATA
void Clr()
Reset and clear error information.
void Set(const char *eMsg=0, int eNum=0, int eArg=0)
std::string GetEndPoint()
const char * GetMetadata(int &dlen)
bool Finished(bool cancel=false)
XrdSsiRequest(const char *reqid=0, uint16_t tmo=0)
virtual void RelRequestBuffer()
void ReleaseRequestBuffer()
void SetRetry(bool onoff)
virtual void ProcessResponseData(const XrdSsiErrInfo &eInfo, char *buff, int blen, bool last)
void GetResponseData(char *buff, int blen)
virtual void Finished(XrdSsiRequest &rqstR, const XrdSsiRespInfo &rInfo, bool cancel=false)=0
XrdSsiMutex ubMutex(XrdSsiMutex::Recursive)
int mdlen
Metadata length.
const char * mdata
-> Metadata about response.