From: Martin Quinson Date: Sat, 25 Aug 2018 22:36:16 +0000 (+0200) Subject: Do not convert TimeoutError to xbt_ex(timeout) in case they were a wait_any X-Git-Tag: v3_21~166 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/c89cb255c89dd438dd1188565e98063da7dec57d Do not convert TimeoutError to xbt_ex(timeout) in case they were a wait_any If there is an issue while dealing with a test_any or a wait_any, the caller must be told which activity failed. I'm not sure of how to cleanly do so. For now, we use exception.value to store the rank of that activity in the container. To modify the exception, C++ leaves us no way but to rethrow it and recatch it, change its value field, and re-store it in the issuer->exception. But then, the exception become of the catching type. Wicked! Vicious! It means that since we were catching (xbt_ex& e), we actually converted the simgrid::TimeoutException into a xbt_ex. And this conversion was done in any case, even if the value was set only if the simcall was actually a wait_any or test_any... With this commit, we catch, extend and rethrow any TimeoutException, and if it's not such an xbt_ex, we do the same for a xbt_ex. A proper version could involve a WaitAnyException (with failing_rank and cause fields), or maybe the TimeoutException could contain a pointer to the timeouted activity so that the caller can find its rank by itself. --- diff --git a/src/simix/smx_network.cpp b/src/simix/smx_network.cpp index 6599c019e5..22c19a4435 100644 --- a/src/simix/smx_network.cpp +++ b/src/simix/smx_network.cpp @@ -584,26 +584,36 @@ void SIMIX_comm_finish(smx_activity_t synchro) } /* if there is an exception during a waitany or a testany, indicate the position of the failed communication */ - if (simcall->issuer->exception) { + if (simcall->issuer->exception && + (simcall->call == SIMCALL_COMM_WAITANY || simcall->call == SIMCALL_COMM_TESTANY)) { + // First retrieve the rank of our failing synchro + int rank; + if (simcall->call == SIMCALL_COMM_WAITANY) { + rank = xbt_dynar_search(simcall_comm_waitany__get__comms(simcall), &synchro); + } else if (simcall->call == SIMCALL_COMM_TESTANY) { + rank = -1; + auto* comms = simcall_comm_testany__get__comms(simcall); + auto count = simcall_comm_testany__get__count(simcall); + auto element = std::find(comms, comms + count, synchro); + if (element == comms + count) + rank = -1; + else + rank = element - comms; + } + // In order to modify the exception we have to rethrow it: try { std::rethrow_exception(simcall->issuer->exception); - } - catch(xbt_ex& e) { - if (simcall->call == SIMCALL_COMM_WAITANY) { - e.value = xbt_dynar_search(simcall_comm_waitany__get__comms(simcall), &synchro); - } - else if (simcall->call == SIMCALL_COMM_TESTANY) { - e.value = -1; - auto* comms = simcall_comm_testany__get__comms(simcall); - auto count = simcall_comm_testany__get__count(simcall); - auto element = std::find(comms, comms + count, synchro); - if (element == comms + count) - e.value = -1; - else - e.value = element - comms; - } + } catch (simgrid::TimeoutError& e) { + e.value = rank; simcall->issuer->exception = std::make_exception_ptr(e); + } catch (xbt_ex& e) { + if (e.category == network_error || e.category == cancel_error) { + e.value = rank; + simcall->issuer->exception = std::make_exception_ptr(e); + } else { + xbt_die("Unexpected xbt_ex(%s). Please enhance this code", xbt_ex_catname(e.category)); + } } catch(...) { // Nothing to do