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 
31 namespace 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:
291  File &f;
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__
XrdCl::RespBase
Definition: XrdClOperationHandlers.hh:510
XrdCl::RespBase::Create
static ResponseHandler * Create(ResponseHandler &hdlr)
Definition: XrdClOperationHandlers.hh:529
XrdCl::Resp
Definition: XrdClOperationHandlers.hh:553
XrdCl::ResponseHandler
Handle an async response.
Definition: XrdClXRootDResponses.hh:854
XrdCl::TaskWrapper< void, Return >::HandleResponse
void HandleResponse(XRootDStatus *status, AnyObject *response)
Callback method.
Definition: XrdClOperationHandlers.hh:238
XrdCl::PipelineException::GetError
const XRootDStatus & GetError() const
Definition: XrdClOperationHandlers.hh:351
XrdCl::FutureWrapperBase::called
bool called
true if the handler has been called, false otherwise
Definition: XrdClOperationHandlers.hh:417
XrdCl::RespBase::Create
static ResponseHandler * Create(std::future< Response > &ftr)
Definition: XrdClOperationHandlers.hh:540
XrdCl::Resp< void >::Create
static ResponseHandler * Create(std::packaged_task< Return(XRootDStatus &)> &task)
Definition: XrdClOperationHandlers.hh:612
XrdCl::TaskWrapper::task
std::packaged_task< Return(XRootDStatus &, Response &)> task
user defined task
Definition: XrdClOperationHandlers.hh:199
XrdCl::FunctionWrapper::nullref
static ResponseType nullref
Null reference to the response (not really but acts as one)
Definition: XrdClOperationHandlers.hh:147
XrdCl::FutureWrapperBase::prms
std::promise< Response > prms
promise that corresponds to the future
Definition: XrdClOperationHandlers.hh:412
XrdCl::FutureWrapperBase::SetException
void SetException(const XRootDStatus &err)
Definition: XrdClOperationHandlers.hh:403
XrdCl::Status::ToString
std::string ToString() const
Create a string representation.
XrdCl::FutureWrapperBase
Definition: XrdClOperationHandlers.hh:370
XrdCl::AnyObject::Get
void Get(Type &object)
Retrieve the object being held.
Definition: XrdClAnyObject.hh:78
XrdCl::FutureWrapperBase::~FutureWrapperBase
~FutureWrapperBase()
Definition: XrdClOperationHandlers.hh:390
XrdCl::TaskWrapper::TaskWrapper
TaskWrapper(std::packaged_task< Return(XRootDStatus &, Response &)> &&task)
Constructor.
Definition: XrdClOperationHandlers.hh:173
XrdCl::PipelineException::operator=
PipelineException & operator=(const PipelineException &ex)
Assigment operator.
Definition: XrdClOperationHandlers.hh:334
XrdCl::File
A file.
Definition: XrdClFile.hh:44
XrdCl::PipelineException
Pipeline exception, wrapps an XRootDStatus.
Definition: XrdClOperationHandlers.hh:311
XrdCl::FunctionWrapper::HandleResponse
void HandleResponse(XRootDStatus *status, AnyObject *response)
Callback method.
Definition: XrdClOperationHandlers.hh:125
XrdCl::ExOpenFuncWrapper::ExOpenFuncWrapper
ExOpenFuncWrapper(File &f, std::function< void(XRootDStatus &, StatInfo &)> handleFunction)
Constructor.
Definition: XrdClOperationHandlers.hh:267
XrdCl::SimpleFunctionWrapper::fun
std::function< void(XRootDStatus &)> fun
user defined function, functor or lambda
Definition: XrdClOperationHandlers.hh:98
XrdCl::FutureWrapper< void >::HandleResponse
void HandleResponse(XRootDStatus *status, AnyObject *response)
Callback method.
Definition: XrdClOperationHandlers.hh:484
XrdCl::TaskWrapper::nullref
static Response nullref
Null reference to the response (not really but acts as one)
Definition: XrdClOperationHandlers.hh:204
XrdCl::PipelineException::error
XRootDStatus error
the XRootDStatus associated with this exception
Definition: XrdClOperationHandlers.hh:361
XrdCl::ExOpenFuncWrapper::nullref
static StatInfo nullref
Null reference to the response (not really but acts as one)
Definition: XrdClOperationHandlers.hh:300
XrdCl::SimpleFunctionWrapper
Lambda wrapper.
Definition: XrdClOperationHandlers.hh:68
XrdCl::XRootDStatus
Request status.
Definition: XrdClXRootDResponses.hh:212
XrdCl::TaskWrapper< void, Return >::TaskWrapper
TaskWrapper(std::packaged_task< Return(XRootDStatus &)> &&task)
Constructor.
Definition: XrdClOperationHandlers.hh:230
XrdCl::TaskWrapper
Definition: XrdClOperationHandlers.hh:164
XrdCl::FunctionWrapper
Definition: XrdClOperationHandlers.hh:107
XrdCl::Resp::Create
static ResponseHandler * Create(std::packaged_task< Return(XRootDStatus &, Response &)> &task)
Definition: XrdClOperationHandlers.hh:574
XrdCl::ExOpenFuncWrapper::fun
std::function< void(XRootDStatus &, StatInfo &)> fun
user defined function, functor or lambda
Definition: XrdClOperationHandlers.hh:295
XrdCl::FutureWrapper::FutureWrapper
FutureWrapper(std::future< Response > &ftr)
Definition: XrdClOperationHandlers.hh:436
XrdCl::SimpleFunctionWrapper::HandleResponse
void HandleResponse(XRootDStatus *status, AnyObject *response)
Callback method.
Definition: XrdClOperationHandlers.hh:86
XrdCl::Resp< void >::Create
static ResponseHandler * Create(std::function< void(XRootDStatus &)> func)
Definition: XrdClOperationHandlers.hh:600
XrdCl::RespBase::Create
static ResponseHandler * Create(ResponseHandler *hdlr)
Definition: XrdClOperationHandlers.hh:518
XrdCl::PipelineException::PipelineException
PipelineException(const PipelineException &ex)
Copy constructor.
Definition: XrdClOperationHandlers.hh:326
XrdCl::Resp::Create
static ResponseHandler * Create(std::function< void(XRootDStatus &, Response &)> func)
Definition: XrdClOperationHandlers.hh:561
XrdCl::Status::IsOK
bool IsOK() const
We're fine.
Definition: XrdClStatus.hh:119
XrdClFile.hh
XrdCl::TaskWrapper< void, Return >::task
std::packaged_task< Return(XRootDStatus &)> task
user defined task
Definition: XrdClOperationHandlers.hh:251
XrdCl::FutureWrapper::HandleResponse
void HandleResponse(XRootDStatus *status, AnyObject *response)
Callback method.
Definition: XrdClOperationHandlers.hh:444
XrdCl::ExOpenFuncWrapper
Lambda wrapper.
Definition: XrdClOperationHandlers.hh:258
XrdCl
Definition: XrdClAnyObject.hh:25
XrdCl::ExOpenFuncWrapper::f
File & f
Definition: XrdClOperationHandlers.hh:291
XrdCl::ExOpenFuncWrapper::HandleResponse
void HandleResponse(XRootDStatus *status, AnyObject *response)
Callback method.
Definition: XrdClOperationHandlers.hh:276
XrdCl::File::Stat
XRootDStatus Stat(bool force, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XrdCl::FutureWrapperBase::FutureWrapperBase
FutureWrapperBase(std::future< Response > &ftr)
Definition: XrdClOperationHandlers.hh:380
XrdCl::FutureWrapper< void >::FutureWrapper
FutureWrapper(std::future< void > &ftr)
Definition: XrdClOperationHandlers.hh:476
XrdCl::stError
const uint16_t stError
An error occurred that could potentially be retried.
Definition: XrdClStatus.hh:32
XrdCl::StatInfo
Object stat info.
Definition: XrdClXRootDResponses.hh:332
XrdCl::SimpleFunctionWrapper::SimpleFunctionWrapper
SimpleFunctionWrapper(std::function< void(XRootDStatus &)> handleFunction)
Constructor.
Definition: XrdClOperationHandlers.hh:77
XrdCl::PipelineException::PipelineException
PipelineException(const XRootDStatus &error)
Constructor from XRootDStatus.
Definition: XrdClOperationHandlers.hh:318
XrdCl::IsResponseHandler::value
static constexpr bool value
Definition: XrdClOperationHandlers.hh:46
XrdCl::TaskWrapper< void, Return >
Definition: XrdClOperationHandlers.hh:221
XrdCl::AnyObject
Definition: XrdClAnyObject.hh:32
XrdCl::errPipelineFailed
const uint16_t errPipelineFailed
Pipeline failed and operation couldn't be executed.
Definition: XrdClStatus.hh:65
XrdCl::FunctionWrapper::fun
std::function< void(XRootDStatus &, ResponseType &)> fun
user defined function, functor or lambda
Definition: XrdClOperationHandlers.hh:142
XrdCl::FutureWrapper
Definition: XrdClOperationHandlers.hh:427
XrdCl::TaskWrapper::HandleResponse
void HandleResponse(XRootDStatus *status, AnyObject *response)
Callback method.
Definition: XrdClOperationHandlers.hh:181
XrdCl::IsResponseHandler
Definition: XrdClOperationHandlers.hh:40
XrdCl::PipelineException::what
const char * what() const noexcept
inherited from std::exception
Definition: XrdClOperationHandlers.hh:343
XrdCl::FunctionWrapper::FunctionWrapper
FunctionWrapper(std::function< void(XRootDStatus &, ResponseType &)> handleFunction)
Constructor.
Definition: XrdClOperationHandlers.hh:116