[Spice-commits] 4 commits - server/agent-msg-filter.c server/agent-msg-filter.h server/inputs-channel.c server/main-channel.c server/main-dispatcher.c server/main-dispatcher.h server/red-channel.c server/red-channel.h server/reds.c server/reds.h server/reds-private.h server/reds-stream.c server/sound.c server/sound.h server/stream.c

Frediano Ziglio fziglio at kemper.freedesktop.org
Tue Feb 16 10:56:20 UTC 2016


 server/agent-msg-filter.c |    7 ++-
 server/agent-msg-filter.h |   11 +++---
 server/inputs-channel.c   |    4 +-
 server/main-channel.c     |    5 +-
 server/main-dispatcher.c  |   83 ++++++++++++++++++++++++----------------------
 server/main-dispatcher.h  |   12 +++---
 server/red-channel.c      |    9 ++++
 server/red-channel.h      |    5 +-
 server/reds-private.h     |    1 
 server/reds-stream.c      |    4 +-
 server/reds.c             |   25 +++++++++----
 server/reds.h             |    2 +
 server/sound.c            |   20 +++++++++--
 server/sound.h            |    4 +-
 server/stream.c           |    5 ++
 15 files changed, 128 insertions(+), 69 deletions(-)

New commits:
commit 1f210080609f2c00b4d1859eb0b363a38838e7d3
Author: Jonathon Jongsma <jjongsma at redhat.com>
Date:   Wed Feb 11 17:11:02 2015 -0600

    Remove use of global 'reds' from AgentMsgFilter
    
    Acked-by: Fabiano Fidêncio <fidencio at redhat.com>

diff --git a/server/agent-msg-filter.c b/server/agent-msg-filter.c
index 069822b..14d5100 100644
--- a/server/agent-msg-filter.c
+++ b/server/agent-msg-filter.c
@@ -28,11 +28,14 @@
 #include "red-dispatcher.h"
 
 void agent_msg_filter_init(struct AgentMsgFilter *filter,
-                           int copy_paste, int file_xfer, int discard_all)
+                           gboolean copy_paste, gboolean file_xfer,
+                           gboolean use_client_monitors_config,
+                           int discard_all)
 {
     memset(filter, 0, sizeof(*filter));
     filter->copy_paste_enabled = copy_paste;
     filter->file_xfer_enabled = file_xfer;
+    filter->use_client_monitors_config = use_client_monitors_config;
     filter->discard_all = discard_all;
 }
 
@@ -93,7 +96,7 @@ data_to_read:
             }
             break;
         case VD_AGENT_MONITORS_CONFIG:
-            if (reds_use_client_monitors_config(reds)) {
+            if (filter->use_client_monitors_config) {
                 filter->result = AGENT_MSG_FILTER_MONITORS_CONFIG;
             } else {
                 filter->result = AGENT_MSG_FILTER_OK;
diff --git a/server/agent-msg-filter.h b/server/agent-msg-filter.h
index 92aabce..c04face 100644
--- a/server/agent-msg-filter.h
+++ b/server/agent-msg-filter.h
@@ -35,13 +35,16 @@ enum {
 typedef struct AgentMsgFilter {
     int msg_data_to_read;
     int result;
-    int copy_paste_enabled;
-    int file_xfer_enabled;
-    int discard_all;
+    gboolean copy_paste_enabled;
+    gboolean file_xfer_enabled;
+    gboolean use_client_monitors_config;
+    gboolean discard_all;
 } AgentMsgFilter;
 
 void agent_msg_filter_init(struct AgentMsgFilter *filter,
-                           int copy_paste, int file_xfer, int discard_all);
+                           gboolean copy_paste, gboolean file_xfer,
+                           gboolean use_client_monitors_config,
+                           gboolean discard_all);
 int agent_msg_filter_process_data(struct AgentMsgFilter *filter,
                                   uint8_t *data, uint32_t len);
 
diff --git a/server/reds.c b/server/reds.c
index f4eda22..a1d3c72 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -407,7 +407,8 @@ static void reds_reset_vdp(RedsState *reds)
     }
     /* Reset read filter to start with clean state when the agent reconnects */
     agent_msg_filter_init(&state->read_filter, reds->agent_copypaste,
-                          reds->agent_file_xfer, TRUE);
+                          reds->agent_file_xfer,
+                          reds_use_client_monitors_config(reds), TRUE);
     /* Throw away pending chunks from the current (if any) and future
      * messages written by the client.
      * TODO: client should clear its agent messages queue when the agent
@@ -521,7 +522,8 @@ void reds_client_disconnect(RedsState *reds, RedClient *client)
 
         /* Reset write filter to start with clean state on client reconnect */
         agent_msg_filter_init(&reds->agent_state.write_filter, reds->agent_copypaste,
-                              reds->agent_file_xfer, TRUE);
+                              reds->agent_file_xfer,
+                              reds_use_client_monitors_config(reds), TRUE);
 
         /* Throw away pending chunks from the current (if any) and future
          *  messages read from the agent */
@@ -3212,6 +3214,8 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *s,
         red_dispatcher_init(qxl);
         dispatcher = qxl->st->dispatcher;
         reds->dispatchers = g_list_prepend(reds->dispatchers, dispatcher);
+        reds->agent_state.write_filter.use_client_monitors_config = reds_use_client_monitors_config(reds);
+        reds->agent_state.read_filter.use_client_monitors_config = reds_use_client_monitors_config(reds);
 
         /* this function has to be called after the dispatcher is on the list
          * as QXLInstance clients expect the dispatcher to be on the list when
@@ -3317,9 +3321,11 @@ static void reds_init_vd_agent_resources(RedsState *reds)
 
     ring_init(&state->read_bufs);
     agent_msg_filter_init(&state->write_filter, reds->agent_copypaste,
-                          reds->agent_file_xfer, TRUE);
+                          reds->agent_file_xfer,
+                          reds_use_client_monitors_config(reds), TRUE);
     agent_msg_filter_init(&state->read_filter, reds->agent_copypaste,
-                          reds->agent_file_xfer, TRUE);
+                          reds->agent_file_xfer,
+                          reds_use_client_monitors_config(reds), TRUE);
 
     state->read_state = VDI_PORT_READ_STATE_READ_HEADER;
     state->receive_pos = (uint8_t *)&state->vdi_chunk_header;
commit 4ac21bc649f1d7c0576f98baa2738d7ef97617f7
Author: Jonathon Jongsma <jjongsma at redhat.com>
Date:   Wed Feb 11 11:38:57 2015 -0600

    Remove use of global 'reds' from sound.c
    
    Pass RedsState variable to snd_attach_(playback|record) and get a
    reference to this variable when needed by various functions.
    
    Acked-by: Fabiano Fidêncio <fidencio at redhat.com>

diff --git a/server/reds.c b/server/reds.c
index e12fdce..f4eda22 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -3243,7 +3243,7 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *s,
             spice_warning("unsupported playback interface");
             return -1;
         }
-        snd_attach_playback(SPICE_CONTAINEROF(sin, SpicePlaybackInstance, base));
+        snd_attach_playback(reds, SPICE_CONTAINEROF(sin, SpicePlaybackInstance, base));
 
     } else if (strcmp(interface->type, SPICE_INTERFACE_RECORD) == 0) {
         spice_info("SPICE_INTERFACE_RECORD");
@@ -3252,7 +3252,7 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *s,
             spice_warning("unsupported record interface");
             return -1;
         }
-        snd_attach_record(SPICE_CONTAINEROF(sin, SpiceRecordInstance, base));
+        snd_attach_record(reds, SPICE_CONTAINEROF(sin, SpiceRecordInstance, base));
 
     } else if (strcmp(interface->type, SPICE_INTERFACE_CHAR_DEVICE) == 0) {
         if (interface->major_version != SPICE_INTERFACE_CHAR_DEVICE_MAJOR ||
diff --git a/server/sound.c b/server/sound.c
index fd0b416..4e61986 100644
--- a/server/sound.c
+++ b/server/sound.c
@@ -199,14 +199,22 @@ static SndChannel *snd_channel_put(SndChannel *channel)
     return channel;
 }
 
+static RedsState* snd_channel_get_server(SndChannel *channel)
+{
+    g_return_val_if_fail(channel != NULL, NULL);
+    return red_channel_get_server(channel->worker->base_channel);
+}
+
 static void snd_disconnect_channel(SndChannel *channel)
 {
     SndWorker *worker;
+    RedsState *reds;
 
     if (!channel || !channel->stream) {
         spice_debug("not connected");
         return;
     }
+    reds = snd_channel_get_server(channel);
     spice_debug("SndChannel=%p rcc=%p type=%d",
                  channel, channel->channel_client, channel->channel_client->channel->type);
     worker = channel->worker;
@@ -247,6 +255,7 @@ static void snd_record_on_message_done(SndChannel *channel)
 
 static int snd_send_data(SndChannel *channel)
 {
+    RedsState *reds = snd_channel_get_server(channel);
     uint32_t n;
 
     if (!channel) {
@@ -900,6 +909,7 @@ static SndChannel *__new_channel(SndWorker *worker, int size, uint32_t channel_i
 #endif
     int tos;
     MainChannelClient *mcc = red_client_get_main(client);
+    RedsState *reds = red_channel_get_server(worker->base_channel);
 
     spice_assert(stream);
     if ((flags = fcntl(stream->socket, F_GETFL)) == -1) {
@@ -1037,6 +1047,7 @@ SPICE_GNUC_VISIBLE void spice_server_playback_start(SpicePlaybackInstance *sin)
 {
     SndChannel *channel = sin->st->worker.connection;
     PlaybackChannel *playback_channel = SPICE_CONTAINEROF(channel, PlaybackChannel, base);
+    RedsState *reds = snd_channel_get_server(channel);
 
     sin->st->worker.active = 1;
     if (!channel)
@@ -1056,6 +1067,7 @@ SPICE_GNUC_VISIBLE void spice_server_playback_stop(SpicePlaybackInstance *sin)
 {
     SndChannel *channel = sin->st->worker.connection;
     PlaybackChannel *playback_channel = SPICE_CONTAINEROF(channel, PlaybackChannel, base);
+    RedsState *reds = snd_channel_get_server(channel);
 
     sin->st->worker.active = 0;
     if (!channel)
@@ -1161,6 +1173,7 @@ static int snd_desired_audio_mode(int frequency, int client_can_celt, int client
 
 static void on_new_playback_channel(SndWorker *worker)
 {
+    RedsState *reds = red_channel_get_server(worker->base_channel);
     PlaybackChannel *playback_channel =
         SPICE_CONTAINEROF(worker->connection, PlaybackChannel, base);
     SpicePlaybackState *st = SPICE_CONTAINEROF(worker, SpicePlaybackState, worker);
@@ -1181,6 +1194,7 @@ static void on_new_playback_channel(SndWorker *worker)
 
 static void snd_playback_cleanup(SndChannel *channel)
 {
+    RedsState *reds = snd_channel_get_server(channel);
     PlaybackChannel *playback_channel = SPICE_CONTAINEROF(channel, PlaybackChannel, base);
 
     if (playback_channel->base.active) {
@@ -1507,7 +1521,7 @@ static void remove_worker(SndWorker *worker)
     spice_printerr("not found");
 }
 
-void snd_attach_playback(SpicePlaybackInstance *sin)
+void snd_attach_playback(RedsState *reds, SpicePlaybackInstance *sin)
 {
     SndWorker *playback_worker;
     RedChannel *channel;
@@ -1537,7 +1551,7 @@ void snd_attach_playback(SpicePlaybackInstance *sin)
     reds_register_channel(reds, channel);
 }
 
-void snd_attach_record(SpiceRecordInstance *sin)
+void snd_attach_record(RedsState *reds, SpiceRecordInstance *sin)
 {
     SndWorker *record_worker;
     RedChannel *channel;
@@ -1570,6 +1584,8 @@ static void snd_detach_common(SndWorker *worker)
     if (!worker) {
         return;
     }
+    RedsState *reds = red_channel_get_server(worker->base_channel);
+
     remove_worker(worker);
     snd_disconnect_channel(worker->connection);
     reds_unregister_channel(reds, worker->base_channel);
diff --git a/server/sound.h b/server/sound.h
index 97f8410..25e59f0 100644
--- a/server/sound.h
+++ b/server/sound.h
@@ -20,10 +20,10 @@
 
 #include "spice.h"
 
-void snd_attach_playback(SpicePlaybackInstance *sin);
+void snd_attach_playback(RedsState *reds, SpicePlaybackInstance *sin);
 void snd_detach_playback(SpicePlaybackInstance *sin);
 
-void snd_attach_record(SpiceRecordInstance *sin);
+void snd_attach_record(RedsState *reds, SpiceRecordInstance *sin);
 void snd_detach_record(SpiceRecordInstance *sin);
 
 void snd_set_playback_compression(int on);
commit 2a18e874a2b2d5bfa95aaaee443ab7846fd8e7fb
Author: Jonathon Jongsma <jjongsma at redhat.com>
Date:   Tue Feb 10 16:37:49 2015 -0600

    Remove global main_dispatcher variable
    
    Requires changing a bunch of internal API to take MainDispatcher
    arguments, etc. The main dispatcher object is now owned by RedsState,
    since that is the object that previously created (initialized) it.
    
    Acked-by: Fabiano Fidêncio <fidencio at redhat.com>

diff --git a/server/main-channel.c b/server/main-channel.c
index 65f862d..6a36ce5 100644
--- a/server/main-channel.c
+++ b/server/main-channel.c
@@ -178,8 +178,9 @@ int main_channel_is_connected(MainChannel *main_chan)
  */
 static void main_channel_client_on_disconnect(RedChannelClient *rcc)
 {
+    RedsState *reds = red_channel_get_server(rcc->channel);
     spice_printerr("rcc=%p", rcc);
-    main_dispatcher_client_disconnect(rcc->client);
+    main_dispatcher_client_disconnect(reds_get_main_dispatcher(reds), rcc->client);
 }
 
 RedClient *main_channel_get_client_by_link_id(MainChannel *main_chan, uint32_t connection_id)
diff --git a/server/main-dispatcher.c b/server/main-dispatcher.c
index 777a44f..298a961 100644
--- a/server/main-dispatcher.c
+++ b/server/main-dispatcher.c
@@ -47,12 +47,11 @@
  *   seperate from self because it may send an ack or do other work in the future.
  */
 
-typedef struct {
+struct MainDispatcher {
     Dispatcher base;
     SpiceCoreInterfaceInternal *core;
-} MainDispatcher;
-
-MainDispatcher main_dispatcher;
+    RedsState *reds;
+};
 
 enum {
     MAIN_DISPATCHER_CHANNEL_EVENT = 0,
@@ -82,33 +81,35 @@ typedef struct MainDispatcherClientDisconnectMessage {
 } MainDispatcherClientDisconnectMessage;
 
 /* channel_event - calls core->channel_event, must be done in main thread */
-static void main_dispatcher_self_handle_channel_event(
-                                                int event,
-                                                SpiceChannelEventInfo *info)
+static void main_dispatcher_self_handle_channel_event(MainDispatcher *self,
+                                                      int event,
+                                                      SpiceChannelEventInfo *info)
 {
-    reds_handle_channel_event(reds, event, info);
+    reds_handle_channel_event(self->reds, event, info);
 }
 
 static void main_dispatcher_handle_channel_event(void *opaque,
                                                  void *payload)
 {
+    MainDispatcher *self = opaque;
     MainDispatcherChannelEventMessage *channel_event = payload;
 
-    main_dispatcher_self_handle_channel_event(channel_event->event,
+    main_dispatcher_self_handle_channel_event(self,
+                                              channel_event->event,
                                               channel_event->info);
 }
 
-void main_dispatcher_channel_event(int event, SpiceChannelEventInfo *info)
+void main_dispatcher_channel_event(MainDispatcher *self, int event, SpiceChannelEventInfo *info)
 {
     MainDispatcherChannelEventMessage msg = {0,};
 
-    if (pthread_self() == main_dispatcher.base.self) {
-        main_dispatcher_self_handle_channel_event(event, info);
+    if (pthread_self() == self->base.self) {
+        main_dispatcher_self_handle_channel_event(self, event, info);
         return;
     }
     msg.event = event;
     msg.info = info;
-    dispatcher_send_message(&main_dispatcher.base, MAIN_DISPATCHER_CHANNEL_EVENT,
+    dispatcher_send_message(&self->base, MAIN_DISPATCHER_CHANNEL_EVENT,
                             &msg);
 }
 
@@ -116,67 +117,71 @@ void main_dispatcher_channel_event(int event, SpiceChannelEventInfo *info)
 static void main_dispatcher_handle_migrate_complete(void *opaque,
                                                     void *payload)
 {
+    MainDispatcher *self = opaque;
     MainDispatcherMigrateSeamlessDstCompleteMessage *mig_complete = payload;
 
-    reds_on_client_seamless_migrate_complete(reds, mig_complete->client);
+    reds_on_client_seamless_migrate_complete(self->reds, mig_complete->client);
     red_client_unref(mig_complete->client);
 }
 
 static void main_dispatcher_handle_mm_time_latency(void *opaque,
                                                    void *payload)
 {
+    MainDispatcher *self = opaque;
     MainDispatcherMmTimeLatencyMessage *msg = payload;
-    reds_set_client_mm_time_latency(reds, msg->client, msg->latency);
+    reds_set_client_mm_time_latency(self->reds, msg->client, msg->latency);
     red_client_unref(msg->client);
 }
 
 static void main_dispatcher_handle_client_disconnect(void *opaque,
                                                      void *payload)
 {
+    MainDispatcher *self = opaque;
     MainDispatcherClientDisconnectMessage *msg = payload;
 
     spice_debug("client=%p", msg->client);
-    reds_client_disconnect(reds, msg->client);
+    reds_client_disconnect(self->reds, msg->client);
     red_client_unref(msg->client);
 }
 
-void main_dispatcher_seamless_migrate_dst_complete(RedClient *client)
+void main_dispatcher_seamless_migrate_dst_complete(MainDispatcher *self,
+                                                   RedClient *client)
 {
     MainDispatcherMigrateSeamlessDstCompleteMessage msg;
 
-    if (pthread_self() == main_dispatcher.base.self) {
-        reds_on_client_seamless_migrate_complete(reds, client);
+    if (pthread_self() == self->base.self) {
+        reds_on_client_seamless_migrate_complete(self->reds, client);
         return;
     }
 
     msg.client = red_client_ref(client);
-    dispatcher_send_message(&main_dispatcher.base, MAIN_DISPATCHER_MIGRATE_SEAMLESS_DST_COMPLETE,
+    dispatcher_send_message(&self->base, MAIN_DISPATCHER_MIGRATE_SEAMLESS_DST_COMPLETE,
                             &msg);
 }
 
-void main_dispatcher_set_mm_time_latency(RedClient *client, uint32_t latency)
+void main_dispatcher_set_mm_time_latency(MainDispatcher *self, RedClient *client, uint32_t latency)
 {
     MainDispatcherMmTimeLatencyMessage msg;
 
-    if (pthread_self() == main_dispatcher.base.self) {
-        reds_set_client_mm_time_latency(reds, client, latency);
+    if (pthread_self() == self->base.self) {
+        reds_set_client_mm_time_latency(self->reds, client, latency);
         return;
     }
 
     msg.client = red_client_ref(client);
     msg.latency = latency;
-    dispatcher_send_message(&main_dispatcher.base, MAIN_DISPATCHER_SET_MM_TIME_LATENCY,
+    dispatcher_send_message(&self->base, MAIN_DISPATCHER_SET_MM_TIME_LATENCY,
                             &msg);
 }
 
-void main_dispatcher_client_disconnect(RedClient *client)
+void main_dispatcher_client_disconnect(MainDispatcher *self, RedClient *client)
 {
     MainDispatcherClientDisconnectMessage msg;
 
     if (!client->disconnecting) {
         spice_debug("client %p", client);
         msg.client = red_client_ref(client);
-        dispatcher_send_message(&main_dispatcher.base, MAIN_DISPATCHER_CLIENT_DISCONNECT,
+        dispatcher_send_message(&self->base, MAIN_DISPATCHER_CLIENT_DISCONNECT,
                                 &msg);
     } else {
         spice_debug("client %p already during disconnection", client);
@@ -185,9 +190,9 @@ void main_dispatcher_client_disconnect(RedClient *client)
 
 static void dispatcher_handle_read(int fd, int event, void *opaque)
 {
-    Dispatcher *dispatcher = opaque;
+    MainDispatcher *self = opaque;
 
-    dispatcher_handle_recv_read(dispatcher);
+    dispatcher_handle_recv_read(&self->base);
 }
 
 /*
@@ -195,23 +200,25 @@ static void dispatcher_handle_read(int fd, int event, void *opaque)
  * Reds routines shouldn't be exposed. Instead reds.c should register the callbacks,
  * and the corresponding operations should be made only via main_dispatcher.
  */
-void main_dispatcher_init(SpiceCoreInterfaceInternal *core)
+MainDispatcher* main_dispatcher_new(RedsState *reds, SpiceCoreInterfaceInternal *core)
 {
-    memset(&main_dispatcher, 0, sizeof(main_dispatcher));
-    main_dispatcher.core = core;
-    dispatcher_init(&main_dispatcher.base, MAIN_DISPATCHER_NUM_MESSAGES, &main_dispatcher.base);
-    core->watch_add(core, main_dispatcher.base.recv_fd, SPICE_WATCH_EVENT_READ,
-                    dispatcher_handle_read, &main_dispatcher.base);
-    dispatcher_register_handler(&main_dispatcher.base, MAIN_DISPATCHER_CHANNEL_EVENT,
+    MainDispatcher *main_dispatcher = g_new0(MainDispatcher, 1);
+    main_dispatcher->core = core;
+    main_dispatcher->reds = reds;
+    dispatcher_init(&main_dispatcher->base, MAIN_DISPATCHER_NUM_MESSAGES, main_dispatcher);
+    core->watch_add(core, main_dispatcher->base.recv_fd, SPICE_WATCH_EVENT_READ,
+                    dispatcher_handle_read, main_dispatcher);
+    dispatcher_register_handler(&main_dispatcher->base, MAIN_DISPATCHER_CHANNEL_EVENT,
                                 main_dispatcher_handle_channel_event,
                                 sizeof(MainDispatcherChannelEventMessage), 0 /* no ack */);
-    dispatcher_register_handler(&main_dispatcher.base, MAIN_DISPATCHER_MIGRATE_SEAMLESS_DST_COMPLETE,
+    dispatcher_register_handler(&main_dispatcher->base, MAIN_DISPATCHER_MIGRATE_SEAMLESS_DST_COMPLETE,
                                 main_dispatcher_handle_migrate_complete,
                                 sizeof(MainDispatcherMigrateSeamlessDstCompleteMessage), 0 /* no ack */);
-    dispatcher_register_handler(&main_dispatcher.base, MAIN_DISPATCHER_SET_MM_TIME_LATENCY,
+    dispatcher_register_handler(&main_dispatcher->base, MAIN_DISPATCHER_SET_MM_TIME_LATENCY,
                                 main_dispatcher_handle_mm_time_latency,
                                 sizeof(MainDispatcherMmTimeLatencyMessage), 0 /* no ack */);
-    dispatcher_register_handler(&main_dispatcher.base, MAIN_DISPATCHER_CLIENT_DISCONNECT,
+    dispatcher_register_handler(&main_dispatcher->base, MAIN_DISPATCHER_CLIENT_DISCONNECT,
                                 main_dispatcher_handle_client_disconnect,
                                 sizeof(MainDispatcherClientDisconnectMessage), 0 /* no ack */);
+    return main_dispatcher;
 }
diff --git a/server/main-dispatcher.h b/server/main-dispatcher.h
index 1a06229..cbc3657 100644
--- a/server/main-dispatcher.h
+++ b/server/main-dispatcher.h
@@ -21,16 +21,18 @@
 #include <spice.h>
 #include "red-channel.h"
 
-void main_dispatcher_channel_event(int event, SpiceChannelEventInfo *info);
-void main_dispatcher_seamless_migrate_dst_complete(RedClient *client);
-void main_dispatcher_set_mm_time_latency(RedClient *client, uint32_t latency);
+typedef struct MainDispatcher MainDispatcher;
+
+void main_dispatcher_channel_event(MainDispatcher *self, int event, SpiceChannelEventInfo *info);
+void main_dispatcher_seamless_migrate_dst_complete(MainDispatcher *self, RedClient *client);
+void main_dispatcher_set_mm_time_latency(MainDispatcher *self, RedClient *client, uint32_t latency);
 /*
  * Disconnecting the client is always executed asynchronously,
  * in order to protect from expired references in the routines
  * that triggered the client destruction.
  */
-void main_dispatcher_client_disconnect(RedClient *client);
+void main_dispatcher_client_disconnect(MainDispatcher *self, RedClient *client);
 
-void main_dispatcher_init(SpiceCoreInterfaceInternal *core);
+MainDispatcher* main_dispatcher_new(RedsState *reds, SpiceCoreInterfaceInternal *core);
 
 #endif //MAIN_DISPATCHER_H
diff --git a/server/red-channel.c b/server/red-channel.c
index 757bb6e..d7ff37e 100644
--- a/server/red-channel.c
+++ b/server/red-channel.c
@@ -941,6 +941,7 @@ error:
 
 static void red_channel_client_seamless_migration_done(RedChannelClient *rcc)
 {
+    RedsState *reds = red_channel_get_server(rcc->channel);
     rcc->wait_migrate_data = FALSE;
 
     pthread_mutex_lock(&rcc->client->lock);
@@ -953,7 +954,8 @@ static void red_channel_client_seamless_migration_done(RedChannelClient *rcc)
         rcc->client->seamless_migrate = FALSE;
         /* migration completion might have been triggered from a different thread
          * than the main thread */
-        main_dispatcher_seamless_migrate_dst_complete(rcc->client);
+        main_dispatcher_seamless_migrate_dst_complete(reds_get_main_dispatcher(reds),
+                                                      rcc->client);
         if (rcc->latency_monitor.timer) {
             red_channel_client_start_ping_timer(rcc, PING_TEST_IDLE_NET_TIMEOUT_MS);
         }
diff --git a/server/reds-private.h b/server/reds-private.h
index c214091..f567929 100644
--- a/server/reds-private.h
+++ b/server/reds-private.h
@@ -242,6 +242,7 @@ struct RedsState {
     RedSSLParameters ssl_parameters;
     SpiceCoreInterfaceInternal *core;
     GList *dispatchers;
+    MainDispatcher *main_dispatcher;
 };
 
 #endif
diff --git a/server/reds-stream.c b/server/reds-stream.c
index ec720e0..140b767 100644
--- a/server/reds-stream.c
+++ b/server/reds-stream.c
@@ -349,7 +349,9 @@ void reds_stream_free(RedsStream *s)
 
 void reds_stream_push_channel_event(RedsStream *s, int event)
 {
-    main_dispatcher_channel_event(event, s->priv->info);
+    RedsState *reds = s->priv->reds;
+    MainDispatcher *md = reds_get_main_dispatcher(reds);
+    main_dispatcher_channel_event(md, event, s->priv->info);
 }
 
 static void reds_stream_set_socket(RedsStream *stream, int socket)
diff --git a/server/reds.c b/server/reds.c
index b13256a..e12fdce 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -3350,7 +3350,7 @@ static int do_spice_init(RedsState *reds, SpiceCoreInterface *core_interface)
     reds_init_vd_agent_resources(reds);
     ring_init(&reds->clients);
     reds->num_clients = 0;
-    main_dispatcher_init(reds->core);
+    reds->main_dispatcher = main_dispatcher_new(reds, reds->core);
     ring_init(&reds->channels);
     ring_init(&reds->mig_target_clients);
     ring_init(&reds->char_devs_states);
@@ -4195,3 +4195,8 @@ uint32_t reds_qxl_ram_size(RedsState *reds)
     first = reds->dispatchers->data;
     return red_dispatcher_qxl_ram_size(first);
 }
+
+MainDispatcher* reds_get_main_dispatcher(RedsState *reds)
+{
+    return reds->main_dispatcher;
+}
diff --git a/server/reds.h b/server/reds.h
index 686aaac..891a1ea 100644
--- a/server/reds.h
+++ b/server/reds.h
@@ -28,6 +28,7 @@
 #include "common/messages.h"
 #include "spice.h"
 #include "red-channel.h"
+#include "main-dispatcher.h"
 #include "migration-protocol.h"
 
 typedef struct RedsState RedsState;
@@ -115,5 +116,6 @@ void reds_update_client_mouse_allowed(RedsState *reds);
 gboolean reds_use_client_monitors_config(RedsState *reds);
 void reds_client_monitors_config(RedsState *reds, VDAgentMonitorsConfig *monitors_config);
 void reds_set_mm_time(RedsState *reds, uint32_t mm_time);
+MainDispatcher* reds_get_main_dispatcher(RedsState *reds);
 
 #endif
diff --git a/server/stream.c b/server/stream.c
index 3120860..2bfb993 100644
--- a/server/stream.c
+++ b/server/stream.c
@@ -683,6 +683,7 @@ static void update_client_playback_delay(void *opaque, uint32_t delay_ms)
 {
     StreamAgent *agent = opaque;
     DisplayChannelClient *dcc = agent->dcc;
+    RedsState *reds = red_channel_get_server(dcc->common.base.channel);
 
     dcc_update_streams_max_latency(dcc, agent);
 
@@ -691,7 +692,9 @@ static void update_client_playback_delay(void *opaque, uint32_t delay_ms)
         agent->dcc->streams_max_latency = delay_ms;
     }
     spice_debug("resetting client latency: %u", agent->dcc->streams_max_latency);
-    main_dispatcher_set_mm_time_latency(RED_CHANNEL_CLIENT(agent->dcc)->client, agent->dcc->streams_max_latency);
+    main_dispatcher_set_mm_time_latency(reds_get_main_dispatcher(reds),
+                                        RED_CHANNEL_CLIENT(agent->dcc)->client,
+                                        agent->dcc->streams_max_latency);
 }
 
 void dcc_create_stream(DisplayChannelClient *dcc, Stream *stream)
commit bc5c07a88109422c8c1e22a68b3d6f0606b74646
Author: Jonathon Jongsma <jjongsma at redhat.com>
Date:   Fri Feb 6 14:39:39 2015 -0600

    Add red_channel_get_server()
    
    Instead of poking into the internals of the RedChannel, provide an
    accessor.
    
    Acked-by: Fabiano Fidêncio <fidencio at redhat.com>

diff --git a/server/inputs-channel.c b/server/inputs-channel.c
index bb1c5ea..df031ef 100644
--- a/server/inputs-channel.c
+++ b/server/inputs-channel.c
@@ -305,7 +305,7 @@ static int inputs_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, ui
     InputsChannel *inputs_channel = (InputsChannel *)rcc->channel;
     InputsChannelClient *icc = (InputsChannelClient *)rcc;
     uint32_t i;
-    RedsState *reds = inputs_channel->base.reds;
+    RedsState *reds = red_channel_get_server(&inputs_channel->base);
 
     switch (type) {
     case SPICE_MSGC_INPUTS_KEY_DOWN: {
@@ -676,7 +676,7 @@ int inputs_channel_set_keyboard(InputsChannel *inputs, SpiceKbdInstance *keyboar
         return -1;
     }
     inputs->keyboard = keyboard;
-    inputs->keyboard->st = spice_kbd_state_new(inputs->base.reds);
+    inputs->keyboard->st = spice_kbd_state_new(red_channel_get_server(&inputs->base));
     return 0;
 }
 
diff --git a/server/main-channel.c b/server/main-channel.c
index f2b9fd7..65f862d 100644
--- a/server/main-channel.c
+++ b/server/main-channel.c
@@ -1088,7 +1088,7 @@ static MainChannelClient *main_channel_client_create(MainChannel *main_chan, Red
     mcc->connection_id = connection_id;
     mcc->bitrate_per_sec = ~0;
 #ifdef RED_STATISTICS
-    core = reds_get_core_interface(main_chan->base.reds);
+    core = reds_get_core_interface(red_channel_get_server(&main_chan->base));
     if (!(mcc->ping_timer = core->timer_add(core, ping_timer_cb, NULL))) {
         spice_error("ping timer create failed");
     }
diff --git a/server/red-channel.c b/server/red-channel.c
index d614955..757bb6e 100644
--- a/server/red-channel.c
+++ b/server/red-channel.c
@@ -2453,3 +2453,8 @@ void red_channel_client_disconnect_if_pending_send(RedChannelClient *rcc)
         spice_assert(red_channel_client_no_item_being_sent(rcc));
     }
 }
+
+RedsState* red_channel_get_server(RedChannel *channel)
+{
+    return channel->reds;
+}
diff --git a/server/red-channel.h b/server/red-channel.h
index 26bd3f9..2d61bc5 100644
--- a/server/red-channel.h
+++ b/server/red-channel.h
@@ -47,6 +47,8 @@
    The intention is to move towards one channel interface gradually.
    At the final stage, this interface shouldn't be exposed. Only RedChannel will use it. */
 
+struct RedsState;
+
 typedef struct SpiceDataHeaderOpaque SpiceDataHeaderOpaque;
 
 typedef uint16_t (*get_msg_type_proc)(SpiceDataHeaderOpaque *header);
@@ -565,8 +567,7 @@ uint32_t red_channel_sum_pipes_size(RedChannel *channel);
 typedef void (*channel_client_callback)(RedChannelClient *rcc);
 typedef void (*channel_client_callback_data)(RedChannelClient *rcc, void *data);
 void red_channel_apply_clients(RedChannel *channel, channel_client_callback v);
-
-struct RedsState;
+struct RedsState* red_channel_get_server(RedChannel *channel);
 
 struct RedClient {
     struct RedsState *reds;


More information about the Spice-commits mailing list