* If the actor is restarted, the actor has a fresh copy of the function.
*/
static ActorPtr create(std::string name, s4u::Host* host, std::function<void()> code);
+ static ActorPtr init(std::string name, s4u::Host* host);
+ ActorPtr start(std::function<void()> code);
/** Create an actor from a std::function
*
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_kernel, msg, "Logging specific to MSG (kernel)");
MSG_Global_t msg_global = nullptr;
+simgrid::xbt::Extension<simgrid::s4u::Actor, simgrid::msg::ActorUserData> simgrid::msg::ActorUserData::EXTENSION_ID;
+
static void MSG_exit();
/********************************* MSG **************************************/
if (not msg_global) {
msg_global = new s_MSG_Global_t();
+ if (not simgrid::msg::ActorUserData::EXTENSION_ID.valid())
+ simgrid::msg::ActorUserData::EXTENSION_ID = simgrid::s4u::Actor::extension_create<simgrid::msg::ActorUserData>();
msg_global->debug_multiple_use = false;
simgrid::config::bind_flag(msg_global->debug_multiple_use, "msg/debug-multiple-use",
msg_global->task_copy_callback = nullptr;
msg_global->process_data_cleanup = nullptr;
+ simgrid::s4u::Actor::on_creation.connect([](simgrid::s4u::ActorPtr actor) {
+ XBT_DEBUG("creating the extension to store user data");
+ actor->extension_set(new simgrid::msg::ActorUserData(actor));
+ });
+
simgrid::s4u::Actor::on_destruction.connect([](simgrid::s4u::ActorPtr actor) {
// free the data if a function was provided
- void* userdata = actor->get_impl()->get_user_data();
+ void* userdata = actor->extension<simgrid::msg::ActorUserData>()->get_user_data();
if (userdata && msg_global->process_data_cleanup) {
msg_global->process_data_cleanup(userdata);
}
}
};
+class ActorUserData {
+ void* userdata_ = nullptr;
+ s4u::ActorPtr actor_ = nullptr;
+
+public:
+ static xbt::Extension<simgrid::s4u::Actor, ActorUserData> EXTENSION_ID;
+
+ explicit ActorUserData(s4u::ActorPtr ptr) : actor_(ptr) {}
+ ~ActorUserData() = default;
+
+ void set_user_data(void* data) { userdata_ = data; }
+ void* get_user_data() { return userdata_; }
+};
+
} // namespace msg
} // namespace simgrid
}
/******************************** Process ************************************/
-
/** @brief Creates and runs a new #msg_process_t.
*
* Does exactly the same as #MSG_process_create_with_arguments but without providing standard arguments
int argc, char **argv, xbt_dict_t properties)
{
xbt_assert(host != nullptr, "Invalid parameters: host param must not be nullptr");
-
simgrid::simix::ActorCode function;
if (code)
function = simgrid::xbt::wrap_main(code, argc, static_cast<const char* const*>(argv));
props[key] = value;
xbt_dict_free(&properties);
- smx_actor_t self = SIMIX_process_self();
- smx_actor_t actor = nullptr;
+ simgrid::s4u::ActorPtr actor = nullptr;
try {
- actor = simgrid::simix::simcall([name, function, data, host, &props, self] {
- return simgrid::kernel::actor::ActorImpl::create(std::move(name), std::move(function), data, host, &props, self)
- .get();
- });
+ actor = simgrid::s4u::Actor::init(std::move(name), host);
+ actor->extension<simgrid::msg::ActorUserData>()->set_user_data(data);
+ actor->start(std::move(function));
} catch (simgrid::HostFailureException const&) {
xbt_die("Could not create a new process on failed host %s.", host->get_cname());
}
return nullptr;
MSG_process_yield();
- return actor->ciface();
+ return actor.get();
}
/** @brief Returns the user data of a process.
xbt_assert(process != nullptr, "Invalid parameter: first parameter must not be nullptr!");
/* get from SIMIX the MSG process data, and then the user data */
- return process->get_impl()->get_user_data();
+ return process->extension<simgrid::msg::ActorUserData>()->get_user_data();
}
/** @brief Sets the user data of a process.
msg_error_t MSG_process_set_data(msg_process_t process, void *data)
{
xbt_assert(process != nullptr, "Invalid parameter: first parameter must not be nullptr!");
-
- process->get_impl()->set_user_data(data);
+ process->extension<simgrid::msg::ActorUserData>()->set_user_data(data);
return MSG_OK;
}
return self_context->get_actor()->iface();
}
+ActorPtr Actor::init(std::string name, s4u::Host* host)
+{
+ return SIMIX_process_self()->init(std::move(name), host)->iface();
+}
+
+ActorPtr Actor::start(std::function<void()> code)
+{
+ simgrid::simix::simcall([this, code] { return this->get_impl()->start(code); });
+ return this;
+}
ActorPtr Actor::create(std::string name, s4u::Host* host, std::function<void()> code)
{