From: Martin Quinson Date: Mon, 4 Mar 2019 22:28:38 +0000 (+0100) Subject: Move ForcefulKillException to the root namespace, along with the other exceptions X-Git-Tag: v3_22~180^2~3 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/55e6d07cfba4948a918765e9d6fd2801d3639a4a Move ForcefulKillException to the root namespace, along with the other exceptions --- diff --git a/include/simgrid/Exception.hpp b/include/simgrid/Exception.hpp index 321b9568d9..0f3a5e3a6d 100644 --- a/include/simgrid/Exception.hpp +++ b/include/simgrid/Exception.hpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -164,6 +165,44 @@ public: } }; +class XBT_PUBLIC ForcefulKillException { + /** @brief Exception launched to kill an actor; DO NOT BLOCK IT! + * + * This exception is thrown whenever the actor's host is turned off. The actor stack is properly unwinded to release + * all objects allocated on the stack (RAII powa). + * + * You may want to catch this exception to perform some extra cleanups in your simulation, but YOUR ACTORS MUST NEVER + * SURVIVE a ForcefulKillException, or your simulation will segfault. + * + * @verbatim + * void* payload = malloc(512); + * + * try { + * simgrid::s4u::this_actor::execute(100000); + * } catch (simgrid::kernel::context::ForcefulKillException& e) { // oops, my host just turned off + * free(malloc); + * throw; // I shall never survive on an host that was switched off + * } + * @endverbatim + */ + /* Nope, Sonar, this should not inherit of std::exception nor of simgrid::Exception. + * Otherwise, users may accidentally catch it with a try {} catch (std::exception) + */ +public: + ForcefulKillException() = default; + explicit ForcefulKillException(const std::string& msg) : msg_(std::string("Actor killed (") + msg + std::string(").")) + { + } + ~ForcefulKillException(); + const char* what() const noexcept { return msg_.c_str(); } + + static void do_throw(); + static bool try_n_catch(std::function try_block); + +private: + std::string msg_ = std::string("Actor killed."); +}; + } // namespace simgrid #endif diff --git a/src/bindings/java/jmsg.cpp b/src/bindings/java/jmsg.cpp index 17a86a4d30..ebe959756d 100644 --- a/src/bindings/java/jmsg.cpp +++ b/src/bindings/java/jmsg.cpp @@ -277,7 +277,7 @@ static void run_jprocess(JNIEnv *env, jobject jprocess) env->ExceptionClear(); XBT_ATTRIB_UNUSED jint error = __java_vm->DetachCurrentThread(); xbt_assert(error == JNI_OK, "Cannot detach failing thread"); - simgrid::kernel::context::ForcefulKillException::do_throw(); + simgrid::ForcefulKillException::do_throw(); } } diff --git a/src/bindings/java/jmsg_host.cpp b/src/bindings/java/jmsg_host.cpp index 63d90994a4..550c172ec5 100644 --- a/src/bindings/java/jmsg_host.cpp +++ b/src/bindings/java/jmsg_host.cpp @@ -5,6 +5,7 @@ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include "simgrid/Exception.hpp" #include "simgrid/plugins/energy.h" #include "simgrid/plugins/load.h" #include "simgrid/s4u/Host.hpp" @@ -142,7 +143,7 @@ JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_on(JNIEnv *env, jobject jhost) JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_off(JNIEnv *env, jobject jhost) { msg_host_t host = jhost_get_native(env, jhost); - if (not simgrid::kernel::context::ForcefulKillException::try_n_catch([host]() { MSG_host_off(host); })) + if (not simgrid::ForcefulKillException::try_n_catch([host]() { MSG_host_off(host); })) jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", "Host turned off"); } diff --git a/src/bindings/java/jmsg_process.cpp b/src/bindings/java/jmsg_process.cpp index 0d0866cba9..0cfc8057dd 100644 --- a/src/bindings/java/jmsg_process.cpp +++ b/src/bindings/java/jmsg_process.cpp @@ -229,8 +229,7 @@ JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_sleep(JNIEnv *env, jclass cl { double time = ((double)jmillis) / 1000 + ((double)jnanos) / 1000000000; msg_error_t rv = MSG_OK; - if (not simgrid::kernel::context::ForcefulKillException::try_n_catch( - [&time]() { simgrid::s4u::this_actor::sleep_for(time); })) { + if (not simgrid::ForcefulKillException::try_n_catch([&time]() { simgrid::s4u::this_actor::sleep_for(time); })) { rv = MSG_HOST_FAILURE; } if (rv != MSG_OK) { @@ -241,7 +240,7 @@ JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_sleep(JNIEnv *env, jclass cl JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_waitFor(JNIEnv * env, jobject jprocess, jdouble jseconds) { msg_error_t rv = MSG_OK; - if (not simgrid::kernel::context::ForcefulKillException::try_n_catch( + if (not simgrid::ForcefulKillException::try_n_catch( [&jseconds]() { simgrid::s4u::this_actor::sleep_for((double)jseconds); })) { rv = MSG_HOST_FAILURE; jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", "Process killed"); @@ -262,7 +261,7 @@ JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_kill(JNIEnv * env, jobject j jxbt_throw_notbound(env, "process", jprocess); return; } - if (not simgrid::kernel::context::ForcefulKillException::try_n_catch([&process]() { MSG_process_kill(process); })) { + if (not simgrid::ForcefulKillException::try_n_catch([&process]() { MSG_process_kill(process); })) { jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", "Process killed"); } } diff --git a/src/bindings/java/jmsg_task.cpp b/src/bindings/java/jmsg_task.cpp index 67b88f2682..1983b13579 100644 --- a/src/bindings/java/jmsg_task.cpp +++ b/src/bindings/java/jmsg_task.cpp @@ -5,6 +5,7 @@ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include "simgrid/Exception.hpp" #include "simgrid/s4u/Host.hpp" #include "src/kernel/context/Context.hpp" @@ -127,8 +128,7 @@ JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_execute(JNIEnv * env, jobject j return; } msg_error_t rv; - if (not simgrid::kernel::context::ForcefulKillException::try_n_catch( - [&rv, &task]() { rv = MSG_task_execute(task); })) { + if (not simgrid::ForcefulKillException::try_n_catch([&rv, &task]() { rv = MSG_task_execute(task); })) { jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", "Process killed"); } @@ -287,7 +287,7 @@ JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_receive(JNIEnv* env, jclass const char *alias = env->GetStringUTFChars(jalias, 0); msg_error_t rv; - if (not simgrid::kernel::context::ForcefulKillException::try_n_catch([&rv, &task, &alias, &jtimeout]() { + if (not simgrid::ForcefulKillException::try_n_catch([&rv, &task, &alias, &jtimeout]() { rv = MSG_task_receive_ext(&task, alias, (double)jtimeout, /*host*/ nullptr); })) { jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", "Process killed"); diff --git a/src/bindings/java/jmsg_vm.cpp b/src/bindings/java/jmsg_vm.cpp index 7102bb443a..b917e08303 100644 --- a/src/bindings/java/jmsg_vm.cpp +++ b/src/bindings/java/jmsg_vm.cpp @@ -151,7 +151,7 @@ JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_nativeMigration(JNIEnv* env, jobj { msg_vm_t vm = jvm_get_native(env,jvm); msg_host_t host = jhost_get_native(env, jhost); - if (not simgrid::kernel::context::ForcefulKillException::try_n_catch([&vm, &host]() { MSG_vm_migrate(vm, host); })) { + if (not simgrid::ForcefulKillException::try_n_catch([&vm, &host]() { MSG_vm_migrate(vm, host); })) { XBT_VERB("Caught exception during migration"); jxbt_throw_host_failure(env, "during migration"); } diff --git a/src/bindings/python/simgrid_python.cpp b/src/bindings/python/simgrid_python.cpp index f9074bf6f9..5a13a8aa02 100644 --- a/src/bindings/python/simgrid_python.cpp +++ b/src/bindings/python/simgrid_python.cpp @@ -13,6 +13,7 @@ #include #include "src/kernel/context/Context.hpp" +#include #include #include #include @@ -56,8 +57,7 @@ PYBIND11_MODULE(simgrid, m) m.attr("simgrid_version") = simgrid_version; // Internal exception used to kill actors and sweep the RAII chimney (free objects living on the stack) - py::object pyForcefulKillEx = - py::register_exception(m, "ActorKilled"); + py::object pyForcefulKillEx = py::register_exception(m, "ActorKilled"); /* this_actor namespace */ void (*sleep_for_fun)(double) = &simgrid::s4u::this_actor::sleep_for; // pick the right overload diff --git a/src/kernel/context/Context.cpp b/src/kernel/context/Context.cpp index 51b492a20b..dedbf2c147 100644 --- a/src/kernel/context/Context.cpp +++ b/src/kernel/context/Context.cpp @@ -112,25 +112,6 @@ void Context::stop() AttachContext::~AttachContext() = default; -ForcefulKillException::~ForcefulKillException() = default; - -void ForcefulKillException::do_throw() -{ - throw ForcefulKillException(); -} - -bool ForcefulKillException::try_n_catch(std::function try_block) -{ - bool res; - try { - try_block(); - res = true; - } catch (ForcefulKillException const&) { - XBT_DEBUG("Caught a ForcefulKillException"); - res = false; - } - return res; -} }}} /** @brief Executes all the processes to run (in parallel if possible). */ diff --git a/src/kernel/context/Context.hpp b/src/kernel/context/Context.hpp index cff4dbe386..97b99e22ac 100644 --- a/src/kernel/context/Context.hpp +++ b/src/kernel/context/Context.hpp @@ -86,43 +86,6 @@ public: virtual void attach_stop() = 0; }; -class XBT_PUBLIC ForcefulKillException { - /** @brief Exception launched to kill an actor; DO NOT BLOCK IT! - * - * This exception is thrown whenever the actor's host is turned off. The actor stack is properly unwinded to release - * all objects allocated on the stack (RAII powa). - * - * You may want to catch this exception to perform some extra cleanups in your simulation, but YOUR ACTORS MUST NEVER - * SURVIVE a ForcefulKillException, or your simulation will segfault. - * - * @verbatim - * void* payload = malloc(512); - * - * try { - * simgrid::s4u::this_actor::execute(100000); - * } catch (simgrid::kernel::context::ForcefulKillException& e) { // oops, my host just turned off - * free(malloc); - * throw; // I shall never survive on an host that was switched off - * } - * @endverbatim - * - * Nope, Sonar, this should not inherit of std::exception nor of simgrid::Exception. - * Otherwise, users may accidentally catch it with a try {} catch (std::exception) - */ -public: - ForcefulKillException() = default; - explicit ForcefulKillException(const std::string& msg) : msg_(std::string("Actor killed (") + msg + std::string(").")) - { - } - ~ForcefulKillException(); - const char* what() const noexcept { return msg_.c_str(); } - - static void do_throw(); - static bool try_n_catch(std::function try_block); - -private: - std::string msg_ = std::string("Actor killed."); -}; /* This allows Java to hijack the context factory (Java induces factories of factory :) */ typedef ContextFactory* (*ContextFactoryInitializer)(); diff --git a/src/kernel/context/ContextSwapped.cpp b/src/kernel/context/ContextSwapped.cpp index 11477407ff..9f402179b9 100644 --- a/src/kernel/context/ContextSwapped.cpp +++ b/src/kernel/context/ContextSwapped.cpp @@ -3,6 +3,7 @@ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include "simgrid/Exception.hpp" #include "simgrid/modelchecker.h" #include "src/internal_config.h" #include "src/kernel/context/context_private.hpp" diff --git a/src/kernel/context/ContextUnix.cpp b/src/kernel/context/ContextUnix.cpp index 2d6fcce015..be6fbc9075 100644 --- a/src/kernel/context/ContextUnix.cpp +++ b/src/kernel/context/ContextUnix.cpp @@ -41,7 +41,7 @@ static void smx_ctx_wrapper(int i1, int i2) try { (*context)(); context->Context::stop(); - } catch (simgrid::kernel::context::ForcefulKillException const&) { + } catch (simgrid::ForcefulKillException const&) { XBT_DEBUG("Caught a ForcefulKillException"); } catch (simgrid::Exception const& e) { XBT_INFO("Actor killed by an uncatched exception %s", simgrid::xbt::demangle(typeid(e).name()).get()); diff --git a/src/simgrid/Exception.cpp b/src/simgrid/Exception.cpp new file mode 100644 index 0000000000..cd4fc1fa22 --- /dev/null +++ b/src/simgrid/Exception.cpp @@ -0,0 +1,31 @@ +/* Copyright (c) 2018-2019. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include + +XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context); + +namespace simgrid { + +ForcefulKillException::~ForcefulKillException() = default; + +void ForcefulKillException::do_throw() +{ + throw ForcefulKillException(); +} + +bool ForcefulKillException::try_n_catch(std::function try_block) +{ + bool res; + try { + try_block(); + res = true; + } catch (ForcefulKillException const&) { + XBT_DEBUG("Caught a ForcefulKillException"); + res = false; + } + return res; +} +} // namespace simgrid diff --git a/src/simix/ActorImpl.cpp b/src/simix/ActorImpl.cpp index bcbe884846..61d4cfba75 100644 --- a/src/simix/ActorImpl.cpp +++ b/src/simix/ActorImpl.cpp @@ -164,7 +164,7 @@ void ActorImpl::exit() // Forcefully kill the actor if its host is turned off. Not a HostFailureException because you should not survive that if (not host_->is_on()) - this->throw_exception(std::make_exception_ptr(simgrid::kernel::context::ForcefulKillException("host failed"))); + this->throw_exception(std::make_exception_ptr(ForcefulKillException("host failed"))); /* destroy the blocking synchro if any */ if (waiting_synchro != nullptr) { diff --git a/src/xbt/exception.cpp b/src/xbt/exception.cpp index a87ac86da6..41db24db88 100644 --- a/src/xbt/exception.cpp +++ b/src/xbt/exception.cpp @@ -145,7 +145,7 @@ static void handler() std::abort(); } - catch (simgrid::kernel::context::ForcefulKillException& e) { + catch (simgrid::ForcefulKillException const& e) { XBT_ERROR("Received a ForcefulKillException at the top-level exception handler. Maybe a Java->C++ call that is not " "protected " "in a try/catch?"); diff --git a/tools/cmake/DefinePackages.cmake b/tools/cmake/DefinePackages.cmake index 718320030f..74880bc966 100644 --- a/tools/cmake/DefinePackages.cmake +++ b/tools/cmake/DefinePackages.cmake @@ -444,6 +444,7 @@ set(S4U_SRC ) set(SIMGRID_SRC + src/simgrid/Exception.cpp src/simgrid/sg_config.cpp src/simgrid/util.hpp )