Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r77852 - in trunk: boost/thread libs/thread/doc libs/thread/test libs/thread/test/sync/futures/packaged_task
From: vicente.botet_at_[hidden]
Date: 2012-04-09 13:18:40


Author: viboes
Date: 2012-04-09 13:18:39 EDT (Mon, 09 Apr 2012)
New Revision: 77852
URL: http://svn.boost.org/trac/boost/changeset/77852

Log:
Thread: Added packaged_task::reste() + more tests
Added:
   trunk/libs/thread/test/sync/futures/packaged_task/reset_pass.cpp (contents, props changed)
Text files modified:
   trunk/boost/thread/future.hpp | 24 +++---
   trunk/libs/thread/doc/changes.qbk | 2
   trunk/libs/thread/doc/future_ref.qbk | 21 +++++
   trunk/libs/thread/test/Jamfile.v2 | 2
   trunk/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp | 44 +++++++++---
   trunk/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp | 52 +++++++++------
   trunk/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp | 137 ++++++++++++++++++++-------------------
   7 files changed, 164 insertions(+), 118 deletions(-)

Modified: trunk/boost/thread/future.hpp
==============================================================================
--- trunk/boost/thread/future.hpp (original)
+++ trunk/boost/thread/future.hpp 2012-04-09 13:18:39 EDT (Mon, 09 Apr 2012)
@@ -1662,6 +1662,10 @@
                 started(false)
             {}
 
+ void reset()
+ {
+ started=false;
+ }
             void run()
             {
                 {
@@ -1705,9 +1709,6 @@
             task_object(F&& f_):
               f(boost::forward<F>(f_))
             {}
-// task_object(task_object&& rhs):
-// f(boost::move(rhs.f_))
-// {}
 #else
 // task_object(R(*f_)()):
 // f(f_)
@@ -1759,9 +1760,6 @@
             task_object(F&& f_):
               f(boost::forward<F>(f_))
             {}
-// task_object(task_object&& rhs):
-// f(boost::forward<F>(rhs.f_))
-// {}
 #else
 // task_object(void(*f_)()):
 // f(f_)
@@ -2000,13 +1998,13 @@
 #endif
 #endif
 
-// void reset()
-// {
-// if (!valid())
-// throw future_error(system::make_error_code(future_errc::no_state));
-// task = new detail::task_object<R,F>(task.get());
-// future_obtained=false;
-// }
+ void reset()
+ {
+ if (!valid())
+ throw future_error(system::make_error_code(future_errc::no_state));
+ task->reset();
+ future_obtained=false;
+ }
 
         void swap(packaged_task& other) BOOST_NOEXCEPT
         {

Modified: trunk/libs/thread/doc/changes.qbk
==============================================================================
--- trunk/libs/thread/doc/changes.qbk (original)
+++ trunk/libs/thread/doc/changes.qbk 2012-04-09 13:18:39 EDT (Mon, 09 Apr 2012)
@@ -33,7 +33,7 @@
 * [@http://svn.boost.org/trac/boost/ticket/6672 #6672] upgrade_lock:: missing constructors from time related types.
 * [@http://svn.boost.org/trac/boost/ticket/6675 #6675] upgrade_lock:: missing non-member swap.
 * Added missing packaged_task::result_type and packaged_task:: constructor with allocator.
-
+* Added packaged_task::reset()
 
 Fixed Bugs:
 

Modified: trunk/libs/thread/doc/future_ref.qbk
==============================================================================
--- trunk/libs/thread/doc/future_ref.qbk (original)
+++ trunk/libs/thread/doc/future_ref.qbk 2012-04-09 13:18:39 EDT (Mon, 09 Apr 2012)
@@ -947,9 +947,9 @@
         // void operator()(ArgTypes... ); // NOT YET IMPLEMENTED
         // void make_ready_at_thread_exit(ArgTypes...); // NOT YET IMPLEMENTED
 
- // void reset(); // NOT YET IMPLEMENTED
+ void reset();
         template<typename F>
- void set_wait_callback(F f);
+ void set_wait_callback(F f); // EXTENSION
     };
 
 [section:task_constructor Task Constructor]
@@ -1079,7 +1079,22 @@
 
 [endsect]
 
-[section:set_wait_callback Member Function `set_wait_callback()`]
+[section:reset Member Function `reset()`]
+
+ void reset();
+
+[variablelist
+
+[[Effects:] [Reset the state of the packaged_task so that it can be called again.]]
+
+[[Throws:] [__task_moved__ if ownership of the task associated with `*this` has been moved to another instance of
+__packaged_task__.]]
+
+]
+
+[endsect]
+
+[section:set_wait_callback Member Function `set_wait_callback()` EXTENSION]
 
     template<typename F>
     void set_wait_callback(F f);

Modified: trunk/libs/thread/test/Jamfile.v2
==============================================================================
--- trunk/libs/thread/test/Jamfile.v2 (original)
+++ trunk/libs/thread/test/Jamfile.v2 2012-04-09 13:18:39 EDT (Mon, 09 Apr 2012)
@@ -223,6 +223,8 @@
           [ thread-run2 ./sync/futures/packaged_task/get_future_pass.cpp : packaged_task__get_future_p ]
           [ thread-run2 ./sync/futures/packaged_task/move_ctor_pass.cpp : packaged_task__move_ctor_p ]
           [ thread-run2 ./sync/futures/packaged_task/move_assign_pass.cpp : packaged_task__move_asign_p ]
+ #[ thread-run2 ./sync/futures/packaged_task/operator_pass.cpp : packaged_task__operator_p ]
+ [ thread-run2 ./sync/futures/packaged_task/reset_pass.cpp : packaged_task__reset_p ]
           [ thread-run2 ./sync/futures/packaged_task/use_allocator_pass.cpp : packaged_task__use_allocator_p ]
           [ thread-run2 ./sync/futures/packaged_task/types_pass.cpp : packaged_task__types_p ]
 

Modified: trunk/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp 2012-04-09 13:18:39 EDT (Mon, 09 Apr 2012)
@@ -24,24 +24,44 @@
 
 class A
 {
- long data_;
+ long data_;
 
 public:
- explicit A(long i) : data_(i) {}
-
- long operator()() const {return data_ ;}
- long operator()(long i, long j) const {return data_ + i + j;}
+ explicit A(long i) :
+ data_(i)
+ {
+ }
+
+ long operator()() const
+ {
+ return data_;
+ }
+ long operator()(long i, long j) const
+ {
+ return data_ + i + j;
+ }
 };
 
 int main()
 {
- boost::unique_lock<mutex> lk1(m);
- boost::unique_lock<mutex> lk2;
- lk1.swap(lk2);
- BOOST_TEST(lk1.mutex() == 0);
- BOOST_TEST(lk1.owns_lock() == false);
- BOOST_TEST(lk2.mutex() == &m);
- BOOST_TEST(lk2.owns_lock() == true);
+ {
+ boost::packaged_task<double> p0(A(5));
+ boost::packaged_task<double> p;
+ p.swap(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_EXPLICIT_MOVE(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<double(int, char)> p0;
+ boost::packaged_task<double(int, char)> p;
+ p.swap(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(!p.valid());
+ }
 
   return boost::report_errors();
 }

Modified: trunk/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp 2012-04-09 13:18:39 EDT (Mon, 09 Apr 2012)
@@ -12,36 +12,46 @@
 // 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)
 
-// <boost/thread/locks.hpp>
+// <boost/thread/future.hpp>
 
-// template <class Mutex>
-// void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y);
+// template <class R>
+// void
+// swap(packaged_task<R>& x, packaged_task<R>& y);
 
-#include <boost/thread/locks.hpp>
+#include <boost/thread/future.hpp>
 #include <boost/detail/lightweight_test.hpp>
 
-struct mutex
+class A
 {
- void lock()
- {
- }
- void unlock()
- {
- }
-};
+ long data_;
 
-mutex m;
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()() const {return data_;}
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
 
 int main()
 {
- boost::unique_lock<mutex> lk1(m);
- boost::unique_lock<mutex> lk2;
- swap(lk1, lk2);
- BOOST_TEST(lk1.mutex() == 0);
- BOOST_TEST(lk1.owns_lock() == false);
- BOOST_TEST(lk2.mutex() == &m);
- BOOST_TEST(lk2.owns_lock() == true);
+ {
+ boost::packaged_task<double> p0(A(5));
+ boost::packaged_task<double> p;
+ p.swap(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(p.valid());
+ boost::future<double> f = p.get_future();
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<double> p0;
+ boost::packaged_task<double> p;
+ p.swap(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(!p.valid());
+ }
 
- return boost::report_errors();
 }
 

Modified: trunk/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp 2012-04-09 13:18:39 EDT (Mon, 09 Apr 2012)
@@ -18,106 +18,107 @@
 // void operator()();
 
 
-
 #define BOOST_THREAD_VERSION 2
 #include <boost/thread/future.hpp>
 #include <boost/detail/lightweight_test.hpp>
 
 class A
 {
- long data_;
+ long data_;
 
 public:
- explicit A(long i) : data_(i) {}
+ explicit A(long i) :
+ data_(i)
+ {
+ }
 
- long operator()() const
- {
- return data_;
- }
- long operator()(long i, long j) const
- {
- if (j == 'z')
- throw A(6);
- return data_ + i + j;
- }
+ long operator()() const
+ {
+ return data_;
+ }
+ long operator()(long i, long j) const
+ {
+ if (j == 'z') throw A(6);
+ return data_ + i + j;
+ }
 };
 
 void func0(boost::packaged_task<double> p)
 {
- boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
- //p(3, 'a');
- p();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ //p(3, 'a');
+ p();
 }
 
 void func1(boost::packaged_task<double(int, char)> p)
 {
- boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
- //p(3, 'z');
- p();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ //p(3, 'z');
+ p();
 }
 
 void func2(boost::packaged_task<double(int, char)> p)
 {
- //p(3, 'a');
+ //p(3, 'a');
+ p();
+ try
+ {
+ //p(3, 'c');
     p();
- try
- {
- //p(3, 'c');
- p();
- }
- catch (const boost::future_error& e)
- {
- BOOST_TEST(e.code() == make_error_code(boost::future_errc::promise_already_satisfied));
- }
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == make_error_code(boost::future_errc::promise_already_satisfied));
+ }
 }
 
 void func3(boost::packaged_task<double(int, char)> p)
 {
+ try
+ {
+ //p(3, 'a');
+ p();
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == make_error_code(boost::future_errc::no_state));
+ }
+}
+
+int main()
+{
+ {
+ boost::packaged_task<double> p(A(5));
+ boost::future<double> f = BOOST_EXPLICIT_MOVE(p.get_future());
+ boost::thread(func0, boost::move(p)).detach();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<double> p(A(5));
+ boost::future<double> f = BOOST_EXPLICIT_MOVE(p.get_future());
+ boost::thread(func1, boost::move(p)).detach();
     try
     {
- //p(3, 'a');
- p();
+ f.get();
+ BOOST_TEST(false);
     }
- catch (const boost::future_error& e)
+ catch (const A& e)
     {
- BOOST_TEST(e.code() == make_error_code(boost::future_errc::no_state));
+ //BOOST_TEST(e(3, 'a') == 106);
+ BOOST_TEST(e() == 5);
     }
-}
-
-
-int main()
-{
+ }
+ {
+ boost::packaged_task<double> p(A(5));
+ boost::future<double> f = BOOST_EXPLICIT_MOVE(p.get_future());
+ boost::thread t(func2, boost::move(p));
+ BOOST_TEST(f.get() == 5.0);
+ t.join();
+ }
   {
- boost::packaged_task<doubl> p(A(5));
- boost::future<double> f = p.get_future();
- boost::thread(func0, boost::move(p)).detach();
- BOOST_TEST(f.get() == 105.0);
- }
- {
- boost::packaged_task<double> p(A(5));
- boost::future<double> f = p.get_future();
- boost::thread(func1, boost::move(p)).detach();
- try
- {
- f.get();
- BOOST_TEST(false);
- }
- catch (const A& e)
- {
- BOOST_TEST(e(3, 'a') == 106);
- }
- }
- {
- boost::packaged_task<double> p(A(5));
- boost::future<double> f = p.get_future();
- boost::thread t(func2, boost::move(p));
- BOOST_TEST(f.get() == 105.0);
- t.join();
- }
- {
- boost::packaged_task<double> p;
- boost::thread t(func3, boost::move(p));
- t.join();
+ boost::packaged_task<double> p;
+ boost::thread t(func3, boost::move(p));
+ t.join();
   }
 
   return boost::report_errors();

Added: trunk/libs/thread/test/sync/futures/packaged_task/reset_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/futures/packaged_task/reset_pass.cpp 2012-04-09 13:18:39 EDT (Mon, 09 Apr 2012)
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 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)
+
+// <boost/thread/future.hpp>
+// class packaged_task<R>
+
+// void operator()();
+
+
+#define BOOST_THREAD_VERSION 2
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) :
+ data_(i)
+ {
+ }
+
+ long operator()() const
+ {
+ return data_;
+ }
+ long operator()(long i, long j) const
+ {
+ if (j == 'z') throw A(6);
+ return data_ + i + j;
+ }
+};
+
+int main()
+{
+ {
+ boost::packaged_task<double> p(A(5));
+ boost::future<double> f = BOOST_EXPLICIT_MOVE(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ p.reset();
+ //p(4, 'a');
+ p();
+ f = p.get_future();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<double> p;
+ try
+ {
+ p.reset();
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+
+ return boost::report_errors();
+}
+


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk