]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Fix a problem with calling pthread_join on the same threads more than once.
authorwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Thu, 16 Jan 2003 18:12:00 +0000 (18:12 +0000)
committerwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Thu, 16 Jan 2003 18:12:00 +0000 (18:12 +0000)
git-svn-id: https://svn.dealii.org/trunk@6924 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/base/include/base/thread_management.h
deal.II/base/source/thread_management.cc
deal.II/doc/news/2002/c-3-4.html

index 59926954a1effb91229e8572625eda4aa2ceebff..2f49b541cf9cd334035a0bc48b1aacb7997d41c8 100644 (file)
@@ -482,6 +482,13 @@ namespace Threads
       void wait () const;
 
     private:
+                                      /**
+                                       * Copy constructor. Made
+                                       * private since copying these
+                                       * kinds of objects is a no-go.
+                                       */
+      PosixThreadManager (const PosixThreadManager &) {};
+      
                                       /**
                                        * List of thread ids. This
                                        * variable actually points to
@@ -493,7 +500,13 @@ namespace Threads
                                        * files including it, we use a
                                        * void pointer instead.
                                        */
-      void * const thread_id_list;
+      volatile void * const thread_id_list;
+
+                                      /**
+                                       * Mutex by which we guard all
+                                       * accesses to the thread list.
+                                       */
+      PosixThreadMutex list_mutex;
   };
   
   
index 494be8a6600b520890631e26c0405d1566391aaa..4252dc99ed1dda34489c168d31c070a26b01123f 100644 (file)
@@ -233,7 +233,11 @@ namespace Threads
                                     // wait for all threads, and
                                     // release memory
     wait ();
-    delete reinterpret_cast<std::list<pthread_t>*>(thread_id_list);
+    list_mutex.acquire ();
+    if (thread_id_list != 0)
+      delete reinterpret_cast<std::list<pthread_t>*>(thread_id_list);
+    thread_id_list = 0;
+    list_mutex.release ();
   }
 
 
@@ -246,7 +250,10 @@ namespace Threads
     std::list<pthread_t> &tid_list
       = *reinterpret_cast<std::list<pthread_t>*>(thread_id_list);
 
+    list_mutex.acquire ();
     tid_list.push_back (pthread_t());
+    pthread_t *tid = &tid_list.back();
+    list_mutex.release ();
 
                                      // start new thread. retry until
                                      // we either succeed or get an
@@ -254,11 +261,11 @@ namespace Threads
     int error = 0;
     do 
       {
-       error = pthread_create (&tid_list.back(), 0, fun_ptr, fun_data);
+       error = pthread_create (tid, 0, fun_ptr, fun_data);
       }
     while (error == EAGAIN);
 
-    Assert (error == 0, ExcInternalError());
+    AssertThrow (error == 0, ExcInternalError());
   }
   
 
@@ -266,12 +273,26 @@ namespace Threads
   void
   PosixThreadManager::wait () const
   {
+    list_mutex.acquire ();
     std::list<pthread_t> &tid_list
       = *reinterpret_cast<std::list<pthread_t>*>(thread_id_list);
 
+                                    // wait for all the threads in
+                                    // turn
     for (std::list<pthread_t>::iterator i=tid_list.begin();
         i != tid_list.end(); ++i)
       pthread_join (*i, 0);
+
+                                    // now we know that these threads
+                                    // have finished, remove their
+                                    // tid's from the list. this way,
+                                    // when new threads are spawned
+                                    // and waited for, we won't wait
+                                    // for expired threads with their
+                                    // invalid handles again
+    tid_list.clear ();
+    
+    list_mutex.release ();
   }
   
 #  endif
index 17fdaa6f58917b76703b5c44014fdf311824ab95..5dfd5e09fbacb507895c0fea68058a9367bcf21e 100644 (file)
@@ -234,6 +234,19 @@ contributor's names are abbreviated by WB (Wolfgang Bangerth), GK
 <h3>base</h3>
 
 <ol>
+  <li> <p> 
+       Fixed: The <code class="class">PosixThreadManager</code> called
+       its <code class="member">wait</code> function in the
+       destructor. If this had been called before already, then the
+       same threads would have been waited for twice, which invokes
+       undefined behavior. This is fixed by making sure that <code
+       class="member">wait</code> removes the id's of the threads it
+       has already waited for, and so calling it more than once will
+       not wait for threads which have already been waited for.
+       <br>
+       (Michael Anderson, WB 2003/01/16)
+       </p>
+
   <li> <p> 
        Fixed: The <code class="class">Subscriptor</code> uses a counter to
        count how many <code class="class">SmartPointer</code> objects subscribe
@@ -242,7 +255,7 @@ contributor's names are abbreviated by WB (Wolfgang Bangerth), GK
        the assumption that the variable cannot change between two subsequent
        reads.
        <br>
-       (Michael Anderson, WB 2003/01/11)
+       (WB 2003/01/11)
        </p>
 
   <li> <p> 

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.