XRootD
Loading...
Searching...
No Matches
XrdSsiResponder.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d S s i R e s p o n d e r . h h */
4/* */
5/* (c) 2013 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
33
34/******************************************************************************/
35/* L o c a l D e f i n e s */
36/******************************************************************************/
37
38#define SSI_VAL_RESPONSE spMutex.Lock();\
39 if (!reqP)\
40 {spMutex.UnLock(); return notActive;}\
41 reqP->rrMutex->Lock();\
42 if (reqP->theRespond != this)\
43 {reqP->rrMutex->UnLock(); spMutex.UnLock();\
44 return notActive;\
45 }\
46 if (reqP->Resp.rType)\
47 {reqP->rrMutex->UnLock(); spMutex.UnLock();\
48 return notPosted;\
49 }
50
51#define SSI_XEQ_RESPONSE if (reqP->onClient)\
52 {XrdSsiRequest *rX = reqP;\
53 reqP->rrMutex->UnLock(); spMutex.UnLock();\
54 return (rX->ProcessResponse(rX->errInfo,rX->Resp)\
55 ? wasPosted : notActive);\
56 } else {\
57 bool isOK = reqP->ProcessResponse(reqP->errInfo,\
58 reqP->Resp);\
59 reqP->rrMutex->UnLock(); spMutex.UnLock();\
60 return (isOK ? wasPosted : notActive);\
61 }
62
63/******************************************************************************/
64/* L o c a l C l a s s e s */
65/******************************************************************************/
66
67namespace
68{
69class XeqUnBind : public XrdSsiResponder
70{
71public:
72
73virtual void Finished( XrdSsiRequest &rqstR,
74 const XrdSsiRespInfo &rInfo,
75 bool cancel=false)
77
78 XeqUnBind() {}
79 ~XeqUnBind() {}
80};
81}
82
83/******************************************************************************/
84/* S t a t i c s */
85/******************************************************************************/
86
87namespace
88{
89XeqUnBind ForceUnBind;
90}
91
92/******************************************************************************/
93/* C o n s t r u c t o r */
94/******************************************************************************/
95
97 : spMutex(XrdSsiMutex::Recursive), reqP(0),
98 rsvd1(0), rsvd2(0), rsvd3(0)
99 {}
100
101/******************************************************************************/
102/* D e s t r u c t o r */
103/******************************************************************************/
104
106{
107// Lock ourselves (unlikely that we need to).
108//
109 spMutex.Lock();
110
111// If we haven't taken a trip to Finished() then we need todo it here. The
112// issue we have is that this object may be deleted before Finished() is called
113// which is quite dicey. So, we defer it until Finished() is called. This is
114// only an issue server-side as we don't control the finish process.
115//
116 if (reqP)
117 {reqP->rrMutex->Lock();
118 if (reqP->theRespond == this)
119 {reqP->theRespond = &ForceUnBind;
120 reqP->rrMutex->UnLock();
121 } else if (reqP->theRespond == 0) // Finish() has been called
122 {reqP->rrMutex->UnLock();
123 reqP->Dispose();
124 }
125 }
126
127// All done
128//
129 spMutex.UnLock();
130}
131
132/******************************************************************************/
133/* A l e r t */
134/******************************************************************************/
135
137{
138 XrdSsiMutexMon lck(spMutex);
139
140// If we have a request pointer then forward the alert. Otherwise, deep-six it
141//
142 if (reqP) reqP->Alert(aMsg);
143 else aMsg.RecycleMsg(false);
144}
145
146/******************************************************************************/
147/* B i n d R e q u e s t */
148/******************************************************************************/
149
151{
152 XrdSsiMutexMon lck(spMutex);
153
154// Get the request lock and link the request to this object and vice versa
155//
156 rqstR.rrMutex->Lock();
157 reqP = &rqstR;
158 rqstR.theRespond = this;
159
160// Initialize the request object
161//
162 rqstR.Resp.Init();
163 rqstR.errInfo.Clr();
164
165// Notify the request that the bind comleted (this is only used on the
166// server to allow a pending finish request to be sent to the responder).
167//
168 rqstR.BindDone();
169
170// Unlock the request. The responder is unlocked upon return
171//
172 rqstR.rrMutex->UnLock();
173}
174
175/******************************************************************************/
176/* G e t R e q u e s t */
177/******************************************************************************/
178
180{
181 XrdSsiMutexMon lck(spMutex);
182
183// If we have a request pointer, forward the call. Otherwise return nothing.
184//
185 if (reqP) return reqP->GetRequest(dlen);
186 dlen = 0;
187 return 0;
188}
189
190/******************************************************************************/
191/* R e l e a s e R e q u e s t B u f f e r */
192/******************************************************************************/
193
195{
196 XrdSsiMutexMon lck(spMutex);
197
198// If we have a request, forward the call (note we need to also get the
199// the request lock to properly serialize this call).
200//
201 if (reqP) reqP->ReleaseRequestBuffer();
202}
203
204/******************************************************************************/
205/* S e t M e t a d a t a */
206/******************************************************************************/
207
209{
210 XrdSsiMutexMon lck(spMutex);
211
212// If we don't have a request or the args are invalid, return an error.
213//
214 if (!reqP || blen < 0 || blen > MaxMetaDataSZ) return notPosted;
215
216// Post the metadata
217//
218 reqP->rrMutex->Lock();
219 reqP->Resp.mdata = buff;
220 reqP->Resp.mdlen = blen;
221 reqP->rrMutex->UnLock();
222 return wasPosted;
223}
224
225/******************************************************************************/
226/* S e t E r r R e s p o n s e */
227/******************************************************************************/
228
230 int eNum)
231{
232
233// Validate object for a response
234//
236
237// Set the error response (we have the right locks now)
238//
239 reqP->errInfo.Set(eMsg, eNum);
240 reqP->Resp.eMsg = reqP->errInfo.Get(reqP->Resp.eNum).c_str();
241 reqP->Resp.rType = XrdSsiRespInfo::isError;
242
243// Complete the response
244//
246}
247
248/******************************************************************************/
249/* S e t R e s p o n s e */
250/******************************************************************************/
251
253{
254
255// Validate object for a response
256//
258
259// Set the response (we have the right locks now)
260//
261 reqP->Resp.buff = buff;
262 reqP->Resp.blen = blen;
263 reqP->Resp.rType = XrdSsiRespInfo::isData;
264
265// Complete the response
266//
268}
269
270/******************************************************************************/
271
273{
274
275// Validate object for a response
276//
278
279// Set the response (we have the right locks now)
280//
281 reqP->Resp.fdnum = fdnum;
282 reqP->Resp.fsize = fsize;
283 reqP->Resp.rType = XrdSsiRespInfo::isFile;
284
285// Complete the response
286//
288}
289
290/******************************************************************************/
291
293{
294
295// Validate object for a response
296//
298
299// Set the response (we have the right locks now)
300//
301 reqP->Resp.eNum = 0;
302 reqP->Resp.strmP = strmP;
303 reqP->Resp.rType = XrdSsiRespInfo::isStream;
304
305// Complete the response
306//
308}
309
310/******************************************************************************/
311/* U n B i n d R e q u e s t */
312/******************************************************************************/
313
315{
316 XrdSsiMutexMon spMon(spMutex);
317
318// If we are not bound to a request, indicate an error.
319//
320 if (!reqP) return false;
321
322// Lock the request and if Finished() was not called, indicate an error.
323//
324 reqP->rrMutex->Lock();
325 if (reqP->theRespond != 0)
326 {reqP->rrMutex->UnLock();
327 return false;
328 }
329
330// We have a request pointer and Finish() was called; so do the actual unbind.
331//
332 reqP->rrMutex->UnLock();
333 reqP->Dispose();
334 reqP = 0;
335 return true;
336}
#define eMsg(x)
#define SSI_XEQ_RESPONSE
#define SSI_VAL_RESPONSE
void Clr()
Reset and clear error information.
void Set(const char *eMsg=0, int eNum=0, int eArg=0)
const std::string & Get(int &eNum) const
static void Dispose(XrdSsiRequest &reqR)
virtual void Alert(XrdSsiRespInfoMsg &aMsg)
Send or receive a server generated alert.
void ReleaseRequestBuffer()
virtual char * GetRequest(int &dlen)=0
virtual void RecycleMsg(bool sent=true)=0
char * GetRequest(int &dlen)
Status SetResponse(const char *buff, int blen)
void BindRequest(XrdSsiRequest &rqstR)
Status SetErrResponse(const char *eMsg, int eNum)
Status SetMetadata(const char *buff, int blen)
virtual ~XrdSsiResponder()
@ wasPosted
Success: The response was successfully posted.
virtual void Finished(XrdSsiRequest &rqstR, const XrdSsiRespInfo &rInfo, bool cancel=false)=0
static const int MaxMetaDataSZ
2MB metadata limit
void Alert(XrdSsiRespInfoMsg &aMsg)
int mdlen
Metadata length.
const char * mdata
-> Metadata about response.