|
25 | 25 | #include "timpi/communicator.h" |
26 | 26 | #include "timpi/timpi_assert.h" |
27 | 27 |
|
| 28 | +#ifdef TIMPI_ENABLE_EXCEPTIONS |
| 29 | +#include <exception> // For std::uncaught_exceptions |
| 30 | +#endif |
28 | 31 |
|
29 | 32 | #ifdef TIMPI_HAVE_MPI |
30 | 33 | void TIMPI_MPI_Handler (MPI_Comm *, int *, ...) |
@@ -119,14 +122,21 @@ TIMPIInit::TIMPIInit (int /* argc */, const char * const * /* argv */, |
119 | 122 | TIMPIInit::~TIMPIInit() |
120 | 123 | { |
121 | 124 | // Every processor had better be ready to exit at the same time. |
122 | | - // This would be a timpi_parallel_only() function, except that |
123 | | - // timpi_parallel_only() uses timpi_assert() which throws an |
124 | | - // exception which causes compilers to scream about exceptions |
125 | | - // inside destructors. |
126 | | - |
127 | 125 | // Even if we're not doing parallel_only debugging, we don't want |
128 | 126 | // one processor to try to exit until all others are done working. |
129 | | - this->comm().barrier(); |
| 127 | + |
| 128 | + // We could be destructing here because we're unwinding the stack |
| 129 | + // due to a thrown exception, though. It's possible that an |
| 130 | + // application is catching exceptions outside of the LibMeshInit |
| 131 | + // scope, or that we're using a C++ compiler that does unwinding |
| 132 | + // for uncaught exceptions (the standard says whether to go straight |
| 133 | + // to terminate() or unwind first is "implementation-defined"). If |
| 134 | + // *that* is the case then we can't safely communicate with other |
| 135 | + // processors that might not all be unwinding too. |
| 136 | +#ifdef TIMPI_ENABLE_EXCEPTIONS |
| 137 | + if (!std::uncaught_exceptions()) |
| 138 | +#endif |
| 139 | + this->comm().barrier(); |
130 | 140 |
|
131 | 141 | // Trigger any SemiPermanent cleanup before potentially finalizing MPI |
132 | 142 | _ref.reset(); |
|
0 commit comments