?
Current File : //usr/src/file_protector-1.1-1487/transport/message.h
/**
@file
@brief    kernel/userspace transport messages
@details  Copyright (c) 2017-2020 Acronis International GmbH
@author   Mikhail Krivtsov (mikhail.krivtsov@acronis.com)
@since    $Id: $
*/

#if !defined message_h
#define message_h

#include "transport.h"
#include "transport_protocol.h"

#include <linux/atomic.h>
#include <linux/list.h>
#include <linux/types.h>	// bool, size_t, [u]int(8|16|32|64)_t
#include <linux/wait.h>

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// 'msg_img_t' accessors

#define IMG_ID(msg_img)		*(&(msg_img)->id)
#define IMG_REPLY(msg_img)	*(&(msg_img)->reply)
#define IMG_TYPE(msg_img)	*(&(msg_img)->type)
#define IMG_PAYLOAD(msg_img)	(void *) (msg_img)->payload

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// To reduce memory overhead 'msg_img_t' is embedded into 'msg_t'
typedef struct msg_s msg_t;
struct msg_s {
	struct list_head list_node;	// to hook msg into queues
	wait_queue_head_t wait_queue;	// to wait for 'reply'
	atomic_t ref_cnt;
	// TODO: add 'timer'/'timeout' to limit 'reply' wait time
	msg_t *reply_msg;
	size_t img_size;
	bool aborted;
	uint8_t img[0];		// 'msg_img_t'
};

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// 'msg_t' accessors

#define MSG_IMG(msg)	(msg_img_t *) (msg)->img
#define MSG_SIZE(msg)	(msg)->img_size
#define MSG_ID(msg)	IMG_ID(MSG_IMG(msg))
#define MSG_REPLY(msg)	IMG_REPLY(MSG_IMG(msg))
#define MSG_TYPE(msg)	IMG_TYPE(MSG_IMG(msg))

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

const char* msg_type_to_string(msg_type_t type);

msg_t *msg_new(size_t msg_img_size);
msg_t *msg_new_nowait(size_t msg_img_size);
msg_t *msg_new_type(size_t msg_img_size, msg_type_t type);
msg_t *msg_new_type_nowait(size_t msg_img_size, msg_type_t type);
msg_t *msg_ref(msg_t *msg);
void msg_unref(msg_t *msg);

msg_t *hello_msg_new(void);
msg_t *ping_reply_msg_new(msg_t *ping_msg);
msg_t *pong_msg_new(msg_t *ping_msg);
msg_t *heur_exec_msg_new(void);  // if was exec for current process, create message
int pid_info_msg_new(msg_t **msg, pid_t nr);
int fs_root_msg_new(msg_t **msg, pid_t nr);

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// sending messages via default 'transport'
void send_msg_async(msg_t *msg);
void send_msg_sync_nowait(msg_t *msg);
void send_msg_sync(msg_t *msg);
void send_msg_sync_unref(msg_t *msg);
void send_reply(msg_t *query, msg_t *reply);

#endif /* !defined message_h */