7
#include "red_common.h"
8
#include "dispatcher.h"
9
#include "main_dispatcher.h"
15
* Communication channel between any non main thread and the main thread.
17
* The main thread is that from which spice_server_init is called.
19
* Messages are single sized, sent from the non-main thread to the main-thread.
20
* No acknowledge is sent back. This prevents a possible deadlock with the main
21
* thread already waiting on a response for the existing red_dispatcher used
22
* by the worker thread.
24
* All events have three functions:
25
* main_dispatcher_<event_name> - non static, public function
26
* main_dispatcher_self_<event_name> - handler for main thread
27
* main_dispatcher_handle_<event_name> - handler for callback from main thread
28
* seperate from self because it may send an ack or do other work in the future.
33
SpiceCoreInterface *core;
36
MainDispatcher main_dispatcher;
39
MAIN_DISPATCHER_CHANNEL_EVENT = 0,
41
MAIN_DISPATCHER_NUM_MESSAGES
44
typedef struct MainDispatcherChannelEventMessage {
46
SpiceChannelEventInfo *info;
47
} MainDispatcherChannelEventMessage;
49
/* channel_event - calls core->channel_event, must be done in main thread */
50
static void main_dispatcher_self_handle_channel_event(
52
SpiceChannelEventInfo *info)
54
main_dispatcher.core->channel_event(event, info);
57
static void main_dispatcher_handle_channel_event(void *opaque,
60
MainDispatcherChannelEventMessage *channel_event = payload;
62
main_dispatcher_self_handle_channel_event(channel_event->event,
66
void main_dispatcher_channel_event(int event, SpiceChannelEventInfo *info)
68
MainDispatcherChannelEventMessage msg;
70
if (pthread_self() == main_dispatcher.base.self) {
71
main_dispatcher_self_handle_channel_event(event, info);
76
dispatcher_send_message(&main_dispatcher.base, MAIN_DISPATCHER_CHANNEL_EVENT,
80
static void dispatcher_handle_read(int fd, int event, void *opaque)
82
Dispatcher *dispatcher = opaque;
84
dispatcher_handle_recv_read(dispatcher);
87
void main_dispatcher_init(SpiceCoreInterface *core)
89
memset(&main_dispatcher, 0, sizeof(main_dispatcher));
90
main_dispatcher.core = core;
91
dispatcher_init(&main_dispatcher.base, MAIN_DISPATCHER_NUM_MESSAGES, &main_dispatcher.base);
92
core->watch_add(main_dispatcher.base.recv_fd, SPICE_WATCH_EVENT_READ,
93
dispatcher_handle_read, &main_dispatcher.base);
94
dispatcher_register_handler(&main_dispatcher.base, MAIN_DISPATCHER_CHANNEL_EVENT,
95
main_dispatcher_handle_channel_event,
96
sizeof(MainDispatcherChannelEventMessage), 0 /* no ack */);