Thread: minor refactorings

[SVN r81842]
This commit is contained in:
Vicente J. Botet Escriba 2012-12-10 22:02:16 +00:00
parent 2b8930a5bf
commit c8edd6c795
9 changed files with 169 additions and 132 deletions

View File

@ -4,8 +4,9 @@
// 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_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET
//#define BOOST_THREAD_USES_LOG
#define BOOST_THREAD_USES_LOG_THREAD_ID
//#define BOOST_THREAD_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET
#include <boost/thread/detail/log.hpp>
#include <boost/thread/future.hpp>

View File

@ -15,6 +15,7 @@
#ifndef BOOST_NO_EXCEPTIONS
//#include <boost/thread/detail/log.hpp>
#include <boost/detail/scoped_enum_emulation.hpp>
#include <stdexcept>
#include <boost/thread/detail/move.hpp>
@ -45,7 +46,7 @@
#include <boost/next_prior.hpp>
#include <vector>
#include <boost/system/error_code.hpp>
#include <boost/thread/future_error_code.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#endif
@ -66,31 +67,10 @@
namespace boost
{
//enum class future_errc
BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc)
{
broken_promise = 1,
future_already_retrieved,
promise_already_satisfied,
no_state
}
BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
namespace system
{
template <>
struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc> : public true_type {};
#ifdef BOOST_NO_CXX11_SCOPED_ENUMS
template <>
struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc::enum_type> : public true_type { };
#endif
}
//enum class launch
BOOST_SCOPED_ENUM_DECLARE_BEGIN(launch)
{
none = 0,
async = 1,
deferred = 2,
any = async | deferred
@ -106,26 +86,6 @@ namespace boost
}
BOOST_SCOPED_ENUM_DECLARE_END(future_status)
BOOST_THREAD_DECL
const system::error_category& future_category() BOOST_NOEXCEPT;
namespace system
{
inline
error_code
make_error_code(future_errc e) BOOST_SYSTEM_NOEXCEPT
{
return error_code(underlying_cast<int>(e), boost::future_category());
}
inline
error_condition
make_error_condition(future_errc e) BOOST_SYSTEM_NOEXCEPT
{
return error_condition(underlying_cast<int>(e), future_category());
}
}
class BOOST_SYMBOL_VISIBLE future_error
: public std::logic_error
{
@ -283,7 +243,7 @@ namespace boost
future_object_base():
done(false),
is_deferred_(false),
policy_(launch::any),
policy_(launch::none),
is_constructed(false)
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
, thread_was_interrupted(false)
@ -295,8 +255,19 @@ namespace boost
virtual ~future_object_base()
{}
void set_deferred() {is_deferred_ = true;}
void set_launch_policy(launch policy) {policy_ = policy;}
void set_deferred()
{
is_deferred_ = true;
set_launch_policy(launch::deferred);
}
void set_async()
{
set_launch_policy(launch::async);
}
void set_launch_policy(launch policy)
{
policy_ = policy;
}
waiter_list::iterator register_external_waiter(boost::condition_variable_any& cv)
{
@ -861,35 +832,41 @@ namespace boost
future_object& operator=(future_object const&);
};
/////////////////////////
/// future_async_object
/////////////////////////
template<typename Rp, typename Fp>
struct future_async_object: future_object<Rp>
{
typedef future_object<Rp> base_type;
typedef typename base_type::move_dest_type move_dest_type;
boost::thread thr_;
public:
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
explicit future_async_object(Fp&& f)
:
#else
explicit future_async_object(BOOST_THREAD_FWD_REF(Fp) f)
:
#endif
thr_(&future_async_object::run, this, boost::forward<Fp>(f))
explicit future_async_object(BOOST_THREAD_FWD_REF(Fp) f) :
thr_(&future_async_object::run, this, boost::forward<Fp>(f))
{
this->set_async();
}
~future_async_object()
{
thr_.join();
if (thr_.joinable()) thr_.join();
}
move_dest_type get()
{
if (thr_.joinable()) thr_.join();
// fixme Is the lock needed during the whole scope?
//this->wait();
boost::unique_lock<boost::mutex> lock(this->mutex);
this->wait_internal(lock);
return static_cast<move_dest_type>(*(this->result));
}
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
static void run(future_async_object* that, Fp&& f)
#else
static void run(future_async_object* that, BOOST_THREAD_FWD_REF(Fp) f)
#endif
{
try
{
@ -912,30 +889,22 @@ namespace boost
struct future_async_object<void, Fp>: public future_object<void>
{
typedef future_object<void> base_type;
boost::thread thr_;
public:
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
explicit future_async_object(Fp&& f)
:
#else
explicit future_async_object(BOOST_THREAD_FWD_REF(Fp) f)
:
#endif
thr_(&future_async_object::run, this, boost::forward<Fp>(f))
explicit future_async_object(BOOST_THREAD_FWD_REF(Fp) f) :
thr_(&future_async_object::run, this, boost::forward<Fp>(f))
{
this->set_async();
}
~future_async_object()
{
thr_.join();
if (thr_.joinable()) thr_.join();
}
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
static void run(future_async_object* that, Fp&& f)
#else
static void run(future_async_object* that, BOOST_THREAD_FWD_REF(Fp) f)
#endif
{
try
{
@ -954,7 +923,9 @@ namespace boost
}
}
};
//////////////////////////
/// future_deferred_object
//////////////////////////
template<typename Rp, typename Fp>
struct future_deferred_object: future_object<Rp>
{
@ -962,13 +933,8 @@ namespace boost
Fp func_;
public:
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
explicit future_deferred_object(Fp&& f)
explicit future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f)
: func_(boost::forward<Fp>(f))
#else
explicit future_deferred_object(Fp f)
: func_(f)
#endif
{
this->set_deferred();
}
@ -992,13 +958,8 @@ namespace boost
Fp func_;
public:
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
explicit future_deferred_object(Fp&& f)
explicit future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f)
: func_(boost::forward<Fp>(f))
#else
explicit future_deferred_object(Fp f)
: func_(f)
#endif
{
this->set_deferred();
}
@ -1396,19 +1357,11 @@ namespace boost
{
template <class Rp, class Fp>
BOOST_THREAD_FUTURE<Rp>
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
make_future_async_object(Fp&& f);
#else
make_future_async_object(BOOST_THREAD_FWD_REF(Fp) f);
#endif
template <class Rp, class Fp>
BOOST_THREAD_FUTURE<Rp>
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
make_future_deferred_object(Fp&& f);
#else
make_future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f);
#endif
}
template <typename R>
@ -1433,19 +1386,11 @@ namespace boost
template <class Rp, class Fp>
friend BOOST_THREAD_FUTURE<Rp>
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
detail::make_future_async_object(Fp&& f);
#else
detail::make_future_async_object(BOOST_THREAD_FWD_REF(Fp) f);
#endif
template <class Rp, class Fp>
friend BOOST_THREAD_FUTURE<Rp>
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
detail::make_future_deferred_object(Fp&& f);
#else
detail::make_future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f);
#endif
typedef typename detail::future_traits<R>::move_dest_type move_dest_type;
@ -2856,11 +2801,7 @@ namespace boost
////////////////////////////////
template <class Rp, class Fp>
BOOST_THREAD_FUTURE<Rp>
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
make_future_deferred_object(Fp&& f)
#else
make_future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f)
#endif
{
shared_ptr<future_deferred_object<Rp, Fp> >
h(new future_deferred_object<Rp, Fp>(boost::forward<Fp>(f)));
@ -2872,11 +2813,7 @@ namespace boost
////////////////////////////////
template <class Rp, class Fp>
BOOST_THREAD_FUTURE<Rp>
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
make_future_async_object(Fp&& f)
#else
make_future_async_object(BOOST_THREAD_FWD_REF(Fp) f)
#endif
{
shared_ptr<future_async_object<Rp, Fp> >
h(new future_async_object<Rp, Fp>(boost::forward<Fp>(f)));

View File

@ -0,0 +1,61 @@
// (C) Copyright 2008-10 Anthony Williams
// (C) Copyright 2011-2012 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_FUTURE_ERROR_CODE_HPP
#define BOOST_THREAD_FUTURE_ERROR_CODE_HPP
#include <boost/thread/detail/config.hpp>
#include <boost/detail/scoped_enum_emulation.hpp>
#include <boost/system/error_code.hpp>
#include <boost/type_traits/integral_constant.hpp>
namespace boost
{
//enum class future_errc
BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc)
{
broken_promise = 1,
future_already_retrieved,
promise_already_satisfied,
no_state
}
BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
namespace system
{
template <>
struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc> : public true_type {};
#ifdef BOOST_NO_CXX11_SCOPED_ENUMS
template <>
struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc::enum_type> : public true_type { };
#endif
} // system
BOOST_THREAD_DECL
const system::error_category& future_category() BOOST_NOEXCEPT;
namespace system
{
inline
error_code
make_error_code(future_errc e) BOOST_SYSTEM_NOEXCEPT
{
return error_code(underlying_cast<int>(e), boost::future_category());
}
inline
error_condition
make_error_condition(future_errc e) BOOST_SYSTEM_NOEXCEPT
{
return error_condition(underlying_cast<int>(e), future_category());
}
} // system
} // boost
#endif // header

View File

@ -7,7 +7,7 @@
#ifndef BOOST_NO_EXCEPTIONS
#include <boost/thread/future.hpp>
#include <boost/thread/future_error_code.hpp>
namespace boost
{

View File

@ -395,7 +395,7 @@ namespace boost
bool thread::joinable() const BOOST_NOEXCEPT
{
return (get_thread_info)()!=0;
return (get_thread_info)()?true:false;
}

View File

@ -330,7 +330,7 @@ namespace boost
bool thread::joinable() const BOOST_NOEXCEPT
{
return (get_thread_info)() != 0;
return (get_thread_info)() ? true : false;
}
bool thread::join_noexcept()
{

View File

@ -662,11 +662,9 @@ rule thread-compile-fail ( sources : reqs * : name )
explicit ts_ ;
test-suite ts_
:
[ thread-run2-noit ./sync/conditions/notify_all_at_thread_exit_pass.cpp : notify_all_at_thread_exit_p2 ]
[ thread-run2-noit ./threads/thread/members/try_join_until_pass.cpp : thread__join_until_p2 ]
[ thread-run2-noit ./threads/thread/members/try_join_for_pass.cpp : thread__join_for_p2 ]
[ thread-run2-noit ./sync/futures/async/async_pass.cpp : async__async_p2 ]
#[ thread-run2-noit ./sync/futures/future/then_pass.cpp : future__then_p ]
[ compile virtual_noexcept.cpp ]
#[ thread-run test_7665.cpp ]
#[ thread-run test_7666.cpp ]
#[ thread-run ../example/unwrap.cpp ]

View File

@ -22,6 +22,9 @@
//#define BOOST_THREAD_VERSION 3
#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_USES_LOG
#define BOOST_THREAD_USES_LOG_THREAD_ID
#include <boost/thread/detail/log.hpp>
#include <boost/thread/future.hpp>
#include <boost/thread/thread.hpp>
@ -87,49 +90,65 @@ void func6(boost::promise<void> p)
int main()
{
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
typedef int T;
// {
// boost::promise<T> p;
// boost::future<T> f = p.get_future();
//#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
// boost::thread(func1, boost::move(p)).detach();
//#else
// p.set_value(3);
//#endif
// BOOST_TEST(f.valid());
// BOOST_TEST(f.get() == 3);
//#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
// BOOST_TEST(!f.valid());
//#endif
// }
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::promise<T> p;
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
boost::future<T> f = p.get_future();
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
boost::thread(func1, boost::move(p)).detach();
#else
p.set_value(3);
#endif
BOOST_TEST(f.valid());
BOOST_TEST(f.get() == 3);
#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
BOOST_TEST(!f.valid());
#endif
}
{
boost::promise<T> p;
boost::future<T> f = p.get_future();
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
boost::thread(func2, boost::move(p)).detach();
#else
p.set_exception(boost::make_exception_ptr(3));
#endif
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
try
{
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(f.valid());
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(f.get() == 3);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(false);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
catch (boost::wrap<int> const& i)
{
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(i.value == 3);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
catch (...)
{
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(false);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(!f.valid());
#endif
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
}
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
typedef int& T;
{
@ -147,6 +166,7 @@ int main()
BOOST_TEST(!f.valid());
#endif
}
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::promise<T> p;
boost::future<T> f = p.get_future();
@ -170,6 +190,7 @@ int main()
#endif
}
}
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
typedef void T;
{
@ -186,6 +207,7 @@ int main()
BOOST_TEST(!f.valid());
#endif
}
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::promise<T> p;
boost::future<T> f = p.get_future();
@ -212,6 +234,7 @@ int main()
BOOST_TEST(!f.valid());
#endif
}
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
return boost::report_errors();
}

View File

@ -8,10 +8,13 @@
// class future<R>
// template<typename F>
// auto then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
// auto then(F&& func) -> future<decltype(func(*this))>;
#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET
//#define BOOST_THREAD_USES_LOG
#define BOOST_THREAD_USES_LOG_THREAD_ID
#include <boost/thread/detail/log.hpp>
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
@ -30,23 +33,37 @@ int p2(boost::future<int>& f)
int main()
{
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::future<int> f1 = boost::async(p1);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
boost::future<int> f2 = f1.then(p2);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(f2.get()==2);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
{
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
boost::future<int> f2 = boost::async(p1).then(p2);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(f2.get()==2);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
{
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
boost::future<int> f1 = boost::async(p1);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
boost::future<int> f2 = f1.then(p2).then(p2);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(f2.get()==4);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
{
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
boost::future<int> f2 = boost::async(p1).then(p2).then(p2);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(f2.get()==4);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
return boost::report_errors();