Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/xrootd/private/XrdCl/XrdClOperationHandlers.hh was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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