\x20\40\x20\40
/**
@file
@brief 'exit' event
@details Copyright (c) 2017-2021 Acronis International GmbH
@author Mikhail Krivtsov (mikhail.krivtsov@acronis.com)
@since $Id: $
*/
#include "exit_event.h"
#include "debug.h"
#include "message.h"
#include "task_info_map.h"
/*
'task_info_map_del()' -> 'task_info_free()' -> 'path_put()'
'path_put()' may 'sleep'. 'exit_event_nowait()' is invoked from
'scheduler' where 'sleeping' is prohibited. It means that
'task_info_map_del()' may not be directly invoked from
'exit_event_nowait()'.
Let's put 'task_info' into helper list for some arbitrary [client]
thread to call 'task_info_map_del()' later.
*/
void exit_event_nowait(pid_t tgid, pid_t pid)
{
msg_t *msg;
size_t exit_img_size;
size_t msg_img_size;
exit_img_size = sizeof(exit_img_t);
msg_img_size = sizeof(msg_img_t) + exit_img_size;
msg = msg_new_type_nowait(msg_img_size, MT_EXIT);
if (msg) {
msg_img_t *msg_img = MSG_IMG(msg);
exit_img_t *exit_img = IMG_PAYLOAD(msg_img);
/*
* userspace kernel
* getpid() current->tgid
* gettid() current->pid
*/
exit_img->pid = tgid;
exit_img->tid = pid;
send_msg_async(msg);
msg_unref(msg);
}
task_info_map_on_exit_event(tgid, pid);
}