Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions src/utilities/src/timpi_init.C
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#include "timpi/communicator.h"
#include "timpi/timpi_assert.h"

#ifdef TIMPI_ENABLE_EXCEPTIONS
#include <exception> // For std::uncaught_exceptions
#endif

#ifdef TIMPI_HAVE_MPI
void TIMPI_MPI_Handler (MPI_Comm *, int *, ...)
Expand Down Expand Up @@ -119,14 +122,21 @@ TIMPIInit::TIMPIInit (int /* argc */, const char * const * /* argv */,
TIMPIInit::~TIMPIInit()
{
// Every processor had better be ready to exit at the same time.
// This would be a timpi_parallel_only() function, except that
// timpi_parallel_only() uses timpi_assert() which throws an
// exception which causes compilers to scream about exceptions
// inside destructors.

// Even if we're not doing parallel_only debugging, we don't want
// one processor to try to exit until all others are done working.
this->comm().barrier();

// We could be destructing here because we're unwinding the stack
// due to a thrown exception, though. It's possible that an
// application is catching exceptions outside of the LibMeshInit
// scope, or that we're using a C++ compiler that does unwinding
// for uncaught exceptions (the standard says whether to go straight
// to terminate() or unwind first is "implementation-defined"). If
// *that* is the case then we can't safely communicate with other
// processors that might not all be unwinding too.
#ifdef TIMPI_ENABLE_EXCEPTIONS
if (!std::uncaught_exceptions())
#endif
this->comm().barrier();

// Trigger any SemiPermanent cleanup before potentially finalizing MPI
_ref.reset();
Expand Down