]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Catch exceptions that are thrown in spawned sub-threads.
authorwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Mon, 14 Oct 2002 14:17:29 +0000 (14:17 +0000)
committerwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Mon, 14 Oct 2002 14:17:29 +0000 (14:17 +0000)
git-svn-id: https://svn.dealii.org/trunk@6638 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 3aa38635105097af701d1c1c896e5f3bb58fa7c6..55c18e55beffe3295a772c70271e6784fe736abc 100644 (file)
@@ -4734,6 +4734,44 @@ namespace Threads
                                     * functions below.
                                     */
   void deregister_new_thread ();  
+
+                                   /**
+                                    * If in a sub-thread an exception
+                                    * is thrown, it is not propagated
+                                    * to the main thread. Therefore,
+                                    * the exception handler that is
+                                    * provided by the applications
+                                    * main function or some of its
+                                    * other parts will not be able to
+                                    * catch these
+                                    * exceptions. Therefore, we have
+                                    * to provide an exception handler
+                                    * in the top function of each
+                                    * sub-thread that at least catches
+                                    * the exception and prints some
+                                    * information, rather than letting
+                                    * the operating system to just
+                                    * kill the program without a
+                                    * message. In each of the
+                                    * functions we use as entry points
+                                    * to new threads, we therefore
+                                    * install a try-catch block, and
+                                    * if an exception of type
+                                    * @p{std::exception} is caught, it
+                                    * passes over control to this
+                                    * function, which will then
+                                    * provide some output.
+                                    */
+  void handle_std_exception (const std::exception &exc);
+
+                                   /**
+                                    * Same as above, but the type of
+                                    * the exception is not derived
+                                    * from @p{std::exception}, so
+                                    * there is little way to provide
+                                    * something more useful.
+                                    */
+  void handle_unknown_exception ();
   
 };   // end declarations of namespace Threads
 
@@ -4797,11 +4835,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (*fun_ptr)();
+    try 
+      {
+        (*fun_ptr)();
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -4879,11 +4936,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (*fun_ptr)(arg1);
+    try 
+      {
+        (*fun_ptr)(arg1);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -4965,11 +5041,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (*fun_ptr)(arg1, arg2);
+    try 
+      {
+        (*fun_ptr)(arg1, arg2);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -5057,11 +5152,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (*fun_ptr)(arg1, arg2, arg3);
+    try 
+      {
+        (*fun_ptr)(arg1, arg2, arg3);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
 
     return 0;
@@ -5154,11 +5268,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (*fun_ptr)(arg1, arg2, arg3, arg4);
+    try 
+      {
+        (*fun_ptr)(arg1, arg2, arg3, arg4);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -5256,11 +5389,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (*fun_ptr)(arg1, arg2, arg3, arg4, arg5);
+    try 
+      {
+        (*fun_ptr)(arg1, arg2, arg3, arg4, arg5);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -5364,11 +5516,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6);
+    try 
+      {
+        (*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -5478,11 +5649,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+    try 
+      {
+        (*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -5599,11 +5789,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+    try 
+      {
+        (*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -5724,11 +5933,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
+    try 
+      {
+        (*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -5857,11 +6085,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
+    try 
+      {
+        (*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -5954,11 +6201,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (object->*fun_ptr)();
+    try 
+      {
+        (object->*fun_ptr)();
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -6050,11 +6316,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (object->*fun_ptr)(arg1);
+    try 
+      {
+        (object->*fun_ptr)(arg1);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -6150,11 +6435,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (object->*fun_ptr)(arg1, arg2);
+    try 
+      {
+        (object->*fun_ptr)(arg1, arg2);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -6258,11 +6562,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (object->*fun_ptr)(arg1, arg2, arg3);
+    try 
+      {
+        (object->*fun_ptr)(arg1, arg2, arg3);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -6373,11 +6696,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (object->*fun_ptr)(arg1, arg2, arg3, arg4);
+    try 
+      {
+        (object->*fun_ptr)(arg1, arg2, arg3, arg4);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -6493,11 +6835,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5);
+    try 
+      {
+        (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -6620,11 +6981,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6);
+    try 
+      {
+        (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -6755,11 +7135,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+    try 
+      {
+        (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -6893,11 +7292,30 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+    try 
+      {
+        (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -7037,11 +7455,31 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
+    try 
+      {
+        (object->*fun_ptr)(arg1, arg2, arg3, arg4,
+                           arg5, arg6, arg7, arg8, arg9);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
@@ -7187,11 +7625,31 @@ namespace Threads
                                     // @p{fun_data}
     fun_data->lock.release ();
 
-                                    // register new thread, call the
+                                     // register new thread, call the
                                     // function, and upon its return,
-                                    // de-register it again
+                                    // de-register it again. since an
+                                    // exception that is thrown from
+                                    // one of the called functions
+                                    // will not propagate to the main
+                                    // thread, it will kill the
+                                    // program if not treated here
+                                    // before we return to the
+                                    // operating system's thread
+                                    // library
     register_new_thread ();
-    (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
+    try 
+      {
+        (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5,
+                           arg6, arg7, arg8, arg9, arg10);
+      }
+    catch (const std::exception &exc)
+      {
+        handle_std_exception (exc);
+      }
+    catch (...)
+      {
+        handle_unknown_exception ();
+      };
     deregister_new_thread ();
   
     return 0;
index 3b1992923920d04881d7d50c821aeda1e2cb1db7..df4d4903feb6b2786e9b0c6743f8ca3eb8d4ee7f 100644 (file)
@@ -45,6 +45,49 @@ namespace Threads
   };
 
 
+
+  void handle_std_exception (const std::exception &exc) 
+  {
+    std::cerr << std::endl << std::endl
+              << "---------------------------------------------------------"
+              << std::endl
+              << "In one of the sub-threads of this program, an exception\n"
+              << "was thrown and not caught. Since exceptions do not\n"
+              << "propagate to the main thread, the library has caught it.\n"
+              << "The information carried by this exception is given below.\n"
+              << std::endl
+              << "---------------------------------------------------------"
+              << std::endl;
+    std::cerr << "Exception on processing: " << std::endl
+              << exc.what() << std::endl
+              << "Aborting!" << std::endl
+              << "---------------------------------------------------------"
+              << std::endl;
+    std::abort ();
+  };
+
+
+
+  void handle_unknown_exception ()
+  {
+    std::cerr << std::endl << std::endl
+              << "---------------------------------------------------------"
+              << std::endl
+              << "In one of the sub-threads of this program, an exception\n"
+              << "was thrown and not caught. Since exceptions do not\n"
+              << "propagate to the main thread, the library has caught it.\n"
+              << "The information carried by this exception is given below.\n"
+              << std::endl
+              << "---------------------------------------------------------"
+              << std::endl;
+    std::cerr << "Type of exception is unknown, but not std::exception.\n"
+              << "No additional information is available.\n"
+              << "---------------------------------------------------------"
+              << std::endl;
+    std::abort ();
+  };
+  
+
   
   unsigned int n_existing_threads () 
   {
index 563b071da1b02cb492cada139664e0e174f74c8d..bd5b29339a8c9f4f3770c8edcec22d177ce44298 100644 (file)
@@ -160,6 +160,19 @@ contributor's names are abbreviated by WB (Wolfgang Bangerth), GK
 <h3>base</h3>
 
 <ol>
+  <li> <p> Changed: When an exception is thrown but not caught in a sub-thread,
+       this exception is not passed to the main thread by the operating
+       system. Rather, if the exception is not caught from the function that
+       was invoked by the spawning system function, the entire program is
+       terminated without an additional message. The wrapper functions which
+       are used to spawn new threads in the <code class="class">Threads</code>
+       namespace therefore now catch these exceptions and at least print the
+       message they carry, before aborting the program. This way, at least the
+       message gets displayed.
+       <br>
+       (WB 2002/10/13)
+       </p>
+
   <li> <p> Changed: The class <code
        class="member">Table&lt;2&gt;::fill</code> function, which is also
        inherited from the <code class="class">FullMatrix</code> class, used to

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.