xrootd
XrdClOperationHandlers.hh
Go to the documentation of this file.
1//------------------------------------------------------------------------------
2// Copyright (c) 2011-2017 by European Organization for Nuclear Research (CERN)
3// Author: Krzysztof Jamrog <krzysztof.piotr.jamrog@cern.ch>,
4// Michal Simon <michal.simon@cern.ch>
5//------------------------------------------------------------------------------
6// This file is part of the XRootD software suite.
7//
8// XRootD is free software: you can redistribute it and/or modify
9// it under the terms of the GNU Lesser General Public License as published by
10// the Free Software Foundation, either version 3 of the License, or
11// (at your option) any later version.
12//
13// XRootD is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU Lesser General Public License
19// along with XRootD. If not, see <http://www.gnu.org/licenses/>.
20//
21// In applying this licence, CERN does not waive the privileges and immunities
22// granted to it by virtue of its status as an Intergovernmental Organization
23// or submit itself to any jurisdiction.
24//------------------------------------------------------------------------------
25
26#ifndef __XRD_CL_OPERATION_HANDLERS_HH__
27#define __XRD_CL_OPERATION_HANDLERS_HH__
28
29#include "XrdCl/XrdClFile.hh"
30
31namespace XrdCl
32{
33 //----------------------------------------------------------------------------
38 //----------------------------------------------------------------------------
39 template<typename Hdlr>
41 {
42 //------------------------------------------------------------------------
45 //------------------------------------------------------------------------
46 static constexpr bool value = std::is_base_of<XrdCl::ResponseHandler, Hdlr>::value;
47 };
48
49 //----------------------------------------------------------------------------
54 //----------------------------------------------------------------------------
55 template<typename Hdlr>
56 struct IsResponseHandler<Hdlr*>
57 {
58 //------------------------------------------------------------------------
61 //------------------------------------------------------------------------
62 static constexpr bool value = std::is_base_of<XrdCl::ResponseHandler, Hdlr>::value;
63 };
64
65 //----------------------------------------------------------------------------
67 //----------------------------------------------------------------------------
69 {
70 public:
71
72 //------------------------------------------------------------------------
74 //
76 //------------------------------------------------------------------------
78 std::function<void( XRootDStatus& )> handleFunction ) :
79 fun( handleFunction )
80 {
81 }
82
83 //------------------------------------------------------------------------
85 //------------------------------------------------------------------------
86 void HandleResponse( XRootDStatus *status, AnyObject *response )
87 {
88 fun( *status );
89 delete status;
90 delete response;
91 delete this;
92 }
93
94 private:
95 //------------------------------------------------------------------------
97 //------------------------------------------------------------------------
98 std::function<void( XRootDStatus& )> fun;
99 };
100
101 //----------------------------------------------------------------------------
105 //----------------------------------------------------------------------------
106 template<typename ResponseType>
108 {
109 public:
110
111 //------------------------------------------------------------------------
113 //
115 //------------------------------------------------------------------------
117 std::function<void( XRootDStatus&, ResponseType& )> handleFunction ) :
118 fun( handleFunction )
119 {
120 }
121
122 //------------------------------------------------------------------------
124 //------------------------------------------------------------------------
125 void HandleResponse( XRootDStatus *status, AnyObject *response )
126 {
127 ResponseType *res = nullptr;
128 if( status->IsOK() )
129 response->Get( res );
130 else
131 res = &nullref;
132 fun( *status, *res );
133 delete status;
134 delete response;
135 delete this;
136 }
137
138 private:
139 //------------------------------------------------------------------------
141 //------------------------------------------------------------------------
142 std::function<void( XRootDStatus&, ResponseType& )> fun;
143
144 //------------------------------------------------------------------------
146 //------------------------------------------------------------------------
147 static ResponseType nullref;
148 };
149
150 //----------------------------------------------------------------------------
151 // Initialize the 'null-reference'
152 //----------------------------------------------------------------------------
153 template<typename ResponseType>
155
156
157 //----------------------------------------------------------------------------
162 //----------------------------------------------------------------------------
163 template<typename Response, typename Return>
165 {
166 public:
167
168 //------------------------------------------------------------------------
170 //
172 //------------------------------------------------------------------------
173 TaskWrapper( std::packaged_task<Return( XRootDStatus&, Response& )> && task ) :
174 task( std::move( task ) )
175 {
176 }
177
178 //------------------------------------------------------------------------
180 //------------------------------------------------------------------------
181 void HandleResponse( XRootDStatus *status, AnyObject *response )
182 {
183 Response *resp = nullptr;
184 if( status->IsOK() )
185 response->Get( resp );
186 else
187 resp = &nullref;
188 task( *status, *resp );
189 delete status;
190 delete response;
191 delete this;
192 }
193
194 private:
195
196 //------------------------------------------------------------------------
198 //------------------------------------------------------------------------
199 std::packaged_task<Return( XRootDStatus&, Response& )> task;
200
201 //------------------------------------------------------------------------
203 //------------------------------------------------------------------------
204 static Response nullref;
205 };
206
207 //----------------------------------------------------------------------------
208 // Initialize the 'null-reference'
209 //----------------------------------------------------------------------------
210 template<typename Response, typename Return>
212
213 //----------------------------------------------------------------------------
219 //----------------------------------------------------------------------------
220 template<typename Return>
221 class TaskWrapper<void, Return>
222 {
223 public:
224
225 //------------------------------------------------------------------------
227 //
229 //------------------------------------------------------------------------
230 TaskWrapper( std::packaged_task<Return( XRootDStatus& )> && task ) :
231 task( std::move( task ) )
232 {
233 }
234
235 //------------------------------------------------------------------------
237 //------------------------------------------------------------------------
238 void HandleResponse( XRootDStatus *status, AnyObject *response )
239 {
240 task( *status );
241 delete status;
242 delete response;
243 delete this;
244 }
245
246 private:
247
248 //------------------------------------------------------------------------
250 //------------------------------------------------------------------------
251 std::packaged_task<Return( XRootDStatus& )> task;
252 };
253
254
255 //----------------------------------------------------------------------------
257 //----------------------------------------------------------------------------
259 {
260 public:
261
262 //------------------------------------------------------------------------
264 //
266 //------------------------------------------------------------------------
268 std::function<void( XRootDStatus&, StatInfo& )> handleFunction ) :
269 f( f ), fun( handleFunction )
270 {
271 }
272
273 //------------------------------------------------------------------------
275 //------------------------------------------------------------------------
276 void HandleResponse( XRootDStatus *status, AnyObject *response )
277 {
278 StatInfo *info = nullptr;
279 if( status->IsOK() )
280 XRootDStatus st = f.Stat( false, info );
281 else
282 info = &nullref;
283 fun( *status, *info );
284 if( info != &nullref ) delete info;
285 delete status;
286 delete response;
287 delete this;
288 }
289
290 private:
292 //------------------------------------------------------------------------
294 //------------------------------------------------------------------------
295 std::function<void( XRootDStatus&, StatInfo& )> fun;
296
297 //------------------------------------------------------------------------
299 //------------------------------------------------------------------------
301 };
302
303 //----------------------------------------------------------------------------
304 // Initialize the 'null-reference'
305 //----------------------------------------------------------------------------
307
308 //----------------------------------------------------------------------------
310 //----------------------------------------------------------------------------
311 class PipelineException : public std::exception
312 {
313 public:
314
315 //------------------------------------------------------------------------
317 //------------------------------------------------------------------------
319 {
320
321 }
322
323 //------------------------------------------------------------------------
325 //------------------------------------------------------------------------
327 {
328
329 }
330
331 //------------------------------------------------------------------------
333 //------------------------------------------------------------------------
335 {
336 error = ex.error;
337 return *this;
338 }
339
340 //------------------------------------------------------------------------
342 //------------------------------------------------------------------------
343 const char* what() const noexcept
344 {
345 return error.ToString().c_str();
346 }
347
348 //------------------------------------------------------------------------
350 //------------------------------------------------------------------------
351 const XRootDStatus& GetError() const
352 {
353 return error;
354 }
355
356 private:
357
358 //------------------------------------------------------------------------
360 //------------------------------------------------------------------------
362 };
363
364 //----------------------------------------------------------------------------
368 //----------------------------------------------------------------------------
369 template<typename Response>
371 {
372 public:
373
374 //------------------------------------------------------------------------
379 //------------------------------------------------------------------------
380 FutureWrapperBase( std::future<Response> &ftr ) : called( false )
381 {
382 ftr = prms.get_future();
383 }
384
385 //------------------------------------------------------------------------
389 //------------------------------------------------------------------------
391 {
392 if( !called )
394 }
395
396 protected:
397
398 //------------------------------------------------------------------------
402 //------------------------------------------------------------------------
403 void SetException( const XRootDStatus &err )
404 {
405 std::exception_ptr ex = std::make_exception_ptr( PipelineException( err ) );
406 prms.set_exception( ex );
407 }
408
409 //------------------------------------------------------------------------
411 //------------------------------------------------------------------------
412 std::promise<Response> prms;
413
414 //------------------------------------------------------------------------
416 //------------------------------------------------------------------------
417 bool called;
418
419 };
420
421 //----------------------------------------------------------------------------
425 //----------------------------------------------------------------------------
426 template<typename Response>
427 class FutureWrapper : public FutureWrapperBase<Response>
428 {
429 public:
430
431 //------------------------------------------------------------------------
435 //------------------------------------------------------------------------
436 FutureWrapper( std::future<Response> &ftr ) : FutureWrapperBase<Response>( ftr )
437 {
438
439 }
440
441 //------------------------------------------------------------------------
443 //------------------------------------------------------------------------
444 void HandleResponse( XRootDStatus *status, AnyObject *response )
445 {
446 this->called = true;
447
448 if( status->IsOK() )
449 {
450 Response *resp = 0;
451 response->Get( resp );
452 this->prms.set_value( std::move( *resp ) );
453 }
454 else
455 this->SetException( *status );
456
457 delete status;
458 delete response;
459 delete this;
460 }
461 };
462
463 //----------------------------------------------------------------------------
465 //----------------------------------------------------------------------------
466 template<>
467 class FutureWrapper<void> : public FutureWrapperBase<void>
468 {
469 public:
470
471 //------------------------------------------------------------------------
475 //------------------------------------------------------------------------
476 FutureWrapper( std::future<void> &ftr ) : FutureWrapperBase<void>( ftr )
477 {
478
479 }
480
481 //------------------------------------------------------------------------
483 //------------------------------------------------------------------------
484 void HandleResponse( XRootDStatus *status, AnyObject *response )
485 {
486 this->called = true;
487
488
489 if( status->IsOK() )
490 {
491 prms.set_value();
492 }
493 else
494 SetException( *status );
495
496 delete status;
497 delete response;
498 delete this;
499 }
500 };
501
502
503 //----------------------------------------------------------------------------
508 //----------------------------------------------------------------------------
509 template<typename Response>
510 struct RespBase
511 {
512 //------------------------------------------------------------------------
517 //------------------------------------------------------------------------
518 inline static ResponseHandler* Create( ResponseHandler *hdlr )
519 {
520 return hdlr;
521 }
522
523 //------------------------------------------------------------------------
528 //------------------------------------------------------------------------
529 inline static ResponseHandler* Create( ResponseHandler &hdlr )
530 {
531 return &hdlr;
532 }
533
534 //------------------------------------------------------------------------
539 //------------------------------------------------------------------------
540 inline static ResponseHandler* Create( std::future<Response> &ftr )
541 {
542 return new FutureWrapper<Response>( ftr );
543 }
544 };
545
546 //----------------------------------------------------------------------------
551 //----------------------------------------------------------------------------
552 template<typename Response>
553 struct Resp: RespBase<Response>
554 {
555 //------------------------------------------------------------------------
560 //------------------------------------------------------------------------
561 inline static ResponseHandler* Create( std::function<void( XRootDStatus&,
562 Response& )> func )
563 {
564 return new FunctionWrapper<Response>( func );
565 }
566
567 //------------------------------------------------------------------------
572 //------------------------------------------------------------------------
573 template<typename Return>
574 inline static ResponseHandler* Create( std::packaged_task<Return( XRootDStatus&,
575 Response& )> &task )
576 {
577 return new TaskWrapper<Response, Return>( std::move( task ) );
578 }
579
580 //------------------------------------------------------------------------
582 //------------------------------------------------------------------------
584 };
585
586 //----------------------------------------------------------------------------
590 //----------------------------------------------------------------------------
591 template<>
592 struct Resp<void>: RespBase<void>
593 {
594 //------------------------------------------------------------------------
599 //------------------------------------------------------------------------
600 inline static ResponseHandler* Create( std::function<void( XRootDStatus& )> func )
601 {
602 return new SimpleFunctionWrapper( func );
603 }
604
605 //------------------------------------------------------------------------
610 //------------------------------------------------------------------------
611 template<typename Return>
612 inline static ResponseHandler* Create( std::packaged_task<Return( XRootDStatus& )> &task )
613 {
614 return new TaskWrapper<void, Return>( std::move( task ) );
615 }
616
617 //------------------------------------------------------------------------
619 //------------------------------------------------------------------------
621 };
622}
623
624#endif // __XRD_CL_OPERATIONS_HANDLERS_HH__
Definition: XrdClAnyObject.hh:33
void Get(Type &object)
Retrieve the object being held.
Definition: XrdClAnyObject.hh:78
Lambda wrapper.
Definition: XrdClOperationHandlers.hh:259
void HandleResponse(XRootDStatus *status, AnyObject *response)
Callback method.
Definition: XrdClOperationHandlers.hh:276
std::function< void(XRootDStatus &, StatInfo &)> fun
user defined function, functor or lambda
Definition: XrdClOperationHandlers.hh:295
File & f
Definition: XrdClOperationHandlers.hh:291
static StatInfo nullref
Null reference to the response (not really but acts as one)
Definition: XrdClOperationHandlers.hh:300
ExOpenFuncWrapper(File &f, std::function< void(XRootDStatus &, StatInfo &)> handleFunction)
Constructor.
Definition: XrdClOperationHandlers.hh:267
A file.
Definition: XrdClFile.hh:45
XRootDStatus Stat(bool force, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClOperationHandlers.hh:108
FunctionWrapper(std::function< void(XRootDStatus &, ResponseType &)> handleFunction)
Constructor.
Definition: XrdClOperationHandlers.hh:116
std::function< void(XRootDStatus &, ResponseType &)> fun
user defined function, functor or lambda
Definition: XrdClOperationHandlers.hh:142
void HandleResponse(XRootDStatus *status, AnyObject *response)
Callback method.
Definition: XrdClOperationHandlers.hh:125
static ResponseType nullref
Null reference to the response (not really but acts as one)
Definition: XrdClOperationHandlers.hh:147
Definition: XrdClOperationHandlers.hh:371
void SetException(const XRootDStatus &err)
Definition: XrdClOperationHandlers.hh:403
std::promise< Response > prms
promise that corresponds to the future
Definition: XrdClOperationHandlers.hh:412
~FutureWrapperBase()
Definition: XrdClOperationHandlers.hh:390
bool called
true if the handler has been called, false otherwise
Definition: XrdClOperationHandlers.hh:417
FutureWrapperBase(std::future< Response > &ftr)
Definition: XrdClOperationHandlers.hh:380
FutureWrapper(std::future< void > &ftr)
Definition: XrdClOperationHandlers.hh:476
void HandleResponse(XRootDStatus *status, AnyObject *response)
Callback method.
Definition: XrdClOperationHandlers.hh:484
Definition: XrdClOperationHandlers.hh:428
void HandleResponse(XRootDStatus *status, AnyObject *response)
Callback method.
Definition: XrdClOperationHandlers.hh:444
FutureWrapper(std::future< Response > &ftr)
Definition: XrdClOperationHandlers.hh:436
Pipeline exception, wrapps an XRootDStatus.
Definition: XrdClOperationHandlers.hh:312
const XRootDStatus & GetError() const
Definition: XrdClOperationHandlers.hh:351
PipelineException(const XRootDStatus &error)
Constructor from XRootDStatus.
Definition: XrdClOperationHandlers.hh:318
XRootDStatus error
the XRootDStatus associated with this exception
Definition: XrdClOperationHandlers.hh:361
PipelineException(const PipelineException &ex)
Copy constructor.
Definition: XrdClOperationHandlers.hh:326
PipelineException & operator=(const PipelineException &ex)
Assigment operator.
Definition: XrdClOperationHandlers.hh:334
const char * what() const noexcept
inherited from std::exception
Definition: XrdClOperationHandlers.hh:343
Handle an async response.
Definition: XrdClXRootDResponses.hh:855
Lambda wrapper.
Definition: XrdClOperationHandlers.hh:69
void HandleResponse(XRootDStatus *status, AnyObject *response)
Callback method.
Definition: XrdClOperationHandlers.hh:86
SimpleFunctionWrapper(std::function< void(XRootDStatus &)> handleFunction)
Constructor.
Definition: XrdClOperationHandlers.hh:77
std::function< void(XRootDStatus &)> fun
user defined function, functor or lambda
Definition: XrdClOperationHandlers.hh:98
Object stat info.
Definition: XrdClXRootDResponses.hh:333
Definition: XrdClOperationHandlers.hh:222
TaskWrapper(std::packaged_task< Return(XRootDStatus &)> &&task)
Constructor.
Definition: XrdClOperationHandlers.hh:230
std::packaged_task< Return(XRootDStatus &)> task
user defined task
Definition: XrdClOperationHandlers.hh:251
void HandleResponse(XRootDStatus *status, AnyObject *response)
Callback method.
Definition: XrdClOperationHandlers.hh:238
Definition: XrdClOperationHandlers.hh:165
static Response nullref
Null reference to the response (not really but acts as one)
Definition: XrdClOperationHandlers.hh:204
void HandleResponse(XRootDStatus *status, AnyObject *response)
Callback method.
Definition: XrdClOperationHandlers.hh:181
std::packaged_task< Return(XRootDStatus &, Response &)> task
user defined task
Definition: XrdClOperationHandlers.hh:199
TaskWrapper(std::packaged_task< Return(XRootDStatus &, Response &)> &&task)
Constructor.
Definition: XrdClOperationHandlers.hh:173
Request status.
Definition: XrdClXRootDResponses.hh:213
Definition: XrdClAnyObject.hh:26
const uint16_t stError
An error occurred that could potentially be retried.
Definition: XrdClStatus.hh:32
const uint16_t errPipelineFailed
Pipeline failed and operation couldn't be executed.
Definition: XrdClStatus.hh:65
Definition: XrdClOperationHandlers.hh:41
static constexpr bool value
Definition: XrdClOperationHandlers.hh:46
Definition: XrdClOperationHandlers.hh:511
static ResponseHandler * Create(ResponseHandler *hdlr)
Definition: XrdClOperationHandlers.hh:518
static ResponseHandler * Create(ResponseHandler &hdlr)
Definition: XrdClOperationHandlers.hh:529
static ResponseHandler * Create(std::future< Response > &ftr)
Definition: XrdClOperationHandlers.hh:540
static ResponseHandler * Create(std::packaged_task< Return(XRootDStatus &)> &task)
Definition: XrdClOperationHandlers.hh:612
static ResponseHandler * Create(std::function< void(XRootDStatus &)> func)
Definition: XrdClOperationHandlers.hh:600
Definition: XrdClOperationHandlers.hh:554
static ResponseHandler * Create(std::packaged_task< Return(XRootDStatus &, Response &)> &task)
Definition: XrdClOperationHandlers.hh:574
static ResponseHandler * Create(std::function< void(XRootDStatus &, Response &)> func)
Definition: XrdClOperationHandlers.hh:561
bool IsOK() const
We're fine.
Definition: XrdClStatus.hh:119
std::string ToString() const
Create a string representation.