XRootD
Loading...
Searching...
No Matches
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
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
47namespace XrdSsi
48{
50}
51
52/******************************************************************************/
53/* C o n s t r u c t o r */
54/******************************************************************************/
55
56XrdSsiRequest::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
65void 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
83bool 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
115bool 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
153const 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
164void 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
192
193/******************************************************************************/
194/* S e t R e t r y */
195/******************************************************************************/
196
198{
199
200// Set flag as needed
201//
202if (onoff) flags |= isaRetry;
203 else flags &= ~isaRetry;
204}
#define ENODATA
void Clr()
Reset and clear error information.
std::string GetEndPoint()
const char * GetMetadata(int &dlen)
bool Finished(bool cancel=false)
XrdSsiRequest(const char *reqid=0, uint16_t tmo=0)
friend class XrdSsiResponder
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)