|
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 *, ...) |
@@ -133,14 +136,21 @@ TIMPIInit::TIMPIInit (int /* argc */, const char * const * /* argv */, |
133 | 136 | TIMPIInit::~TIMPIInit() |
134 | 137 | { |
135 | 138 | // Every processor had better be ready to exit at the same time. |
136 | | - // This would be a timpi_parallel_only() function, except that |
137 | | - // timpi_parallel_only() uses timpi_assert() which throws an |
138 | | - // exception which causes compilers to scream about exceptions |
139 | | - // inside destructors. |
140 | | - |
141 | 139 | // Even if we're not doing parallel_only debugging, we don't want |
142 | 140 | // one processor to try to exit until all others are done working. |
143 | | - this->comm().barrier(); |
| 141 | + |
| 142 | + // We could be destructing here because we're unwinding the stack |
| 143 | + // due to a thrown exception, though. It's possible that an |
| 144 | + // application is catching exceptions outside of the LibMeshInit |
| 145 | + // scope, or that we're using a C++ compiler that does unwinding |
| 146 | + // for uncaught exceptions (the standard says whether to go straight |
| 147 | + // to terminate() or unwind first is "implementation-defined"). If |
| 148 | + // *that* is the case then we can't safely communicate with other |
| 149 | + // processors that might not all be unwinding too. |
| 150 | +#ifdef TIMPI_ENABLE_EXCEPTIONS |
| 151 | + if (!std::uncaught_exceptions()) |
| 152 | +#endif |
| 153 | + this->comm().barrier(); |
144 | 154 |
|
145 | 155 | // Trigger any SemiPermanent cleanup before potentially finalizing MPI |
146 | 156 | _ref.reset(); |
|
0 commit comments