dispatcher: Use a new API to handle events

Instead of having to manually register the file descriptor and
than need to call dispatcher_handle_recv_read just provide a single
API to create the watch.
This has some advantage:
- replace 2 API with 1;
- code reuse for handling the event (removed 2 functions);
- avoid the caller to use the file descriptor;
- avoid the caller to register wrong events.

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Victor Toso <victortoso@redhat.com>
This commit is contained in:
Frediano Ziglio 2019-03-29 15:18:08 +00:00
parent a21de34173
commit 5fb4f52bdb
4 changed files with 17 additions and 47 deletions

View File

@ -317,11 +317,13 @@ static int dispatcher_handle_single_read(Dispatcher *dispatcher)
}
/*
* dispatcher_handle_recv_read
* dispatcher_handle_event
* doesn't handle being in the middle of a message. all reads are blocking.
*/
void dispatcher_handle_recv_read(Dispatcher *dispatcher)
static void dispatcher_handle_event(int fd, int event, void *opaque)
{
Dispatcher *dispatcher = opaque;
while (dispatcher_handle_single_read(dispatcher)) {
}
}
@ -430,16 +432,17 @@ static void setup_dummy_signal_handler(void)
}
#endif
SpiceWatch *dispatcher_create_watch(Dispatcher *dispatcher, SpiceCoreInterfaceInternal *core)
{
return core->watch_add(core, dispatcher->priv->recv_fd,
SPICE_WATCH_EVENT_READ, dispatcher_handle_event, dispatcher);
}
void dispatcher_set_opaque(Dispatcher *self, void *opaque)
{
self->priv->opaque = opaque;
}
int dispatcher_get_recv_fd(Dispatcher *dispatcher)
{
return dispatcher->priv->recv_fd;
}
pthread_t dispatcher_get_thread_id(Dispatcher *self)
{
return self->priv->thread_id;

View File

@ -148,29 +148,14 @@ void dispatcher_register_handler(Dispatcher *dispatcher, uint32_t message_type,
void dispatcher_register_universal_handler(Dispatcher *dispatcher,
dispatcher_handle_any_message handler);
/* dispatcher_handle_recv_read
/* dispatcher_create_watch
*
* A convenience function that is intended to be called by the receiving thread
* to handle all incoming messages and execute any handlers for those messages.
* This function will handle all incoming messages until there is no more data
* to read, so multiple handlers may be executed from a single call to
* dispatcher_handle_recv_read().
* Create a new watch to handle events for the dispatcher.
* You should release it before releasing the dispatcher.
*
* @dispatcher: Dispatcher instance
* @return: newly created watch
*/
void dispatcher_handle_recv_read(Dispatcher *);
/* dispatcher_get_recv_fd
*
* This function returns the file descriptor that is used by the receiving
* thread to listen for incoming messages. You should not read or write
* directly to this fd, but should only use it to watch for read events. When
* there is a read event, you should use dispatcher_handle_recv_read() to
* handle the incoming messages.
*
* @return: receive file descriptor of the dispatcher
*/
int dispatcher_get_recv_fd(Dispatcher *);
SpiceWatch *dispatcher_create_watch(Dispatcher *dispatcher, SpiceCoreInterfaceInternal *core);
/* dispatcher_set_opaque
*

View File

@ -247,13 +247,6 @@ void main_dispatcher_client_disconnect(MainDispatcher *self, RedClient *client)
}
}
static void dispatcher_handle_read(int fd, int event, void *opaque)
{
Dispatcher *dispatcher = opaque;
dispatcher_handle_recv_read(dispatcher);
}
/*
* FIXME:
* Reds routines shouldn't be exposed. Instead reds.c should register the callbacks,
@ -276,10 +269,7 @@ void main_dispatcher_constructed(GObject *object)
dispatcher_set_opaque(DISPATCHER(self), self->priv->reds);
self->priv->watch =
reds_core_watch_add(self->priv->reds,
dispatcher_get_recv_fd(DISPATCHER(self)),
SPICE_WATCH_EVENT_READ, dispatcher_handle_read,
DISPATCHER(self));
dispatcher_create_watch(DISPATCHER(self), reds_get_core_interface(self->priv->reds));
dispatcher_register_handler(DISPATCHER(self), MAIN_DISPATCHER_CHANNEL_EVENT,
main_dispatcher_handle_channel_event,
sizeof(MainDispatcherChannelEventMessage), false);

View File

@ -980,13 +980,6 @@ static void register_callbacks(Dispatcher *dispatcher)
static void handle_dev_input(int fd, int event, void *opaque)
{
Dispatcher *dispatcher = opaque;
dispatcher_handle_recv_read(dispatcher);
}
typedef struct RedWorkerSource {
GSource source;
RedWorker *worker;
@ -1086,8 +1079,7 @@ RedWorker* red_worker_new(QXLInstance *qxl)
stat_init_counter(&worker->total_loop_counter, reds, &worker->stat, "total_loops", TRUE);
worker->dispatch_watch =
worker->core.watch_add(&worker->core, dispatcher_get_recv_fd(dispatcher),
SPICE_WATCH_EVENT_READ, handle_dev_input, dispatcher);
dispatcher_create_watch(dispatcher, &worker->core);
spice_assert(worker->dispatch_watch != NULL);
GSource *source = g_source_new(&worker_source_funcs, sizeof(RedWorkerSource));