diff --git a/example/executor.cpp b/example/executor.cpp index 8d1f0392..7316370e 100644 --- a/example/executor.cpp +++ b/example/executor.cpp @@ -4,29 +4,42 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #define BOOST_THREAD_VERSION 4 -#define BOOST_THREAD_USES_LOG +#define BOOST_THREAD_PROVIDES_EXECUTORS #define BOOST_THREAD_USES_LOG_THREAD_ID -#include #include #include #include +#include #include #include +#include void p1() { - BOOST_THREAD_LOG - << boost::this_thread::get_id() << " P1" << BOOST_THREAD_END_LOG; + std::cout << BOOST_CONTEXTOF << std::endl; } void p2() { - BOOST_THREAD_LOG - << boost::this_thread::get_id() << " P2" << BOOST_THREAD_END_LOG; + std::cout << BOOST_CONTEXTOF << std::endl; } -void submit_some(boost::executor& tp) { +int f1() +{ + std::cout << BOOST_CONTEXTOF << std::endl; + boost::this_thread::sleep_for(boost::chrono::seconds(1)); + return 1; +} +int f2(int i) +{ + std::cout << BOOST_CONTEXTOF << std::endl; + boost::this_thread::sleep_for(boost::chrono::seconds(2)); + return i + 1; +} + +void submit_some(boost::executor& tp) +{ tp.submit(&p1); tp.submit(&p2); tp.submit(&p1); @@ -41,13 +54,29 @@ void submit_some(boost::executor& tp) { int main() { - BOOST_THREAD_LOG - << boost::this_thread::get_id() << " ea; submit_some(ea); + { + boost::future t1 = boost::async(ea, &f1); + boost::future t2 = boost::async(ea, &f1); + std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl; + std::cout << BOOST_CONTEXTOF << " t2= " << t2.get() << std::endl; + } + submit_some(ea); + { + boost::thread_pool ea3(1); + boost::future t1 = boost::async(ea3, &f1); + boost::future t2 = boost::async(ea3, &f1); + //boost::future t2 = boost::async(ea3, f2, 1); // todo this doesn't compiles yet on C++11 + //boost::future t2 = boost::async(ea3, boost::bind(f2, 1)); // todo this doesn't compiles yet on C++98 + std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl; + std::cout << BOOST_CONTEXTOF << " t2= " << t2.get() << std::endl; + } + submit_some(ea); boost::executor_adaptor ea2; submit_some(ea2); @@ -56,18 +85,15 @@ int main() } catch (std::exception& ex) { - BOOST_THREAD_LOG - << "ERRORRRRR " << ex.what() << "" << BOOST_THREAD_END_LOG; + std::cout << "ERROR= " << ex.what() << "" << std::endl; return 1; } catch (...) { - BOOST_THREAD_LOG - << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + std::cout << " ERROR= exception thrown" << std::endl; return 2; } } - BOOST_THREAD_LOG - << boost::this_thread::get_id() << "MAIN>" << BOOST_THREAD_END_LOG; + std::cout << BOOST_CONTEXTOF << std::endl; return 0; } diff --git a/example/future_fallback_to.cpp b/example/future_fallback_to.cpp index 6b0b41ee..36536543 100644 --- a/example/future_fallback_to.cpp +++ b/example/future_fallback_to.cpp @@ -4,7 +4,7 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #define BOOST_THREAD_VERSION 4 -#define BOOST_THREAD_USES_LOG +//#define BOOST_THREAD_USES_LOG #define BOOST_THREAD_USES_LOG_THREAD_ID #include @@ -12,6 +12,7 @@ #include #include #include +#include #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION @@ -29,9 +30,10 @@ int p1() int main() { + const int number_of_tests = 100; BOOST_THREAD_LOG << " f1 = boost::async(boost::launch::async, &p1); @@ -45,17 +47,20 @@ int main() } catch (std::exception& ex) { + std::cout << "ERRORRRRR "< @@ -28,6 +28,7 @@ int p2(boost::future f) } catch (std::exception& ex) { + std::cout << "ERRORRRRR "< f) } catch (std::exception& ex) { + std::cout << "ERRORRRRR "< f) int main() { + const int number_of_tests = 100; BOOST_THREAD_LOG << " @@ -29,8 +29,9 @@ boost::future p2() int main() { + const int number_of_tests = 100; BOOST_THREAD_LOG << " > outer_future = boost::async(boost::launch::async, &p2); @@ -40,11 +41,13 @@ int main() } catch (std::exception& ex) { + std::cout << "ERRORRRRR "< @@ -20,11 +20,13 @@ #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION \ && ! defined BOOST_NO_CXX11_LAMBDAS + int main() { + const int number_of_tests = 100; BOOST_THREAD_LOG << " shared_compute(int x) int main() { - for (int i=0; i< 10; i++) + const int number_of_tests = 100; + for (int i=0; i< number_of_tests; i++) try { #if defined BOOST_THREAD_USES_MOVE diff --git a/include/boost/thread/caller_context.hpp b/include/boost/thread/caller_context.hpp new file mode 100644 index 00000000..a21c1173 --- /dev/null +++ b/include/boost/thread/caller_context.hpp @@ -0,0 +1,55 @@ +// (C) Copyright 2013 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef BOOST_THREAD_CALL_CONTEXT_HPP +#define BOOST_THREAD_CALL_CONTEXT_HPP + +#include +#if defined BOOST_THREAD_USES_LOG_THREAD_ID +#include +#endif +#include + +#include + +namespace boost +{ + + struct caller_context_t + { + const char * filename; + unsigned lineno; + const char * func; + caller_context_t(const char * filename, unsigned lineno, const char * func) : + filename(filename), lineno(lineno), func(func) + { + } + }; + +#define BOOST_CONTEXTOF boost::caller_context_t(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION) + + template + OStream& operator<<(OStream& os, caller_context_t const& ctx) + { +#if defined BOOST_THREAD_USES_LOG_THREAD_ID + { + io::ios_flags_saver ifs( os ); + os << std::left << std::setw(14) << boost::this_thread::get_id() << " "; + } +#endif + { + io::ios_flags_saver ifs(os); + os << ctx.filename << "[" + << std::setw(4) << std::right << std::dec<< ctx.lineno << "] "; + os << ctx.func << " " ; + } + return os; + } +} + +#include + +#endif // header diff --git a/include/boost/thread/executor.hpp b/include/boost/thread/executor.hpp index 1bed6162..48d6a1c0 100644 --- a/include/boost/thread/executor.hpp +++ b/include/boost/thread/executor.hpp @@ -142,7 +142,32 @@ namespace boost executor_adaptor(BOOST_THREAD_RV_REF(Args) ... args) : ex(boost::forward(args)...) {} #else template - executor_adaptor(BOOST_THREAD_FWD_REF(A1) a1) : ex(boost::forward(a1)) {} + executor_adaptor( + BOOST_THREAD_FWD_REF(A1) a1 + ) : + ex( + boost::forward(a1) + ) {} + template + executor_adaptor( + BOOST_THREAD_FWD_REF(A1) a1, + BOOST_THREAD_FWD_REF(A2) a2 + ) : + ex( + boost::forward(a1), + boost::forward(a2) + ) {} + template + executor_adaptor( + BOOST_THREAD_FWD_REF(A1) a1, + BOOST_THREAD_FWD_REF(A2) a2, + BOOST_THREAD_FWD_REF(A3) a3 + ) : + ex( + boost::forward(a1), + boost::forward(a2), + boost::forward(a3) + ) {} #endif Executor& underlying_executor() { return ex; } @@ -166,8 +191,30 @@ namespace boost * \b Throws: \c sync_queue_is_closed if the thread pool is closed. * Whatever exception that can be throw while storing the closure. */ - void submit(BOOST_THREAD_RV_REF(work) closure) { return ex.submit(boost::move(closure)); } + void submit(BOOST_THREAD_RV_REF(work) closure) { + return ex.submit(boost::move(closure)); + } +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + template + void submit(Closure & closure) + { + work w ((closure)); + submit(boost::move(w)); + } +#endif + void submit(void (*closure)()) + { + work w ((closure)); + submit(boost::move(w)); + } + + template + void submit(BOOST_THREAD_RV_REF(Closure) closure) + { + work w =boost::move(closure); + submit(boost::move(w)); + } /** * Effects: try to execute one task. diff --git a/include/boost/thread/future.hpp b/include/boost/thread/future.hpp index 0d253eb1..ddb20d38 100644 --- a/include/boost/thread/future.hpp +++ b/include/boost/thread/future.hpp @@ -15,7 +15,6 @@ #ifndef BOOST_NO_EXCEPTIONS -//#include #include #include #include @@ -30,8 +29,6 @@ #include #include #include -//#include -//#include #include #include #include @@ -69,10 +66,6 @@ #include #endif -#ifdef BOOST_THREAD_PROVIDES_EXECUTORS -#include -#endif - #if defined BOOST_THREAD_PROVIDES_FUTURE #define BOOST_THREAD_FUTURE future #else @@ -3712,20 +3705,20 @@ namespace boost ///////////////////////// /// future_executor_shared_state_base ///////////////////////// - template + template struct future_executor_shared_state: shared_state { typedef shared_state base_type; protected: - boost::executor& ex_; + //Executor& ex_; public: template - future_executor_shared_state(boost::executor& ex, BOOST_THREAD_FWD_REF(Fp) f) - : ex_(ex) + future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f) + //: ex_(ex) { this->set_executor(); shared_state_nullary_task t(this, boost::forward(f)); - ex_.submit(boost::move(t)); + ex.submit(boost::move(t)); } ~future_executor_shared_state() @@ -3737,28 +3730,28 @@ namespace boost //////////////////////////////// // make_future_executor_shared_state //////////////////////////////// - template + template BOOST_THREAD_FUTURE - make_future_executor_shared_state(executor& ex, BOOST_THREAD_FWD_REF(Fp) f) + make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f) { - shared_ptr > - h(new future_executor_shared_state(ex, boost::forward(f))); + shared_ptr > + h(new future_executor_shared_state(ex, boost::forward(f))); return BOOST_THREAD_FUTURE(h); } } // detail //////////////////////////////// - // template - // future async(executor& ex, F&&, ArgTypes&&...); + // template + // future async(Executor& ex, F&&, ArgTypes&&...); //////////////////////////////// #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR - template + template BOOST_THREAD_FUTURE - async(executor& ex, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) + async(Executor& ex, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) { typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...); typedef detail::async_func::type, typename decay::type...> BF; @@ -3773,11 +3766,11 @@ namespace boost } #endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR - template + template BOOST_THREAD_FUTURE::type( typename decay::type... )>::type> - async(executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) + async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) { typedef detail::async_func::type, typename decay::type...> BF; typedef typename BF::result_type Rp; @@ -3792,41 +3785,41 @@ namespace boost #else // ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR - template + template BOOST_THREAD_FUTURE - async(executor& ex, R(*f)()) + async(Executor& ex, R(*f)()) { typedef R(*F)(); - typedef detail::async_func::type> BF; + typedef detail::async_func BF; typedef typename BF::result_type Rp; return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state(ex, BF( - thread_detail::decay_copy(boost::forward(f)) + f ) )); } - template + template BOOST_THREAD_FUTURE - async(executor& ex, R(*f)(BOOST_THREAD_FWD_REF(A1)), BOOST_THREAD_FWD_REF(A1) a1) + async(Executor& ex, R(*f)(BOOST_THREAD_FWD_REF(A1)), BOOST_THREAD_FWD_REF(A1) a1) { typedef R(*F)(BOOST_THREAD_FWD_REF(A1)); - typedef detail::async_func::type, typename decay::type> BF; + typedef detail::async_func::type> BF; typedef typename BF::result_type Rp; return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state(ex, BF( - thread_detail::decay_copy(boost::forward(f)) + f , thread_detail::decay_copy(boost::forward(a1)) ) )); } #endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR - template + template BOOST_THREAD_FUTURE::type()>::type> - async(executor& ex, BOOST_THREAD_FWD_REF(F) f) + async(Executor& ex, BOOST_THREAD_FWD_REF(F) f) { typedef detail::async_func::type> BF; typedef typename BF::result_type Rp; @@ -3838,11 +3831,11 @@ namespace boost ); } - template + template BOOST_THREAD_FUTURE::type( typename decay::type )>::type> - async(executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) + async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) { typedef detail::async_func::type, typename decay::type> BF; typedef typename BF::result_type Rp; diff --git a/include/boost/thread/ostream_buffer.hpp b/include/boost/thread/ostream_buffer.hpp index 88a92d49..cc02a9c0 100644 --- a/include/boost/thread/ostream_buffer.hpp +++ b/include/boost/thread/ostream_buffer.hpp @@ -21,13 +21,23 @@ namespace boost { public: typedef std::basic_ostringstream stream_type; - ostream_buffer(OStream& os) : os_(os) {} - ~ostream_buffer() { os_ << o_str_.str(); } - stream_type& stream() { return o_str_; } + ostream_buffer(OStream& os) : + os_(os) + { + } + ~ostream_buffer() + { + os_ << o_str_.str(); + } + stream_type& stream() + { + return o_str_; + } private: OStream& os_; stream_type o_str_; }; + } #include