[Spice-devel] [PATCH spice-server] dispatcher: Use a new API to handle events

Frediano Ziglio fziglio at redhat.com
Thu May 23 15:38:11 UTC 2019


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 at redhat.com>
---
 server/dispatcher.c      | 15 +++++++++------
 server/dispatcher.h      | 25 +++++--------------------
 server/main-dispatcher.c | 12 +-----------
 server/red-worker.c      | 10 +---------
 4 files changed, 16 insertions(+), 46 deletions(-)

diff --git a/server/dispatcher.c b/server/dispatcher.c
index 602f30a8e..bd74b6f35 100644
--- a/server/dispatcher.c
+++ b/server/dispatcher.c
@@ -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,14 +432,15 @@ static void setup_dummy_signal_handler(void)
 }
 #endif
 
-void dispatcher_set_opaque(Dispatcher *self, void *opaque)
+SpiceWatch *dispatcher_create_watch(Dispatcher *dispatcher, SpiceCoreInterfaceInternal *core)
 {
-    self->priv->opaque = opaque;
+    return core->watch_add(core, dispatcher->priv->recv_fd,
+                           SPICE_WATCH_EVENT_READ, dispatcher_handle_event, dispatcher);
 }
 
-int dispatcher_get_recv_fd(Dispatcher *dispatcher)
+void dispatcher_set_opaque(Dispatcher *self, void *opaque)
 {
-    return dispatcher->priv->recv_fd;
+    self->priv->opaque = opaque;
 }
 
 pthread_t dispatcher_get_thread_id(Dispatcher *self)
diff --git a/server/dispatcher.h b/server/dispatcher.h
index 49215782a..5bd0b1055 100644
--- a/server/dispatcher.h
+++ b/server/dispatcher.h
@@ -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
- */
-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
+ * @return: newly created watch
  */
-int dispatcher_get_recv_fd(Dispatcher *);
+SpiceWatch *dispatcher_create_watch(Dispatcher *dispatcher, SpiceCoreInterfaceInternal *core);
 
 /* dispatcher_set_opaque
  *
diff --git a/server/main-dispatcher.c b/server/main-dispatcher.c
index 839e7242c..2ca68a4d1 100644
--- a/server/main-dispatcher.c
+++ b/server/main-dispatcher.c
@@ -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);
diff --git a/server/red-worker.c b/server/red-worker.c
index d64c26e83..1ed5a05cb 100644
--- a/server/red-worker.c
+++ b/server/red-worker.c
@@ -978,13 +978,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;
@@ -1084,8 +1077,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));
-- 
2.20.1



More information about the Spice-devel mailing list