XBT_PUBLIC(MSG_error_t) MSG_process_suspend(m_process_t process);
XBT_PUBLIC(MSG_error_t) MSG_process_resume(m_process_t process);
XBT_PUBLIC(int) MSG_process_is_suspended(m_process_t process);
+XBT_PUBLIC(void) MSG_process_on_exit_add(int_f_pvoid_t fun, void *data);
/************************** Task handling ************************************/
XBT_PUBLIC(m_task_t) MSG_task_create(const char *name,
smx_context_t MSG_process_get_smx_ctx(m_process_t process) {
return SIMIX_process_get_context(process);
}
+/**
+ * \ingroup m_process_management
+ * \brief Add a function to the list of "on_exit" functions for the current process.
+ * The on_exit functions are the functions executed when your process is killed.
+ * You should use them to free the data used by your process.
+ */
+void MSG_process_on_exit_add(int_f_pvoid_t fun, void *data) {
+ SIMIX_process_on_exit_add(fun,data);
+}
void smx_ctx_base_stop(smx_context_t context)
{
+ SIMIX_process_on_exit(context->data);
if (context->cleanup_func)
context->cleanup_func(context->data);
context->iwannadie = 0;
XBT_DEBUG("Start context '%s'", (*process)->name);
+ /* Build the dynars for the on_exit functions */
+ (*process)->on_exit_fun = xbt_dynar_new(sizeof(int_f_pvoid_t),NULL);
+ (*process)->on_exit_args = xbt_dynar_new(sizeof(void*),NULL);
/* Now insert it in the global process list and in the process to run list */
xbt_swag_insert(*process, simix_global->process_list);
XBT_DEBUG("Inserting %s(%s) in the to_run list", (*process)->name, host->name);
}
return res;
}
+void SIMIX_process_on_exit(smx_process_t process) {
+ int length = xbt_dynar_length(process->on_exit_fun);
+ int cpt;
+ int_f_pvoid_t fun;
+ void *data;
+ for (cpt = 0; cpt < length; cpt++) {
+ fun = xbt_dynar_get_as(process->on_exit_fun,cpt,int_f_pvoid_t);
+ data = xbt_dynar_get_as(process->on_exit_args,cpt,void*);
+ (fun)(data);
+ }
+}
+void SIMIX_process_on_exit_add(int_f_pvoid_t fun, void *data) {
+ smx_process_t process = SIMIX_process_self();
+ xbt_assert(process, "current process not found: are you in maestro context ?");
+ xbt_dynar_push_as(process->on_exit_fun,int_f_pvoid_t,fun);
+ xbt_dynar_push_as(process->on_exit_args,void*,data);
+}
#include "simgrid/simix.h"
#include "smx_smurf_private.h"
+typedef struct s_smx_process_exit_fun {
+ int_f_pvoid_t fun;
+ void *arg;
+} s_smx_process_exit_fun_t, *smx_process_exit_fun_t;
+
/** @brief Process datatype */
typedef struct s_smx_process {
s_xbt_swag_hookup_t process_hookup;
unsigned long pid;
char *name; /**< @brief process name if any */
smx_host_t smx_host; /* the host on which the process is running */
- smx_context_t context; /* the context (either uctx or thread) that executes the user function */
+ smx_context_t context; /* the context (uctx/raw/thread) that executes the user function */
xbt_running_ctx_t *running_ctx;
unsigned doexception:1;
unsigned blocked:1;
xbt_dict_t properties;
s_smx_simcall_t simcall;
void *data; /* kept for compatibility, it should be replaced with moddata */
-
+ xbt_dynar_t on_exit_fun; /* list of functions executed when the process dies */
+ xbt_dynar_t on_exit_args; /* arguments (void*) of the functions executed when the process dies */
} s_smx_process_t;
typedef struct s_smx_process_arg {
void SIMIX_process_sleep_resume(smx_action_t action);
void SIMIX_process_sleep_destroy(smx_action_t action);
+void SIMIX_process_on_exit(smx_process_t process);
+void SIMIX_process_on_exit_add(int_f_pvoid_t fun, void *data);
#endif