|
||||
File indexing completed on 2025-01-18 10:15:37
0001 //------------------------------------------------------------------------------ 0002 // Copyright (c) 2011-2014 by European Organization for Nuclear Research (CERN) 0003 // Author: Michal Simon <michal.simon@cern.ch> 0004 //------------------------------------------------------------------------------ 0005 // This file is part of the XRootD software suite. 0006 // 0007 // XRootD is free software: you can redistribute it and/or modify 0008 // it under the terms of the GNU Lesser General Public License as published by 0009 // the Free Software Foundation, either version 3 of the License, or 0010 // (at your option) any later version. 0011 // 0012 // XRootD is distributed in the hope that it will be useful, 0013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0015 // GNU General Public License for more details. 0016 // 0017 // You should have received a copy of the GNU Lesser General Public License 0018 // along with XRootD. If not, see <http://www.gnu.org/licenses/>. 0019 // 0020 // In applying this licence, CERN does not waive the privileges and immunities 0021 // granted to it by virtue of its status as an Intergovernmental Organization 0022 // or submit itself to any jurisdiction. 0023 //------------------------------------------------------------------------------ 0024 0025 #include "XrdCl/XrdClJobManager.hh" 0026 0027 #include <future> 0028 #include <type_traits> 0029 0030 #ifndef SRC_XRDEC_XRDECTHREADPOOL_HH_ 0031 #define SRC_XRDEC_XRDECTHREADPOOL_HH_ 0032 0033 namespace XrdEc 0034 { 0035 //--------------------------------------------------------------------------- 0036 // A theread pool class for the XrdEc module 0037 //--------------------------------------------------------------------------- 0038 class ThreadPool 0039 { 0040 private: 0041 0042 // This is the type which holds sequences 0043 template<int ... Is> struct sequence {}; 0044 0045 // First define the template signature 0046 template <int ... Ns> struct seq_gen; 0047 0048 // Recursion case 0049 template <int I, int ... Ns> 0050 struct seq_gen<I, Ns...> 0051 { 0052 using type = typename seq_gen<I - 1, I - 1, Ns...>::type; 0053 }; 0054 0055 // Recursion abort 0056 template <int ... Ns> 0057 struct seq_gen<0, Ns...> 0058 { 0059 using type = sequence<Ns...>; 0060 }; 0061 0062 // call functional with arguments in a tuple (implementation) 0063 template <typename FUNC, typename TUPL, int ... INDICES> 0064 inline static auto tuple_call_impl( FUNC &func, TUPL &args, sequence<INDICES...> ) -> decltype( func( std::move( std::get<INDICES>( args ) )... ) ) 0065 { 0066 return func( std::move( std::get<INDICES>( args ) )... ); 0067 } 0068 0069 // call functional with argumetns packaged in a tuple 0070 template <typename FUNC, typename ... ARGs> 0071 inline static auto tuple_call( FUNC &func, std::tuple<ARGs...> &tup ) ->decltype( tuple_call_impl( func, tup, typename seq_gen<sizeof...(ARGs)>::type{} ) ) 0072 { 0073 return tuple_call_impl( func, tup, typename seq_gen<sizeof...(ARGs)>::type{} ); 0074 } 0075 0076 //----------------------------------------------------------------------- 0077 // Helper class implementing a job containing any functional and its 0078 // arguments. 0079 //----------------------------------------------------------------------- 0080 template<typename FUNC, typename RET, typename ... ARGs> 0081 class AnyJob : public XrdCl::Job 0082 { 0083 //--------------------------------------------------------------------- 0084 // Run the functional (returning void) with the packaged arguments 0085 //--------------------------------------------------------------------- 0086 static inline void RunImpl( FUNC func, std::tuple<ARGs...> &args, std::promise<void> &prms ) 0087 { 0088 tuple_call( func, args ); 0089 prms.set_value(); 0090 } 0091 0092 //--------------------------------------------------------------------- 0093 // Run the functional (returning anything but void) with the packaged 0094 // arguments 0095 //--------------------------------------------------------------------- 0096 template<typename RETURN> 0097 static inline void RunImpl( FUNC func, std::tuple<ARGs...> &args, std::promise<RETURN> &prms ) 0098 { 0099 prms.set_value( tuple_call( func, args ) ); 0100 } 0101 0102 public: 0103 //------------------------------------------------------------------- 0104 //! Constructor 0105 //! 0106 //! @param func : functional to be called 0107 //! @param args : arguments for the functional 0108 //------------------------------------------------------------------- 0109 AnyJob( FUNC func, ARGs... args ) : func( std::move( func ) ), 0110 args( std::tuple<ARGs...>( std::move( args )... ) ) 0111 { 0112 } 0113 0114 //------------------------------------------------------------------- 0115 //! Run the job 0116 //------------------------------------------------------------------- 0117 void Run( void *arg ) 0118 { 0119 RunImpl( this->func, this->args, this->prms ); 0120 delete this; 0121 } 0122 0123 //------------------------------------------------------------------- 0124 //! Get the future result of the job 0125 //------------------------------------------------------------------- 0126 std::future<RET> GetFuture() 0127 { 0128 return prms.get_future(); 0129 } 0130 0131 protected: 0132 0133 FUNC func; //< the functional 0134 std::tuple<ARGs...> args; //< the arguments 0135 std::promise<RET> prms; //< the promiss that there will be a result 0136 }; 0137 0138 public: 0139 0140 //----------------------------------------------------------------------- 0141 //! Destructor 0142 //----------------------------------------------------------------------- 0143 ~ThreadPool() 0144 { 0145 threadpool.Stop(); 0146 threadpool.Finalize(); 0147 } 0148 0149 //----------------------------------------------------------------------- 0150 //! Singleton access 0151 //----------------------------------------------------------------------- 0152 static ThreadPool& Instance() 0153 { 0154 static ThreadPool instance; 0155 return instance; 0156 } 0157 0158 //----------------------------------------------------------------------- 0159 //! Schedule a functional (together with its arguments) for execution 0160 //----------------------------------------------------------------------- 0161 template<typename FUNC, typename ... ARGs> 0162 inline std::future<std::invoke_result_t<FUNC, ARGs...>> 0163 Execute( FUNC func, ARGs... args ) 0164 { 0165 using RET = std::invoke_result_t<FUNC, ARGs...>; 0166 auto *job = new AnyJob<FUNC, RET, ARGs...>( func, std::move( args )... ); 0167 std::future<RET> ftr = job->GetFuture(); 0168 threadpool.QueueJob( job, nullptr ); 0169 return ftr; 0170 } 0171 0172 private: 0173 0174 //----------------------------------------------------------------------- 0175 //! Constructor 0176 //----------------------------------------------------------------------- 0177 ThreadPool() : threadpool( 64 ) 0178 { 0179 threadpool.Initialize(); 0180 threadpool.Start(); 0181 } 0182 0183 XrdCl::JobManager threadpool; //< the thread-pool itself 0184 }; 0185 0186 } 0187 0188 0189 #endif /* SRC_XRDEC_XRDECTHREADPOOL_HH_ */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |