- .def("register_actor", [](Engine*, std::string name, py::object obj) {
- simgrid::simix::register_function(name,
- [obj](std::vector<std::string> args) -> simgrid::simix::ActorCode {
- return [obj, args]() {
- /* Convert the std::vector into a py::tuple */
- py::tuple params(args.size()-1);
- for (size_t i=1; i<args.size(); i++)
- params[i-1] = py::cast(args[i]);
-
- PyObject *result = PyObject_CallObject(obj.ptr(), params.ptr());
- if (!result)
- throw pybind11::error_already_set();
-
- /* If I was passed a class, I just built an instance, so I need to call it now */
- if (PyCallable_Check(result)) {
- py::object obj2 = pybind11::reinterpret_steal<py::object>(pybind11::handle(static_cast<PyObject*>(result)));
- obj2();
- }
- };
- });
- }, "Registers the main function of an actor, see :cpp:func:`simgrid::s4u::Engine::register_function()`")
- ;
+ .def("register_actor",
+ [pyForcefulKillEx](Engine*, const std::string& name, py::object fun_or_class) {
+ simgrid::simix::register_function(
+ name, [pyForcefulKillEx, fun_or_class](std::vector<std::string> args) -> simgrid::simix::ActorCode {
+ return [pyForcefulKillEx, fun_or_class, args]() {
+ try {
+ /* Convert the std::vector into a py::tuple */
+ py::tuple params(args.size() - 1);
+ for (size_t i = 1; i < args.size(); i++)
+ params[i - 1] = py::cast(args[i]);
+
+ py::object res = fun_or_class(*params);
+
+ /* If I was passed a class, I just built an instance, so I need to call it now */
+ if (py::isinstance<py::function>(res))
+ res();
+ } catch (py::error_already_set& ex) {
+ if (ex.matches(pyForcefulKillEx)) {
+ XBT_VERB("Actor killed");
+ /* Stop here that ForcefulKill exception which was meant to free the RAII stuff on the stack */
+ } else {
+ throw;
+ }
+ }
+ };
+ });
+ },
+ "Registers the main function of an actor, see :cpp:func:`simgrid::s4u::Engine::register_function()`");