$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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