1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
#ifndef MAIN_DISPATCHER_H
#define MAIN_DISPATCHER_H
#include <spice.h>
typedef struct Dispatcher Dispatcher;
typedef void (*dispatcher_handle_message)(void *opaque,
void *payload);
typedef void (*dispatcher_handle_async_done)(void *opaque,
uint32_t message_type,
void *payload);
typedef struct DispatcherMessage {
size_t size;
int ack;
dispatcher_handle_message handler;
} DispatcherMessage;
struct Dispatcher {
SpiceCoreInterface *recv_core;
int recv_fd;
int send_fd;
pthread_t self;
pthread_mutex_t lock;
DispatcherMessage *messages;
int stage; /* message parser stage - sender has no stages */
size_t max_message_type;
void *payload; /* allocated as max of message sizes */
size_t payload_size; /* used to track realloc calls */
void *opaque;
dispatcher_handle_async_done handle_async_done;
};
/*
* dispatcher_send_message
* @message_type: message type
* @payload: payload
*/
void dispatcher_send_message(Dispatcher *dispatcher, uint32_t message_type,
void *payload);
/*
* dispatcher_init
* @max_message_type: number of message types. Allows upfront allocation
* of a DispatcherMessage list.
* up front, and registration in any order wanted.
*/
void dispatcher_init(Dispatcher *dispatcher, size_t max_message_type,
void *opaque);
enum {
DISPATCHER_NONE = 0,
DISPATCHER_ACK,
DISPATCHER_ASYNC
};
/*
* dispatcher_register_handler
* @dispatcher: dispatcher
* @messsage_type: message type
* @handler: message handler
* @size: message size. Each type has a fixed associated size.
* @ack: One of DISPATCHER_NONE, DISPATCHER_ACK, DISPATCHER_ASYNC.
* DISPATCHER_NONE - only send the message
* DISPATCHER_ACK - send an ack after the message
* DISPATCHER_ASYNC - call send an ack. This is per message type - you can't send the
* same message type with and without. Register two different
* messages if that is what you want.
*/
void dispatcher_register_handler(Dispatcher *dispatcher, uint32_t message_type,
dispatcher_handle_message handler, size_t size,
int ack);
/*
* dispatcher_register_async_done_callback
* @dispatcher: dispatcher
* @handler: callback on the receiver side called *after* the
* message callback in case ack == DISPATCHER_ASYNC.
*/
void dispatcher_register_async_done_callback(
Dispatcher *dispatcher,
dispatcher_handle_async_done handler);
/*
* dispatcher_handle_recv_read
* @dispatcher: Dispatcher instance
*/
void dispatcher_handle_recv_read(Dispatcher *);
/*
* dispatcher_get_recv_fd
* @return: receive file descriptor of the dispatcher
*/
int dispatcher_get_recv_fd(Dispatcher *);
/*
* dispatcher_set_opaque
* @dispatcher: Dispatcher instance
* @opaque: opaque to use for callbacks
*/
void dispatcher_set_opaque(Dispatcher *dispatcher, void *opaque);
#endif //MAIN_DISPATCHER_H
|