Boost logo

Boost-Commit :

From: anthony_at_[hidden]
Date: 2007-11-14 06:56:54


Author: anthonyw
Date: 2007-11-14 06:56:53 EST (Wed, 14 Nov 2007)
New Revision: 41084
URL: http://svn.boost.org/trac/boost/changeset/41084

Log:
interrupt and join all threads in a group if an exception is thrown during a test
Text files modified:
   trunk/boost/thread/pthread/thread.hpp | 1
   trunk/boost/thread/win32/thread.hpp | 12 +
   trunk/libs/thread/test/test_barrier.cpp | 13 -
   trunk/libs/thread/test/test_condition.cpp | 24 ++-
   trunk/libs/thread/test/test_once.cpp | 50 ++++++-
   trunk/libs/thread/test/test_shared_mutex.cpp | 261 +++++++++++++++++++++++++--------------
   trunk/libs/thread/test/test_tss.cpp | 16 +
   7 files changed, 251 insertions(+), 126 deletions(-)

Modified: trunk/boost/thread/pthread/thread.hpp
==============================================================================
--- trunk/boost/thread/pthread/thread.hpp (original)
+++ trunk/boost/thread/pthread/thread.hpp 2007-11-14 06:56:53 EST (Wed, 14 Nov 2007)
@@ -277,6 +277,7 @@
         void add_thread(thread* thrd);
         void remove_thread(thread* thrd);
         void join_all();
+ void interrupt_all();
         int size() const;
 
     private:

Modified: trunk/boost/thread/win32/thread.hpp
==============================================================================
--- trunk/boost/thread/win32/thread.hpp (original)
+++ trunk/boost/thread/win32/thread.hpp 2007-11-14 06:56:53 EST (Wed, 14 Nov 2007)
@@ -429,6 +429,18 @@
             }
         }
         
+ void interrupt_all()
+ {
+ boost::lock_guard<mutex> guard(m);
+
+ for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
+ it!=end;
+ ++it)
+ {
+ (*it)->interrupt();
+ }
+ }
+
         int size() const
         {
             boost::lock_guard<mutex> guard(m);

Modified: trunk/libs/thread/test/test_barrier.cpp
==============================================================================
--- trunk/libs/thread/test/test_barrier.cpp (original)
+++ trunk/libs/thread/test/test_barrier.cpp 2007-11-14 06:56:53 EST (Wed, 14 Nov 2007)
@@ -39,26 +39,19 @@
     boost::thread_group g;
     global_parameter = 0;
 
- std::vector<boost::thread*> threads;
- threads.reserve(N_THREADS);
-
     try
     {
         for (int i = 0; i < N_THREADS; ++i)
- threads.push_back(g.create_thread(&barrier_thread));
+ g.create_thread(&barrier_thread);
+ g.join_all();
     }
     catch(...)
     {
- for(unsigned i=0;i<threads.size();++i)
- {
- threads[i]->interrupt();
- }
+ g.interrupt_all();
         g.join_all();
         throw;
     }
     
- g.join_all();
-
     BOOST_CHECK(global_parameter == 5);
 }
 

Modified: trunk/libs/thread/test/test_condition.cpp
==============================================================================
--- trunk/libs/thread/test/test_condition.cpp (original)
+++ trunk/libs/thread/test/test_condition.cpp 2007-11-14 06:56:53 EST (Wed, 14 Nov 2007)
@@ -112,17 +112,27 @@
     boost::thread_group threads;
     condition_test_data data;
 
- for (int i = 0; i < NUMTHREADS; ++i)
- threads.create_thread(bind(&condition_test_thread, &data));
+ try
+ {
+ for (int i = 0; i < NUMTHREADS; ++i)
+ threads.create_thread(bind(&condition_test_thread, &data));
+
+ {
+ boost::mutex::scoped_lock lock(data.mutex);
+ BOOST_CHECK(lock ? true : false);
+ data.notified++;
+ data.condition.notify_all();
+ }
 
+ threads.join_all();
+ }
+ catch(...)
     {
- boost::mutex::scoped_lock lock(data.mutex);
- BOOST_CHECK(lock ? true : false);
- data.notified++;
- data.condition.notify_all();
+ threads.interrupt_all();
+ threads.join_all();
+ throw;
     }
 
- threads.join_all();
     BOOST_CHECK_EQUAL(data.awoken, NUMTHREADS);
 }
 

Modified: trunk/libs/thread/test/test_once.cpp
==============================================================================
--- trunk/libs/thread/test/test_once.cpp (original)
+++ trunk/libs/thread/test/test_once.cpp 2007-11-14 06:56:53 EST (Wed, 14 Nov 2007)
@@ -40,12 +40,22 @@
 {
     unsigned const num_threads=20;
     boost::thread_group group;
-
- for(unsigned i=0;i<num_threads;++i)
+
+ try
+ {
+ for(unsigned i=0;i<num_threads;++i)
+ {
+ group.create_thread(&call_once_thread);
+ }
+ group.join_all();
+ }
+ catch(...)
     {
- group.create_thread(&call_once_thread);
+ group.interrupt_all();
+ group.join_all();
+ throw;
     }
- group.join_all();
+
     BOOST_CHECK_EQUAL(var_to_init,1);
 }
 
@@ -88,11 +98,21 @@
     unsigned const num_threads=20;
     boost::thread_group group;
 
- for(unsigned i=0;i<num_threads;++i)
+ try
+ {
+ for(unsigned i=0;i<num_threads;++i)
+ {
+ group.create_thread(&call_once_with_functor);
+ }
+ group.join_all();
+ }
+ catch(...)
     {
- group.create_thread(&call_once_with_functor);
+ group.interrupt_all();
+ group.join_all();
+ throw;
     }
- group.join_all();
+
     BOOST_CHECK_EQUAL(var_to_init_with_functor,1);
 }
 
@@ -137,11 +157,21 @@
     unsigned const num_threads=20;
     boost::thread_group group;
 
- for(unsigned i=0;i<num_threads;++i)
+ try
     {
- group.create_thread(&call_once_with_exception);
+ for(unsigned i=0;i<num_threads;++i)
+ {
+ group.create_thread(&call_once_with_exception);
+ }
+ group.join_all();
     }
- group.join_all();
+ catch(...)
+ {
+ group.interrupt_all();
+ group.join_all();
+ throw;
+ }
+
     BOOST_CHECK_EQUAL(throw_before_third_pass::pass_counter,3u);
     BOOST_CHECK_EQUAL(exception_counter,2u);
 }

Modified: trunk/libs/thread/test/test_shared_mutex.cpp
==============================================================================
--- trunk/libs/thread/test/test_shared_mutex.cpp (original)
+++ trunk/libs/thread/test/test_shared_mutex.cpp 2007-11-14 06:56:53 EST (Wed, 14 Nov 2007)
@@ -92,26 +92,35 @@
     boost::condition_variable unblocked_condition;
     boost::mutex finish_mutex;
     boost::mutex::scoped_lock finish_lock(finish_mutex);
-
- for(unsigned i=0;i<number_of_threads;++i)
- {
- pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
- finish_mutex,simultaneous_running_count,max_simultaneous_running));
- }
 
+ try
     {
- boost::mutex::scoped_lock lk(unblocked_count_mutex);
- while(unblocked_count<number_of_threads)
+ for(unsigned i=0;i<number_of_threads;++i)
         {
- unblocked_condition.wait(lk);
+ pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_mutex,simultaneous_running_count,max_simultaneous_running));
         }
- }
 
- CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,number_of_threads);
+ {
+ boost::mutex::scoped_lock lk(unblocked_count_mutex);
+ while(unblocked_count<number_of_threads)
+ {
+ unblocked_condition.wait(lk);
+ }
+ }
 
- finish_lock.unlock();
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,number_of_threads);
+
+ finish_lock.unlock();
 
- pool.join_all();
+ pool.join_all();
+ }
+ catch(...)
+ {
+ pool.interrupt_all();
+ pool.join_all();
+ throw;
+ }
 
     CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,number_of_threads);
 }
@@ -131,19 +140,28 @@
     boost::mutex finish_mutex;
     boost::mutex::scoped_lock finish_lock(finish_mutex);
     
- for(unsigned i=0;i<number_of_threads;++i)
+ try
     {
- pool.create_thread(locking_thread<boost::unique_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
- finish_mutex,simultaneous_running_count,max_simultaneous_running));
- }
+ for(unsigned i=0;i<number_of_threads;++i)
+ {
+ pool.create_thread(locking_thread<boost::unique_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_mutex,simultaneous_running_count,max_simultaneous_running));
+ }
 
- boost::thread::sleep(delay(2));
+ boost::thread::sleep(delay(2));
 
- CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
 
- finish_lock.unlock();
+ finish_lock.unlock();
 
- pool.join_all();
+ pool.join_all();
+ }
+ catch(...)
+ {
+ pool.interrupt_all();
+ pool.join_all();
+ throw;
+ }
 
     CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,number_of_threads);
     CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1u);
@@ -162,24 +180,34 @@
     boost::mutex finish_mutex;
     boost::mutex::scoped_lock finish_lock(finish_mutex);
     
- pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
- finish_mutex,simultaneous_running_count,max_simultaneous_running));
+ try
     {
- boost::mutex::scoped_lock lk(unblocked_count_mutex);
- while(unblocked_count<1)
+
+ pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_mutex,simultaneous_running_count,max_simultaneous_running));
         {
- unblocked_condition.wait(lk);
+ boost::mutex::scoped_lock lk(unblocked_count_mutex);
+ while(unblocked_count<1)
+ {
+ unblocked_condition.wait(lk);
+ }
         }
- }
- CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
- pool.create_thread(locking_thread<boost::unique_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
- finish_mutex,simultaneous_running_count,max_simultaneous_running));
- boost::thread::sleep(delay(1));
- CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
+ pool.create_thread(locking_thread<boost::unique_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_mutex,simultaneous_running_count,max_simultaneous_running));
+ boost::thread::sleep(delay(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
 
- finish_lock.unlock();
+ finish_lock.unlock();
 
- pool.join_all();
+ pool.join_all();
+ }
+ catch(...)
+ {
+ pool.interrupt_all();
+ pool.join_all();
+ throw;
+ }
 
     CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,2U);
     CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1u);
@@ -201,28 +229,38 @@
 
     unsigned const reader_count=100;
 
- for(unsigned i=0;i<reader_count;++i)
+ try
     {
- pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
- finish_mutex,simultaneous_running_count,max_simultaneous_running));
- }
- boost::thread::sleep(delay(1));
- CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,0U);
+ for(unsigned i=0;i<reader_count;++i)
+ {
+ pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_mutex,simultaneous_running_count,max_simultaneous_running));
+ }
+ boost::thread::sleep(delay(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,0U);
 
- write_lock.unlock();
+ write_lock.unlock();
     
- {
- boost::mutex::scoped_lock lk(unblocked_count_mutex);
- while(unblocked_count<reader_count)
         {
- unblocked_condition.wait(lk);
+ boost::mutex::scoped_lock lk(unblocked_count_mutex);
+ while(unblocked_count<reader_count)
+ {
+ unblocked_condition.wait(lk);
+ }
         }
- }
 
- CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count);
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count);
+
+ finish_lock.unlock();
+ pool.join_all();
+ }
+ catch(...)
+ {
+ pool.interrupt_all();
+ pool.join_all();
+ throw;
+ }
 
- finish_lock.unlock();
- pool.join_all();
     CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,reader_count);
 }
 
@@ -246,40 +284,51 @@
     unsigned const reader_count=100;
     unsigned const writer_count=100;
 
- for(unsigned i=0;i<reader_count;++i)
+ try
     {
- pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
- finish_reading_mutex,simultaneous_running_readers,max_simultaneous_readers));
- }
- boost::thread::sleep(delay(1));
- for(unsigned i=0;i<writer_count;++i)
- {
- pool.create_thread(locking_thread<boost::unique_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
- finish_writing_mutex,simultaneous_running_writers,max_simultaneous_writers));
- }
- {
- boost::mutex::scoped_lock lk(unblocked_count_mutex);
- while(unblocked_count<reader_count)
+ for(unsigned i=0;i<reader_count;++i)
         {
- unblocked_condition.wait(lk);
+ pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_reading_mutex,simultaneous_running_readers,max_simultaneous_readers));
         }
- }
- boost::thread::sleep(delay(1));
- CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count);
+ boost::thread::sleep(delay(1));
+ for(unsigned i=0;i<writer_count;++i)
+ {
+ pool.create_thread(locking_thread<boost::unique_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_writing_mutex,simultaneous_running_writers,max_simultaneous_writers));
+ }
+ {
+ boost::mutex::scoped_lock lk(unblocked_count_mutex);
+ while(unblocked_count<reader_count)
+ {
+ unblocked_condition.wait(lk);
+ }
+ }
+ boost::thread::sleep(delay(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count);
 
- finish_reading_lock.unlock();
+ finish_reading_lock.unlock();
 
- {
- boost::mutex::scoped_lock lk(unblocked_count_mutex);
- while(unblocked_count<(reader_count+1))
         {
- unblocked_condition.wait(lk);
+ boost::mutex::scoped_lock lk(unblocked_count_mutex);
+ while(unblocked_count<(reader_count+1))
+ {
+ unblocked_condition.wait(lk);
+ }
         }
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
+
+ finish_writing_lock.unlock();
+ pool.join_all();
+ }
+ catch(...)
+ {
+ pool.interrupt_all();
+ pool.join_all();
+ throw;
     }
- CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
 
- finish_writing_lock.unlock();
- pool.join_all();
+
     CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+writer_count);
     CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_readers,reader_count);
     CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_writers,1u);
@@ -300,19 +349,28 @@
     boost::mutex finish_mutex;
     boost::mutex::scoped_lock finish_lock(finish_mutex);
     
- for(unsigned i=0;i<number_of_threads;++i)
+ try
     {
- pool.create_thread(locking_thread<boost::upgrade_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
- finish_mutex,simultaneous_running_count,max_simultaneous_running));
- }
+ for(unsigned i=0;i<number_of_threads;++i)
+ {
+ pool.create_thread(locking_thread<boost::upgrade_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_mutex,simultaneous_running_count,max_simultaneous_running));
+ }
 
- boost::thread::sleep(delay(1));
+ boost::thread::sleep(delay(1));
 
- CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
 
- finish_lock.unlock();
+ finish_lock.unlock();
 
- pool.join_all();
+ pool.join_all();
+ }
+ catch(...)
+ {
+ pool.interrupt_all();
+ pool.join_all();
+ throw;
+ }
 
     CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,number_of_threads);
     CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1u);
@@ -333,25 +391,36 @@
 
     unsigned const reader_count=100;
 
- for(unsigned i=0;i<reader_count;++i)
- {
- pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
- finish_mutex,simultaneous_running_count,max_simultaneous_running));
- }
- boost::thread::sleep(delay(1));
- pool.create_thread(locking_thread<boost::upgrade_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
- finish_mutex,simultaneous_running_count,max_simultaneous_running));
+ try
     {
- boost::mutex::scoped_lock lk(unblocked_count_mutex);
- while(unblocked_count<(reader_count+1))
+ for(unsigned i=0;i<reader_count;++i)
         {
- unblocked_condition.wait(lk);
+ pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_mutex,simultaneous_running_count,max_simultaneous_running));
         }
+ boost::thread::sleep(delay(1));
+ pool.create_thread(locking_thread<boost::upgrade_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_mutex,simultaneous_running_count,max_simultaneous_running));
+ {
+ boost::mutex::scoped_lock lk(unblocked_count_mutex);
+ while(unblocked_count<(reader_count+1))
+ {
+ unblocked_condition.wait(lk);
+ }
+ }
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
+
+ finish_lock.unlock();
+ pool.join_all();
+ }
+ catch(...)
+ {
+ pool.interrupt_all();
+ pool.join_all();
+ throw;
     }
- CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
 
- finish_lock.unlock();
- pool.join_all();
+
     CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
     CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,reader_count+1);
 }

Modified: trunk/libs/thread/test/test_tss.cpp
==============================================================================
--- trunk/libs/thread/test/test_tss.cpp (original)
+++ trunk/libs/thread/test/test_tss.cpp 2007-11-14 06:56:53 EST (Wed, 14 Nov 2007)
@@ -100,9 +100,19 @@
 
     const int NUMTHREADS=5;
     boost::thread_group threads;
- for (int i=0; i<NUMTHREADS; ++i)
- threads.create_thread(&test_tss_thread);
- threads.join_all();
+ try
+ {
+ for (int i=0; i<NUMTHREADS; ++i)
+ threads.create_thread(&test_tss_thread);
+ threads.join_all();
+ }
+ catch(...)
+ {
+ threads.interrupt_all();
+ threads.join_all();
+ throw;
+ }
+
 
     std::cout
         << "tss_instances = " << tss_instances


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