From 8695e982e8a17d4d42259356d151cab27203f60d Mon Sep 17 00:00:00 2001 From: Rene Gassmoeller Date: Mon, 17 Oct 2022 15:17:18 -0400 Subject: [PATCH] Remove communication during stack unwinding. --- source/base/mpi.cc | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/source/base/mpi.cc b/source/base/mpi.cc index 33e1160f22..605c00fffd 100644 --- a/source/base/mpi.cc +++ b/source/base/mpi.cc @@ -1143,20 +1143,33 @@ namespace Utilities 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 - - // 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 __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): # 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; } -- 2.39.5