Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:15:36

0001 //------------------------------------------------------------------------------
0002 // Copyright (c) 2011-2017 by European Organization for Nuclear Research (CERN)
0003 // Author: Krzysztof Jamrog <krzysztof.piotr.jamrog@cern.ch>,
0004 //         Michal Simon <michal.simon@cern.ch>
0005 //------------------------------------------------------------------------------
0006 // This file is part of the XRootD software suite.
0007 //
0008 // XRootD is free software: you can redistribute it and/or modify
0009 // it under the terms of the GNU Lesser General Public License as published by
0010 // the Free Software Foundation, either version 3 of the License, or
0011 // (at your option) any later version.
0012 //
0013 // XRootD is distributed in the hope that it will be useful,
0014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
0015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0016 // GNU General Public License for more details.
0017 //
0018 // You should have received a copy of the GNU Lesser General Public License
0019 // along with XRootD.  If not, see <http://www.gnu.org/licenses/>.
0020 //
0021 // In applying this licence, CERN does not waive the privileges and immunities
0022 // granted to it by virtue of its status as an Intergovernmental Organization
0023 // or submit itself to any jurisdiction.
0024 //------------------------------------------------------------------------------
0025 
0026 #ifndef __XRD_CL_OPERATION_HANDLERS_HH__
0027 #define __XRD_CL_OPERATION_HANDLERS_HH__
0028 
0029 #include "XrdCl/XrdClFile.hh"
0030 #include "XrdCl/XrdClCtx.hh"
0031 
0032 #include<functional>
0033 #include<future>
0034 #include <memory>
0035 
0036 namespace XrdCl
0037 {
0038   //----------------------------------------------------------------------------
0039   //! Helper class for unpacking single XAttrStatus from bulk response
0040   //----------------------------------------------------------------------------
0041   class UnpackXAttrStatus : public ResponseHandler
0042   {
0043     public:
0044 
0045       UnpackXAttrStatus( ResponseHandler *handler ) : handler( handler )
0046       {
0047       }
0048 
0049       //------------------------------------------------------------------------
0050       //! Callback method.
0051       //------------------------------------------------------------------------
0052       void HandleResponse( XRootDStatus *status, AnyObject *response )
0053       {
0054         // status maybe error for old servers not supporting xattrs
0055         if( !status->IsOK() )
0056         {
0057           handler->HandleResponse( status, nullptr );
0058           return;
0059         }
0060 
0061         std::vector<XAttrStatus> *bulk = nullptr;
0062         response->Get( bulk );
0063         *status = bulk->front().status;
0064         handler->HandleResponse( status, nullptr );
0065         delete response;
0066       }
0067 
0068     private:
0069 
0070       ResponseHandler *handler;
0071   };
0072 
0073   //----------------------------------------------------------------------------
0074   //! Helper class for unpacking single XAttr from bulk response
0075   //----------------------------------------------------------------------------
0076   class UnpackXAttr : public ResponseHandler
0077   {
0078     public:
0079 
0080       UnpackXAttr( ResponseHandler *handler ) : handler( handler )
0081       {
0082       }
0083 
0084       //------------------------------------------------------------------------
0085       //! Callback method.
0086       //------------------------------------------------------------------------
0087       void HandleResponse( XRootDStatus *status, AnyObject *response )
0088       {
0089         // status is always OK for bulk response
0090 
0091         std::vector<XAttr> *bulk = nullptr;
0092         response->Get( bulk );
0093         *status = bulk->front().status;
0094         std::string *rsp = new std::string( std::move( bulk->front().value ) );
0095         delete bulk;
0096         response->Set( rsp );
0097         handler->HandleResponse( status, response );
0098       }
0099 
0100     private:
0101 
0102       ResponseHandler *handler;
0103   };
0104 
0105   //----------------------------------------------------------------------------
0106   // Helper class for creating null references for particular types
0107   //
0108   // @arg Response : type for which we need a null reference
0109   //----------------------------------------------------------------------------
0110   template<typename Response>
0111   struct NullRef
0112   {
0113       static Response value;
0114   };
0115 
0116   //----------------------------------------------------------------------------
0117   // Initialize the 'null-reference'
0118   //----------------------------------------------------------------------------
0119   template<typename Response>
0120   Response NullRef<Response>::value;
0121 
0122   //----------------------------------------------------------------------------
0123   //! Unpack response
0124   //!
0125   //! @param rsp : AnyObject holding response
0126   //! @return    : the response
0127   //----------------------------------------------------------------------------
0128   template<typename Response>
0129   inline Response* GetResponse( AnyObject *rsp )
0130   {
0131     Response *ret = nullptr;
0132     rsp->Get( ret );
0133     return ret;
0134   }
0135 
0136   //----------------------------------------------------------------------------
0137   //! Unpack response
0138   //!
0139   //! @param rsp    : AnyObject holding response
0140   //! @param status :
0141   //! @return       : the response
0142   //----------------------------------------------------------------------------
0143   template<typename Response>
0144   inline Response* GetResponse( XRootDStatus *status, AnyObject *rsp )
0145   {
0146     if( !status->IsOK() ) return &NullRef<Response>::value;
0147     return GetResponse<Response>( rsp );
0148   }
0149 
0150   //----------------------------------------------------------------------------
0151   //! Lambda wrapper
0152   //!
0153   //! @arg ResponseType : type of response returned by the server
0154   //----------------------------------------------------------------------------
0155   template<typename Response>
0156   class FunctionWrapper: public ResponseHandler
0157   {
0158     public:
0159 
0160       //------------------------------------------------------------------------
0161       //! Constructor.
0162       //
0163       //! @param func : function, functor or lambda (2 arguments)
0164       //------------------------------------------------------------------------
0165       FunctionWrapper(
0166           std::function<void( XRootDStatus&, Response& )> handleFunction ) :
0167           fun( [handleFunction]( XRootDStatus &s, Response &r, HostList& ){ handleFunction( s, r ); } )
0168       {
0169       }
0170 
0171       //------------------------------------------------------------------------
0172       //! Constructor.
0173       //
0174       //! @param func : function, functor or lambda (3 arguments)
0175       //------------------------------------------------------------------------
0176       FunctionWrapper(
0177           std::function<void( XRootDStatus&, Response&, HostList& )> handleFunction ) :
0178           fun( handleFunction )
0179       {
0180       }
0181 
0182       //------------------------------------------------------------------------
0183       //! Callback method.
0184       //------------------------------------------------------------------------
0185       void HandleResponseWithHosts( XRootDStatus *status, AnyObject *response, HostList *hostList )
0186       {
0187         std::unique_ptr<XRootDStatus> delst( status );
0188         std::unique_ptr<AnyObject> delrsp( response );
0189         std::unique_ptr<HostList> delhl( hostList );
0190         Response *res = GetResponse<Response>( status, response );
0191         fun( *status, *res, *hostList );
0192       }
0193 
0194     private:
0195       //------------------------------------------------------------------------
0196       //! user defined function, functor or lambda
0197       //------------------------------------------------------------------------
0198       std::function<void( XRootDStatus&, Response&, HostList& )> fun;
0199   };
0200 
0201   //----------------------------------------------------------------------------
0202   //! Lambda wrapper
0203   //!
0204   //! Template specialization for responses that return no value (void)
0205   //----------------------------------------------------------------------------
0206   template<>
0207   class FunctionWrapper<void> : public ResponseHandler
0208   {
0209     public:
0210 
0211       //------------------------------------------------------------------------
0212       //! Constructor.
0213       //
0214       //! @param func : function, functor or lambda (1 argument)
0215       //------------------------------------------------------------------------
0216       FunctionWrapper(
0217           std::function<void( XRootDStatus& )> handleFunction ) :
0218           fun( [handleFunction]( XRootDStatus& s, HostList& ){ handleFunction( s ); } )
0219       {
0220       }
0221 
0222       //------------------------------------------------------------------------
0223       //! Constructor.
0224       //
0225       //! @param func : function, functor or lambda (2 arguments)
0226       //------------------------------------------------------------------------
0227       FunctionWrapper(
0228           std::function<void( XRootDStatus&, HostList& )> handleFunction ) :
0229           fun( handleFunction )
0230       {
0231       }
0232 
0233       //------------------------------------------------------------------------
0234       //! Callback method.
0235       //------------------------------------------------------------------------
0236       void HandleResponseWithHosts( XRootDStatus *status, AnyObject *response, HostList *hostList )
0237       {
0238         std::unique_ptr<XRootDStatus> delst( status );
0239         std::unique_ptr<AnyObject> delrsp( response );
0240         std::unique_ptr<HostList> delhl( hostList );
0241         fun( *status, *hostList );
0242       }
0243 
0244     private:
0245       //------------------------------------------------------------------------
0246       //! user defined function, functor or lambda
0247       //------------------------------------------------------------------------
0248       std::function<void( XRootDStatus&, HostList& )> fun;
0249   };
0250 
0251   //----------------------------------------------------------------------------
0252   //! Packaged Task wrapper
0253   //!
0254   //! @arg Response : type of response returned by the server
0255   //! @arg Return   : type of the value returned by the task
0256   //----------------------------------------------------------------------------
0257   template<typename Response, typename Return>
0258   class TaskWrapper: public ResponseHandler
0259   {
0260     public:
0261 
0262       //------------------------------------------------------------------------
0263       //! Constructor.
0264       //
0265       //! @param task : a std::packaged_task
0266       //------------------------------------------------------------------------
0267       TaskWrapper( std::packaged_task<Return( XRootDStatus&, Response& )> && task ) :
0268         task( std::move( task ) )
0269       {
0270       }
0271 
0272       //------------------------------------------------------------------------
0273       //! Callback method.
0274       //------------------------------------------------------------------------
0275       void HandleResponse( XRootDStatus *status, AnyObject *response )
0276       {
0277         std::unique_ptr<XRootDStatus> delst( status );
0278         std::unique_ptr<AnyObject> delrsp( response );
0279         Response *resp = GetResponse<Response>( status, response );
0280         task( *status, *resp );
0281       }
0282 
0283     private:
0284 
0285       //------------------------------------------------------------------------
0286       //! user defined task
0287       //------------------------------------------------------------------------
0288       std::packaged_task<Return( XRootDStatus&, Response& )> task;
0289   };
0290 
0291   //----------------------------------------------------------------------------
0292   //! Packaged Task wrapper, specialization for requests that have no response
0293   //! except for status.
0294   //!
0295   //! @arg Response : type of response returned by the server
0296   //! @arg Return   : type of the value returned by the task
0297   //----------------------------------------------------------------------------
0298   template<typename Return>
0299   class TaskWrapper<void, Return>: public ResponseHandler
0300   {
0301     public:
0302 
0303       //------------------------------------------------------------------------
0304       //! Constructor.
0305       //
0306       //! @param task : a std::packaged_task
0307       //------------------------------------------------------------------------
0308       TaskWrapper( std::packaged_task<Return( XRootDStatus& )> && task ) :
0309         task( std::move( task ) )
0310       {
0311       }
0312 
0313       //------------------------------------------------------------------------
0314       //! Callback method.
0315       //------------------------------------------------------------------------
0316       void HandleResponse( XRootDStatus *status, AnyObject *response )
0317       {
0318         std::unique_ptr<XRootDStatus> delst( status );
0319         std::unique_ptr<AnyObject> delrsp( response );
0320         task( *status );
0321       }
0322 
0323     private:
0324 
0325       //------------------------------------------------------------------------
0326       //! user defined task
0327       //------------------------------------------------------------------------
0328       std::packaged_task<Return( XRootDStatus& )> task;
0329   };
0330 
0331 
0332   //----------------------------------------------------------------------------
0333   //! Lambda wrapper
0334   //----------------------------------------------------------------------------
0335   class ExOpenFuncWrapper: public ResponseHandler
0336   {
0337     public:
0338 
0339       //------------------------------------------------------------------------
0340       //! Constructor.
0341       //
0342       //! @param func : function, functor or lambda (2 arguments)
0343       //------------------------------------------------------------------------
0344       ExOpenFuncWrapper( const Ctx<File> &f,
0345           std::function<void( XRootDStatus&, StatInfo& )> handleFunction ) :
0346           f( f ), fun( [handleFunction]( XRootDStatus &s, StatInfo &i, HostList& ){ handleFunction( s, i ); } )
0347       {
0348       }
0349 
0350       //------------------------------------------------------------------------
0351       //! Constructor.
0352       //
0353       //! @param func : function, functor or lambda (3 arguments)
0354       //------------------------------------------------------------------------
0355       ExOpenFuncWrapper( const Ctx<File> &f,
0356           std::function<void( XRootDStatus&, StatInfo&, HostList& )> handleFunction ) :
0357           f( f ), fun( handleFunction )
0358       {
0359       }
0360 
0361       //------------------------------------------------------------------------
0362       //! Callback method.
0363       //------------------------------------------------------------------------
0364       void HandleResponseWithHosts( XRootDStatus *status, AnyObject *response, HostList *hostList )
0365       {
0366         delete response;
0367         std::unique_ptr<XRootDStatus> delst( status );
0368         std::unique_ptr<StatInfo> delrsp;
0369         std::unique_ptr<HostList> delhl;
0370         StatInfo *info = nullptr;
0371         if( status->IsOK() )
0372         {
0373           XRootDStatus st = f->Stat( false, info );
0374           delrsp.reset( info );
0375         }
0376         else
0377           info = &NullRef<StatInfo>::value;
0378         fun( *status, *info, *hostList );
0379       }
0380 
0381     private:
0382       Ctx<File> f;
0383       //------------------------------------------------------------------------
0384       //! user defined function, functor or lambda
0385       //------------------------------------------------------------------------
0386       std::function<void( XRootDStatus&, StatInfo&, HostList& )> fun;
0387   };
0388 
0389   //----------------------------------------------------------------------------
0390   //! Pipeline exception, wrapps an XRootDStatus
0391   //----------------------------------------------------------------------------
0392   class PipelineException : public std::exception
0393   {
0394     public:
0395 
0396       //------------------------------------------------------------------------
0397       //! Constructor from XRootDStatus
0398       //------------------------------------------------------------------------
0399       PipelineException( const XRootDStatus &error ) : error( error ), strerr( error.ToString() )
0400       {
0401 
0402       }
0403 
0404       //------------------------------------------------------------------------
0405       //! Copy constructor.
0406       //------------------------------------------------------------------------
0407       PipelineException( const PipelineException &ex ) : error( ex.error ), strerr( ex.error.ToString() )
0408       {
0409 
0410       }
0411 
0412       //------------------------------------------------------------------------
0413       //! Assigment operator
0414       //------------------------------------------------------------------------
0415       PipelineException& operator=( const PipelineException &ex )
0416       {
0417         error  = ex.error;
0418         strerr = ex.strerr;
0419         return *this;
0420       }
0421 
0422       //------------------------------------------------------------------------
0423       //! inherited from std::exception
0424       //------------------------------------------------------------------------
0425       const char* what() const noexcept
0426       {
0427         return strerr.c_str();
0428       }
0429 
0430       //------------------------------------------------------------------------
0431       //! @return : the XRootDStatus
0432       //------------------------------------------------------------------------
0433       const XRootDStatus& GetError() const
0434       {
0435         return error;
0436       }
0437 
0438     private:
0439 
0440       //------------------------------------------------------------------------
0441       //! the XRootDStatus associated with this exception
0442       //------------------------------------------------------------------------
0443       XRootDStatus error;
0444       std::string  strerr;
0445   };
0446 
0447   //----------------------------------------------------------------------------
0448   //! A wrapper handler for a std::promise / std::future.
0449   //!
0450   //! @arg Response : response type
0451   //----------------------------------------------------------------------------
0452   template<typename Response>
0453   class FutureWrapperBase : public ResponseHandler
0454   {
0455     public:
0456 
0457       //------------------------------------------------------------------------
0458       //! Constructor, initializes the std::future argument from its
0459       //! own std::promise
0460       //!
0461       //! @param ftr : the future to be linked with this handler
0462       //------------------------------------------------------------------------
0463       FutureWrapperBase( std::future<Response> &ftr ) : fulfilled( false )
0464       {
0465         ftr = prms.get_future();
0466       }
0467 
0468       //------------------------------------------------------------------------
0469       //! Destructor
0470       //------------------------------------------------------------------------
0471       virtual ~FutureWrapperBase()
0472       {
0473         if( !fulfilled ) SetException( XRootDStatus( stError, errPipelineFailed ) );
0474       }
0475 
0476     protected:
0477 
0478       //------------------------------------------------------------------------
0479       //! Set exception in the std::promise / std::future
0480       //!
0481       //! @param err : the error
0482       //------------------------------------------------------------------------
0483       inline void SetException( const XRootDStatus &err )
0484       {
0485         std::exception_ptr ex = std::make_exception_ptr( PipelineException( err ) );
0486         prms.set_exception( ex );
0487         fulfilled = true;
0488       }
0489 
0490       //------------------------------------------------------------------------
0491       //! promise that corresponds to the future
0492       //------------------------------------------------------------------------
0493       std::promise<Response> prms;
0494       bool                   fulfilled;
0495   };
0496 
0497   //----------------------------------------------------------------------------
0498   //! A wrapper handler for a std::promise / std::future.
0499   //!
0500   //! @arg Response : response type
0501   //----------------------------------------------------------------------------
0502   template<typename Response>
0503   class FutureWrapper : public FutureWrapperBase<Response>
0504   {
0505     public:
0506 
0507       //------------------------------------------------------------------------
0508       //! Constructor, @see FutureWrapperBase
0509       //!
0510       //! @param ftr : the future to be linked with this handler
0511       //------------------------------------------------------------------------
0512       FutureWrapper( std::future<Response> &ftr ) : FutureWrapperBase<Response>( ftr )
0513       {
0514       }
0515 
0516       //------------------------------------------------------------------------
0517       //! Callback method.
0518       //------------------------------------------------------------------------
0519       void HandleResponse( XRootDStatus *status, AnyObject *response )
0520       {
0521         std::unique_ptr<XRootDStatus> delst( status );
0522         std::unique_ptr<AnyObject> delrsp( response );
0523         if( status->IsOK() )
0524         {
0525           Response *resp = GetResponse<Response>( response );
0526           if( resp == &NullRef<Response>::value )
0527             this->SetException( XRootDStatus( stError, errInternal ) );
0528           else
0529           {
0530             this->prms.set_value( std::move( *resp ) );
0531             this->fulfilled = true;
0532           }
0533         }
0534         else
0535           this->SetException( *status );
0536       }
0537   };
0538 
0539   //----------------------------------------------------------------------------
0540   //! A wrapper handler for a std::promise / std::future, overload for void type
0541   //----------------------------------------------------------------------------
0542   template<>
0543   class FutureWrapper<void> : public FutureWrapperBase<void>
0544   {
0545     public:
0546 
0547       //------------------------------------------------------------------------
0548       //! Constructor, @see FutureWrapperBase
0549       //!
0550       //! @param ftr : the future to be linked with this handler
0551       //------------------------------------------------------------------------
0552       FutureWrapper( std::future<void> &ftr ) : FutureWrapperBase<void>( ftr )
0553       {
0554       }
0555 
0556       //------------------------------------------------------------------------
0557       //! Callback method.
0558       //------------------------------------------------------------------------
0559       void HandleResponse( XRootDStatus *status, AnyObject *response )
0560       {
0561         std::unique_ptr<XRootDStatus> delst( status );
0562         std::unique_ptr<AnyObject> delrsp( response );
0563         if( status->IsOK() )
0564         {
0565           prms.set_value();
0566           fulfilled = true;
0567         }
0568         else
0569           SetException( *status );
0570       }
0571   };
0572 
0573 
0574   //----------------------------------------------------------------------------
0575   //! Wrapper class for raw response handler (ResponseHandler).
0576   //----------------------------------------------------------------------------
0577   class RawWrapper : public ResponseHandler
0578   {
0579     public:
0580 
0581       //------------------------------------------------------------------------
0582       //! Constructor
0583       //!
0584       //! @param handler : the actual operation handler
0585       //------------------------------------------------------------------------
0586       RawWrapper( ResponseHandler *handler ) : handler( handler )
0587       {
0588       }
0589 
0590       //------------------------------------------------------------------------
0591       //! Callback method (@see ResponseHandler)
0592       //!
0593       //! Note: does not delete itself because it is assumed that it is owned
0594       //!       by the PipelineHandler (@see PipelineHandler)
0595       //------------------------------------------------------------------------
0596       virtual void HandleResponseWithHosts( XRootDStatus *status,
0597                                             AnyObject    *response,
0598                                             HostList     *hostList )
0599       {
0600         handler->HandleResponseWithHosts( status, response, hostList );
0601       }
0602 
0603     private:
0604       //------------------------------------------------------------------------
0605       //! The actual operation handler (we don't own the pointer)
0606       //------------------------------------------------------------------------
0607       ResponseHandler *handler;
0608   };
0609 
0610 
0611   //----------------------------------------------------------------------------
0612   //! A base class for factories, creates ForwardingHandlers from
0613   //! ResponseHandler*, ResponseHandler& and std::future<Response>
0614   //!
0615   //! @arg Response : response type
0616   //----------------------------------------------------------------------------
0617   template<typename Response>
0618   struct RespBase
0619   {
0620       //------------------------------------------------------------------------
0621       //!  A factory method, simply forwards the given handler
0622       //!
0623       //! @param hdlr : the ResponseHandler that should be wrapped
0624       //! @return     : a ForwardingHandler instance
0625       //------------------------------------------------------------------------
0626       inline static ResponseHandler* Create( ResponseHandler *hdlr )
0627       {
0628         return new RawWrapper( hdlr );
0629       }
0630 
0631       //------------------------------------------------------------------------
0632       //!  A factory method, simply forwards the given handler
0633       //!
0634       //! @param hdlr : the ResponseHandler that should be wrapped
0635       //! @return     : a ForwardingHandler instance
0636       //------------------------------------------------------------------------
0637       inline static ResponseHandler* Create( ResponseHandler &hdlr )
0638       {
0639         return new RawWrapper( &hdlr );
0640       }
0641 
0642       //------------------------------------------------------------------------
0643       //! A factory method
0644       //!
0645       //! @arg   Response : response type
0646       //! @param ftr      : the std::future that should be wrapped
0647       //------------------------------------------------------------------------
0648       inline static ResponseHandler* Create( std::future<Response> &ftr )
0649       {
0650         return new FutureWrapper<Response>( ftr );
0651       }
0652   };
0653 
0654   //----------------------------------------------------------------------------
0655   //! Factory class, creates ForwardingHandler from std::function, in addition
0656   //! to what RespBase provides (@see RespBase)
0657   //!
0658   //! @arg Response : response type
0659   //----------------------------------------------------------------------------
0660   template<typename Response>
0661   struct Resp: RespBase<Response>
0662   {
0663       //------------------------------------------------------------------------
0664       //! A factory method
0665       //!
0666       //! @param func : the function/functor/lambda that should be wrapped
0667       //! @return     : FunctionWrapper instance
0668       //------------------------------------------------------------------------
0669       inline static ResponseHandler* Create( std::function<void( XRootDStatus&,
0670           Response& )> func )
0671       {
0672         return new FunctionWrapper<Response>( func );
0673       }
0674 
0675       //------------------------------------------------------------------------
0676       //! A factory method
0677       //!
0678       //! @param func : the function/functor/lambda that should be wrapped
0679       //! @return     : FunctionWrapper instance
0680       //------------------------------------------------------------------------
0681       inline static ResponseHandler* Create( std::function<void( XRootDStatus&,
0682           Response&, HostList& )> func )
0683       {
0684         return new FunctionWrapper<Response>( func );
0685       }
0686 
0687       //------------------------------------------------------------------------
0688       //! A factory method
0689       //!
0690       //! @param task : the task that should be wrapped
0691       //! @return     : TaskWrapper instance
0692       //------------------------------------------------------------------------
0693       template<typename Return>
0694       inline static ResponseHandler* Create( std::packaged_task<Return( XRootDStatus&,
0695           Response& )> &task )
0696       {
0697         return new TaskWrapper<Response, Return>( std::move( task ) );
0698       }
0699 
0700       //------------------------------------------------------------------------
0701       //! Make the Create overloads from RespBase visible
0702       //------------------------------------------------------------------------
0703       using RespBase<Response>::Create;
0704   };
0705 
0706   //----------------------------------------------------------------------------
0707   //! Factory class, overloads Resp for void type
0708   //!
0709   //! @arg Response : response type
0710   //----------------------------------------------------------------------------
0711   template<>
0712   struct Resp<void>: RespBase<void>
0713   {
0714       //------------------------------------------------------------------------
0715       //! A factory method
0716       //!
0717       //! @param func : the function/functor/lambda that should be wrapped
0718       //! @return     : SimpleFunctionWrapper instance
0719       //------------------------------------------------------------------------
0720       inline static ResponseHandler* Create( std::function<void( XRootDStatus& )> func )
0721       {
0722         return new FunctionWrapper<void>( func );
0723       }
0724 
0725       //------------------------------------------------------------------------
0726       //! A factory method
0727       //!
0728       //! @param func : the function/functor/lambda that should be wrapped
0729       //! @return     : SimpleFunctionWrapper instance
0730       //------------------------------------------------------------------------
0731       inline static ResponseHandler* Create( std::function<void( XRootDStatus&, HostList& )> func )
0732       {
0733         return new FunctionWrapper<void>( func );
0734       }
0735 
0736       //------------------------------------------------------------------------
0737       //! A factory method
0738       //!
0739       //! @param task : the task that should be wrapped
0740       //! @return     : TaskWrapper instance
0741       //------------------------------------------------------------------------
0742       template<typename Return>
0743       inline static ResponseHandler* Create( std::packaged_task<Return( XRootDStatus& )> &task )
0744       {
0745         return new TaskWrapper<void, Return>( std::move( task ) );
0746       }
0747 
0748       //------------------------------------------------------------------------
0749       //! Make the Create overloads from RespBase visible
0750       //------------------------------------------------------------------------
0751       using RespBase<void>::Create;
0752   };
0753 }
0754 
0755 #endif // __XRD_CL_OPERATIONS_HANDLERS_HH__