]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Abort when exception is uncaught. 14356/head
authorRene Gassmoeller <rene.gassmoeller@mailbox.org>
Thu, 20 Oct 2022 13:56:37 +0000 (09:56 -0400)
committerRene Gassmoeller <rene.gassmoeller@mailbox.org>
Thu, 20 Oct 2022 13:57:48 +0000 (09:57 -0400)
source/base/mpi.cc

index 605c00fffd7bc71b35219c49679fa2ee98fe9865..cb58254d592e1fbc28dd40714e3b3e6c316a7a8e 100644 (file)
@@ -1078,6 +1078,46 @@ namespace Utilities
 
 
 
+    namespace internal
+    {
+      namespace CollectiveMutexImplementation
+      {
+        /**
+         * Abort, should there be an exception being processed (see the error
+         * message).
+         */
+        void
+        check_exception()
+        {
+#ifdef DEAL_II_WITH_MPI
+#  if __cpp_lib_uncaught_exceptions >= 201411
+          // std::uncaught_exception() is deprecated in c++17
+          if (std::uncaught_exceptions() != 0)
+#  else
+          if (std::uncaught_exception() == true)
+#  endif
+            {
+              std::cerr
+                << "---------------------------------------------------------\n"
+                << "An exception was thrown inside a section of the program\n"
+                << "guarded by a CollectiveMutex.\n"
+                << "Because a CollectiveMutex guards critical communication\n"
+                << "handling the exception would likely\n"
+                << "deadlock because only the current process is aware of the\n"
+                << "exception. To prevent this deadlock, the program will be\n"
+                << "aborted.\n"
+                << "---------------------------------------------------------"
+                << std::endl;
+
+              MPI_Abort(MPI_COMM_WORLD, 1);
+            }
+#endif
+        }
+      } // namespace CollectiveMutexImplementation
+    }   // namespace internal
+
+
+
     CollectiveMutex::CollectiveMutex()
       : locked(false)
       , request(MPI_REQUEST_NULL)
@@ -1089,6 +1129,10 @@ namespace Utilities
 
     CollectiveMutex::~CollectiveMutex()
     {
+      // First check if this destructor is called during exception handling
+      // if so, abort.
+      internal::CollectiveMutexImplementation::check_exception();
+
       Assert(
         !locked,
         ExcMessage(
@@ -1138,38 +1182,29 @@ namespace Utilities
     {
       (void)comm;
 
+      // First check if this function is called during exception handling
+      // if so, abort. This can happen if a ScopedLock is destroyed.
+      internal::CollectiveMutexImplementation::check_exception();
+
       Assert(
         locked,
         ExcMessage(
           "Error: MPI::CollectiveMutex needs to be locked before unlock()"));
 
-      // Only communicate with other processes if there is no uncaught
-      // exception to avoid a deadlock.
 #ifdef DEAL_II_WITH_MPI
-#  if __cpp_lib_uncaught_exceptions >= 201411
-      // std::uncaught_exception() is deprecated in c++17
-      if (std::uncaught_exceptions() == 0 && comm != MPI_COMM_SELF)
-#  else
-      if (std::uncaught_exception() == false && comm != MPI_COMM_SELF)
-#  endif
-        {
-          // TODO: For now, we implement this mutex with a blocking barrier
-          // in the lock and unlock. It needs to be tested, if we can move
-          // to a nonblocking barrier (code disabled below):
+
+      // TODO: For now, we implement this mutex with a blocking barrier
+      // in the lock and unlock. It needs to be tested, if we can move
+      // to a nonblocking barrier (code disabled below):
 #  if 0
-          const int ierr = MPI_Ibarrier(comm, &request);
-          AssertThrowMPI(ierr);
+      const int ierr = MPI_Ibarrier(comm, &request);
+      AssertThrowMPI(ierr);
 #  else
-          const int ierr = MPI_Barrier(comm);
-          AssertThrowMPI(ierr);
+      const int ierr = MPI_Barrier(comm);
+      AssertThrowMPI(ierr);
 #  endif
-        }
 #endif
 
-      // Unlock the mutex in either case. Either we successfully
-      // synchronized processes in the barrier, or we want to
-      // continue to unwind the stack without throwing exceptions
-      // in the destructor of this class.
       locked = false;
     }
 

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.