[Spice-devel] [PATCH 07/17] Remove global 'dispatchers', 'num_active_workers' variables

Frediano Ziglio fziglio at redhat.com
Fri Feb 12 15:59:38 UTC 2016


> 
> On Fri, 2016-02-12 at 07:41 -0500, Frediano Ziglio wrote:
> > > 
> > > From: Jonathon Jongsma <jjongsma at redhat.com>
> > > 
> > > Since these are server-level variables, move them into RedsState.
> > > However, num_active_workers was removed because:
> > > - each dispatcher always has 1 active worker, so we can determine the
> > >   number of active workers by counting the dispatchers
> > > - it was never actually set correctly. Even if there was more than one
> > >   worker, this variable was always only set to either 0 or 1.
> > > 
> > > This change required moving a bunch of helper code into RedsState as
> > > well, an providing some RedDispatcher interfaces to access dispatcher
> > > information from RedsState.
> > 
> > This patch has two main problems:
> > 1- is really big;
> > 2- code is broken.
> > 
> > Due to 1 I cannot understand why 2, I'll try to split the patch.
> 
> You can feel free to ask me to do the split if you want ;)
> 

Started and found the issue. Quite hidden!
I have to sort out my (ugly) fix and put everything together again.

I also fixed another bug in the patches, now the branch is compiling
and running! (at least base testings)

Frediano

> 
> > 
> > Frediano
> > 
> > 
> > > ---
> > >  server/agent-msg-filter.c |   3 +-
> > >  server/red-dispatcher.c   | 229
> > >  +++++++++++++---------------------------------
> > >  server/red-dispatcher.h   |  26 +++---
> > >  server/reds-private.h     |   2 +-
> > >  server/reds.c             | 170 +++++++++++++++++++++++++++++++---
> > >  server/reds.h             |   4 +
> > >  6 files changed, 243 insertions(+), 191 deletions(-)
> > > 
> > > diff --git a/server/agent-msg-filter.c b/server/agent-msg-filter.c
> > > index 1c1c01f..069822b 100644
> > > --- a/server/agent-msg-filter.c
> > > +++ b/server/agent-msg-filter.c
> > > @@ -24,6 +24,7 @@
> > >  #include <string.h>
> > >  #include "red-common.h"
> > >  #include "agent-msg-filter.h"
> > > +#include "reds.h"
> > >  #include "red-dispatcher.h"
> > >  
> > >  void agent_msg_filter_init(struct AgentMsgFilter *filter,
> > > @@ -92,7 +93,7 @@ data_to_read:
> > >              }
> > >              break;
> > >          case VD_AGENT_MONITORS_CONFIG:
> > > -            if (red_dispatcher_use_client_monitors_config()) {
> > > +            if (reds_use_client_monitors_config(reds)) {
> > >                  filter->result = AGENT_MSG_FILTER_MONITORS_CONFIG;
> > >              } else {
> > >                  filter->result = AGENT_MSG_FILTER_OK;
> > > diff --git a/server/red-dispatcher.c b/server/red-dispatcher.c
> > > index dce20c4..ead598d 100644
> > > --- a/server/red-dispatcher.c
> > > +++ b/server/red-dispatcher.c
> > > @@ -39,7 +39,6 @@
> > >  
> > >  #include "red-dispatcher.h"
> > >  
> > > -static int num_active_workers = 0;
> > >  
> > >  struct AsyncCommand {
> > >      RingItem link;
> > > @@ -56,15 +55,12 @@ struct RedDispatcher {
> > >      int x_res;
> > >      int y_res;
> > >      int use_hardware_cursor;
> > > -    RedDispatcher *next;
> > >      Ring async_commands;
> > >      pthread_mutex_t  async_lock;
> > >      QXLDevSurfaceCreate surface_create;
> > >      unsigned int max_monitors;
> > >  };
> > >  
> > > -static RedDispatcher *dispatchers = NULL;
> > > -
> > >  static int red_dispatcher_check_qxl_version(RedDispatcher *rd, int
> > >  major,
> > >  int minor)
> > >  {
> > >      int qxl_major = rd->qxl->st->qif->base.major_version;
> > > @@ -194,42 +190,6 @@ static void
> > > red_dispatcher_cursor_migrate(RedChannelClient *rcc)
> > >                              &payload);
> > >  }
> > >  
> > > -int red_dispatcher_qxl_count(void)
> > > -{
> > > -    return num_active_workers;
> > > -}
> > > -
> > > -static void update_client_mouse_allowed(void)
> > > -{
> > > -    static int allowed = FALSE;
> > > -    int allow_now = FALSE;
> > > -    int x_res = 0;
> > > -    int y_res = 0;
> > > -
> > > -    if (num_active_workers > 0) {
> > > -        allow_now = TRUE;
> > > -        RedDispatcher *now = dispatchers;
> > > -        while (now && allow_now) {
> > > -            if (now->primary_active) {
> > > -                allow_now = now->use_hardware_cursor;
> > > -                if (num_active_workers == 1) {
> > > -                    if (allow_now) {
> > > -                        x_res = now->x_res;
> > > -                        y_res = now->y_res;
> > > -                    }
> > > -                    break;
> > > -                }
> > > -            }
> > > -            now = now->next;
> > > -        }
> > > -    }
> > > -
> > > -    if (allow_now || allow_now != allowed) {
> > > -        allowed = allow_now;
> > > -        reds_set_client_mouse_allowed(reds, allowed, x_res, y_res);
> > > -    }
> > > -}
> > > -
> > >  static void red_dispatcher_update_area(RedDispatcher *dispatcher,
> > >  uint32_t
> > >  surface_id,
> > >                                     QXLRect *qxl_area, QXLRect
> > >                                     *qxl_dirty_rects,
> > >                                     uint32_t num_dirty_rects, uint32_t
> > >                                     clear_dirty_region)
> > > @@ -246,37 +206,19 @@ static void
> > > red_dispatcher_update_area(RedDispatcher
> > > *dispatcher, uint32_t surfa
> > >                              &payload);
> > >  }
> > >  
> > > -int red_dispatcher_use_client_monitors_config(void)
> > > +gboolean red_dispatcher_use_client_monitors_config(RedDispatcher
> > > *dispatcher)
> > >  {
> > > -    RedDispatcher *now = dispatchers;
> > > -
> > > -    if (num_active_workers == 0) {
> > > -        return FALSE;
> > > -    }
> > > -
> > > -    for (; now ; now = now->next) {
> > > -        if (!red_dispatcher_check_qxl_version(now, 3, 3) ||
> > > -            !now->qxl->st->qif->client_monitors_config ||
> > > -            !now->qxl->st->qif->client_monitors_config(now->qxl, NULL))
> > > {
> > > -            return FALSE;
> > > -        }
> > > -    }
> > > -    return TRUE;
> > > +    return (red_dispatcher_check_qxl_version(dispatcher, 3, 3) &&
> > > +        dispatcher->qxl->st->qif->client_monitors_config &&
> > > +
> > > dispatcher->qxl->st->qif->client_monitors_config(dispatcher->qxl,
> > > NULL));
> > >  }
> > >  
> > > -void red_dispatcher_client_monitors_config(VDAgentMonitorsConfig
> > > *monitors_config)
> > > +gboolean red_dispatcher_client_monitors_config(RedDispatcher
> > > *dispatcher,
> > > +                                               VDAgentMonitorsConfig
> > > *monitors_config)
> > >  {
> > > -    RedDispatcher *now = dispatchers;
> > > -
> > > -    while (now) {
> > > -        if (!now->qxl->st->qif->client_monitors_config ||
> > > -            !now->qxl->st->qif->client_monitors_config(now->qxl,
> > > -                                                       monitors_config))
> > > {
> > > -            /* this is a normal condition, some qemu devices might not
> > > implement it */
> > > -            spice_debug("QXLInterface::client_monitors_config failed");
> > > -        }
> > > -        now = now->next;
> > > -    }
> > > +    return (dispatcher->qxl->st->qif->client_monitors_config &&
> > > +
> > > dispatcher->qxl->st->qif->client_monitors_config(dispatcher->qxl,
> > > +
> > >  monitors_config));
> > >  }
> > >  
> > >  static AsyncCommand *async_command_alloc(RedDispatcher *dispatcher,
> > > @@ -391,7 +333,7 @@ static void
> > > red_dispatcher_destroy_primary_surface_complete(RedDispatcher *dispa
> > >      dispatcher->use_hardware_cursor = FALSE;
> > >      dispatcher->primary_active = FALSE;
> > >  
> > > -    update_client_mouse_allowed();
> > > +    reds_update_client_mouse_allowed(reds);
> > >  }
> > >  
> > >  static void
> > > @@ -443,7 +385,7 @@ static void
> > > red_dispatcher_create_primary_surface_complete(RedDispatcher *dispat
> > >      dispatcher->use_hardware_cursor = surface->mouse_mode;
> > >      dispatcher->primary_active = TRUE;
> > >  
> > > -    update_client_mouse_allowed();
> > > +    reds_update_client_mouse_allowed(reds);
> > >      memset(&dispatcher->surface_create, 0, sizeof(QXLDevSurfaceCreate));
> > >  }
> > >  
> > > @@ -619,7 +561,7 @@ static void qxl_worker_oom(QXLWorker *qxl_worker)
> > >      red_dispatcher_oom((RedDispatcher*)qxl_worker);
> > >  }
> > >  
> > > -static void red_dispatcher_start(RedDispatcher *dispatcher)
> > > +void red_dispatcher_start(RedDispatcher *dispatcher)
> > >  {
> > >      RedWorkerMessageStart payload;
> > >  
> > > @@ -667,7 +609,7 @@ static void
> > > red_dispatcher_driver_unload(RedDispatcher
> > > *dispatcher)
> > >                              &payload);
> > >  }
> > >  
> > > -static void red_dispatcher_stop(RedDispatcher *dispatcher)
> > > +void red_dispatcher_stop(RedDispatcher *dispatcher)
> > >  {
> > >      RedWorkerMessageStop payload;
> > >  
> > > @@ -702,103 +644,20 @@ static void qxl_worker_loadvm_commands(QXLWorker
> > > *qxl_worker,
> > >      red_dispatcher_loadvm_commands((RedDispatcher*)qxl_worker, ext,
> > >      count);
> > >  }
> > >  
> > > -static inline int calc_compression_level(void)
> > > +void red_dispatcher_set_mm_time(RedDispatcher *dispatcher, uint32_t
> > > mm_time)
> > >  {
> > > -    spice_assert(reds_get_streaming_video(reds) !=
> > > SPICE_STREAM_VIDEO_INVALID);
> > > -
> > > -    if ((reds_get_streaming_video(reds) != SPICE_STREAM_VIDEO_OFF) ||
> > > -        (spice_server_get_image_compression(reds) !=
> > > SPICE_IMAGE_COMPRESSION_QUIC)) {
> > > -        return 0;
> > > -    } else {
> > > -        return 1;
> > > -    }
> > > -}
> > > -
> > > -void red_dispatcher_on_ic_change(void)
> > > -{
> > > -    RedWorkerMessageSetCompression payload;
> > > -    int compression_level = calc_compression_level();
> > > -    RedDispatcher *now = dispatchers;
> > > -
> > > -    while (now) {
> > > -        now->qxl->st->qif->set_compression_level(now->qxl,
> > > compression_level);
> > > -        payload.image_compression =
> > > spice_server_get_image_compression(reds);
> > > -        dispatcher_send_message(&now->dispatcher,
> > > -                                RED_WORKER_MESSAGE_SET_COMPRESSION,
> > > -                                &payload);
> > > -        now = now->next;
> > > -    }
> > > -}
> > > -
> > > -void red_dispatcher_on_sv_change(void)
> > > -{
> > > -    RedWorkerMessageSetStreamingVideo payload;
> > > -    int compression_level = calc_compression_level();
> > > -    RedDispatcher *now = dispatchers;
> > > -    while (now) {
> > > -        now->qxl->st->qif->set_compression_level(now->qxl,
> > > compression_level);
> > > -        payload.streaming_video = reds_get_streaming_video(reds);
> > > -        dispatcher_send_message(&now->dispatcher,
> > > -                                RED_WORKER_MESSAGE_SET_STREAMING_VIDEO,
> > > -                                &payload);
> > > -        now = now->next;
> > > -    }
> > > +    dispatcher->qxl->st->qif->set_mm_time(dispatcher->qxl, mm_time);
> > >  }
> > >  
> > > -void red_dispatcher_set_mouse_mode(uint32_t mode)
> > > +void red_dispatcher_set_compression_level(RedDispatcher *dispatcher, int
> > > level)
> > >  {
> > > -    RedWorkerMessageSetMouseMode payload;
> > > -    RedDispatcher *now = dispatchers;
> > > -    while (now) {
> > > -        payload.mode = mode;
> > > -        dispatcher_send_message(&now->dispatcher,
> > > -                                RED_WORKER_MESSAGE_SET_MOUSE_MODE,
> > > -                                &payload);
> > > -        now = now->next;
> > > -    }
> > > -}
> > > -
> > > -void red_dispatcher_on_vm_stop(void)
> > > -{
> > > -    RedDispatcher *now = dispatchers;
> > > -
> > > -    spice_debug(NULL);
> > > -    while (now) {
> > > -        red_dispatcher_stop(now);
> > > -        now = now->next;
> > > -    }
> > > +    dispatcher->qxl->st->qif->set_compression_level(dispatcher->qxl,
> > > level);
> > >  }
> > >  
> > > -void red_dispatcher_on_vm_start(void)
> > > -{
> > > -    RedDispatcher *now = dispatchers;
> > > -
> > > -    spice_debug(NULL);
> > > -    while (now) {
> > > -        red_dispatcher_start(now);
> > > -        now = now->next;
> > > -    }
> > > -}
> > > -
> > > -int red_dispatcher_count(void)
> > > -{
> > > -    RedDispatcher *now = dispatchers;
> > > -    int ret = 0;
> > > -
> > > -    while (now) {
> > > -        ret++;
> > > -        now = now->next;
> > > -    }
> > > -    return ret;
> > > -}
> > > -
> > > -uint32_t red_dispatcher_qxl_ram_size(void)
> > > +uint32_t red_dispatcher_qxl_ram_size(RedDispatcher *dispatcher)
> > >  {
> > >      QXLDevInitInfo qxl_info;
> > > -    if (!dispatchers) {
> > > -        return 0;
> > > -    }
> > > -    dispatchers->qxl->st->qif->get_init_info(dispatchers->qxl,
> > > &qxl_info);
> > > +    dispatcher->qxl->st->qif->get_init_info(dispatcher->qxl, &qxl_info);
> > >      return qxl_info.qxl_ram_size;
> > >  }
> > >  
> > > @@ -1049,7 +908,7 @@ void red_dispatcher_async_complete(struct
> > > RedDispatcher
> > > *dispatcher,
> > >      free(async_command);
> > >  }
> > >  
> > > -void red_dispatcher_init(QXLInstance *qxl)
> > > +void red_dispatcher_init(QXLInstance *qxl, int compression_level)
> > >  {
> > >      RedDispatcher *red_dispatcher;
> > >      RedChannel *channel;
> > > @@ -1116,14 +975,11 @@ void red_dispatcher_init(QXLInstance *qxl)
> > >      reds_register_channel(reds, channel);
> > >  
> > >      red_worker_run(worker);
> > > -    num_active_workers = 1;
> > >  
> > >      qxl->st->dispatcher = red_dispatcher;
> > > -    red_dispatcher->next = dispatchers;
> > > -    dispatchers = red_dispatcher;
> > >  
> > >      qxl->st->qif->attache_worker(qxl, &red_dispatcher->base);
> > > -    qxl->st->qif->set_compression_level(qxl, calc_compression_level());
> > > +    qxl->st->qif->set_compression_level(qxl, compression_level);
> > >  }
> > >  
> > >  struct Dispatcher *red_dispatcher_get_dispatcher(RedDispatcher
> > >  *red_dispatcher)
> > > @@ -1143,3 +999,46 @@ void red_dispatcher_clear_pending(RedDispatcher
> > > *red_dispatcher, int pending)
> > >  
> > >      clear_bit(pending, &red_dispatcher->pending);
> > >  }
> > > +
> > > +gboolean red_dispatcher_get_primary_active(RedDispatcher *dispatcher)
> > > +{
> > > +    return dispatcher->primary_active;
> > > +}
> > > +
> > > +gboolean red_dispatcher_get_allow_client_mouse(RedDispatcher
> > > *dispatcher,
> > > gint *x_res, gint *y_res)
> > > +{
> > > +    if (dispatcher->use_hardware_cursor) {
> > > +        if (x_res)
> > > +            *x_res = dispatcher->x_res;
> > > +        if (y_res)
> > > +            *y_res = dispatcher->y_res;
> > > +    }
> > > +    return dispatcher->use_hardware_cursor;
> > > +}
> > > +
> > > +void red_dispatcher_on_ic_change(RedDispatcher *dispatcher,
> > > SpiceImageCompression ic)
> > > +{
> > > +    RedWorkerMessageSetCompression payload;
> > > +    payload.image_compression = ic;
> > > +    dispatcher_send_message(&dispatcher->dispatcher,
> > > +                            RED_WORKER_MESSAGE_SET_COMPRESSION,
> > > +                            &payload);
> > > +}
> > > +
> > > +void red_dispatcher_on_sv_change(RedDispatcher *dispatcher, int sv)
> > > +{
> > > +    RedWorkerMessageSetStreamingVideo payload;
> > > +    payload.streaming_video = sv;
> > > +    dispatcher_send_message(&dispatcher->dispatcher,
> > > +                            RED_WORKER_MESSAGE_SET_STREAMING_VIDEO,
> > > +                            &payload);
> > > +}
> > > +
> > > +void red_dispatcher_set_mouse_mode(RedDispatcher *dispatcher, uint32_t
> > > mode)
> > > +{
> > > +    RedWorkerMessageSetMouseMode payload;
> > > +    payload.mode = mode;
> > > +    dispatcher_send_message(&dispatcher->dispatcher,
> > > +                            RED_WORKER_MESSAGE_SET_MOUSE_MODE,
> > > +                            &payload);
> > > +}
> > > diff --git a/server/red-dispatcher.h b/server/red-dispatcher.h
> > > index 11a4f2a..e62092f 100644
> > > --- a/server/red-dispatcher.h
> > > +++ b/server/red-dispatcher.h
> > > @@ -24,20 +24,22 @@ typedef struct RedDispatcher RedDispatcher;
> > >  
> > >  typedef struct AsyncCommand AsyncCommand;
> > >  
> > > -void red_dispatcher_init(QXLInstance *qxl);
> > > -
> > > -void red_dispatcher_on_ic_change(void);
> > > -void red_dispatcher_on_sv_change(void);
> > > -void red_dispatcher_set_mouse_mode(uint32_t mode);
> > > -void red_dispatcher_on_vm_stop(void);
> > > -void red_dispatcher_on_vm_start(void);
> > > -int red_dispatcher_count(void);
> > > -uint32_t red_dispatcher_qxl_ram_size(void);
> > > -int red_dispatcher_qxl_count(void);
> > > +void red_dispatcher_init(QXLInstance *qxl, int compression_level);
> > > +
> > > +void red_dispatcher_set_mm_time(RedDispatcher *dispatcher, uint32_t);
> > > +void red_dispatcher_on_ic_change(RedDispatcher *dispatcher,
> > > SpiceImageCompression ic);
> > > +void red_dispatcher_on_sv_change(RedDispatcher *dispatcher, int sv);
> > > +void red_dispatcher_set_mouse_mode(RedDispatcher *dispatcher, uint32_t
> > > mode);
> > > +void red_dispatcher_set_compression_level(RedDispatcher *dispatcher, int
> > > level);
> > > +void red_dispatcher_stop(RedDispatcher *dispatcher);
> > > +void red_dispatcher_start(RedDispatcher *dispatcher);
> > > +uint32_t red_dispatcher_qxl_ram_size(RedDispatcher *dispatcher);
> > >  void red_dispatcher_async_complete(struct RedDispatcher *, AsyncCommand
> > >  *);
> > >  struct Dispatcher *red_dispatcher_get_dispatcher(struct RedDispatcher
> > >  *);
> > > -int red_dispatcher_use_client_monitors_config(void);
> > > -void red_dispatcher_client_monitors_config(VDAgentMonitorsConfig
> > > *monitors_config);
> > > +gboolean red_dispatcher_use_client_monitors_config(RedDispatcher
> > > *dispatcher);
> > > +gboolean red_dispatcher_client_monitors_config(RedDispatcher
> > > *dispatcher,
> > > VDAgentMonitorsConfig *monitors_config);
> > > +gboolean red_dispatcher_get_primary_active(RedDispatcher *dispatcher);
> > > +gboolean red_dispatcher_get_allow_client_mouse(RedDispatcher
> > > *dispatcher,
> > > gint *x_res, gint *y_res);
> > >  
> > >  typedef uint32_t RedWorkerMessage;
> > >  
> > > diff --git a/server/reds-private.h b/server/reds-private.h
> > > index 2272d4c..c214091 100644
> > > --- a/server/reds-private.h
> > > +++ b/server/reds-private.h
> > > @@ -241,7 +241,7 @@ struct RedsState {
> > >  
> > >      RedSSLParameters ssl_parameters;
> > >      SpiceCoreInterfaceInternal *core;
> > > -
> > > +    GList *dispatchers;
> > >  };
> > >  
> > >  #endif
> > > diff --git a/server/reds.c b/server/reds.c
> > > index 81a9220..eec8086 100644
> > > --- a/server/reds.c
> > > +++ b/server/reds.c
> > > @@ -172,6 +172,13 @@ static void
> > > reds_mig_remove_wait_disconnect_client(RedsState *reds, RedClient *c
> > >  static void reds_char_device_add_state(RedsState *reds,
> > > SpiceCharDeviceState
> > >  *st);
> > >  static void reds_char_device_remove_state(RedsState *reds,
> > >  SpiceCharDeviceState *st);
> > >  static void reds_send_mm_time(RedsState *reds);
> > > +static void reds_on_ic_change(RedsState *reds);
> > > +static void reds_on_sv_change(RedsState *reds);
> > > +static void reds_on_vm_stop(RedsState *reds);
> > > +static void reds_on_vm_start(RedsState *reds);
> > > +static void reds_set_mouse_mode(RedsState *reds, uint32_t mode);
> > > +static uint32_t reds_qxl_ram_size(RedsState *reds);
> > > +static int calc_compression_level(RedsState *reds);
> > >  
> > >  static VDIReadBuf *vdi_port_state_get_read_buf(VDIPortState *state);
> > >  static VDIReadBuf *vdi_port_read_buf_ref(VDIReadBuf *buf);
> > > @@ -556,11 +563,16 @@ int reds_get_mouse_mode(RedsState *reds)
> > >  
> > >  static void reds_set_mouse_mode(RedsState *reds, uint32_t mode)
> > >  {
> > > +    GList *l;
> > > +
> > >      if (reds->mouse_mode == mode) {
> > >          return;
> > >      }
> > >      reds->mouse_mode = mode;
> > > -    red_dispatcher_set_mouse_mode(reds->mouse_mode);
> > > +
> > > +    for (l = reds->dispatchers; l != NULL; l = l->next)
> > > +        red_dispatcher_set_mouse_mode(l->data, mode);
> > > +
> > >      main_channel_push_mouse_mode(reds->main_channel, reds->mouse_mode,
> > >      reds->is_client_mouse_allowed);
> > >  }
> > >  
> > > @@ -572,7 +584,7 @@ gboolean reds_get_agent_mouse(const RedsState *reds)
> > >  static void reds_update_mouse_mode(RedsState *reds)
> > >  {
> > >      int allowed = 0;
> > > -    int qxl_count = red_dispatcher_qxl_count();
> > > +    int qxl_count = g_list_length(reds->dispatchers);
> > >  
> > >      if ((reds->agent_mouse && reds->vdagent) ||
> > >          (inputs_channel_has_tablet(reds->inputs_channel) && qxl_count ==
> > > 1))
> > >          {
> > > @@ -1025,7 +1037,7 @@ static void
> > > reds_on_main_agent_monitors_config(RedsState *reds,
> > >      }
> > >      monitors_config = (VDAgentMonitorsConfig *)(cmc->buffer +
> > >      sizeof(*msg_header));
> > >      spice_debug("%s: %d", __func__, monitors_config->num_of_monitors);
> > > -    red_dispatcher_client_monitors_config(monitors_config);
> > > +    reds_client_monitors_config(reds, monitors_config);
> > >      reds_client_monitors_config_cleanup(reds);
> > >  }
> > >  
> > > @@ -1669,10 +1681,10 @@ static void reds_handle_main_link(RedsState
> > > *reds,
> > > RedLinkInfo *link)
> > >      }
> > >  
> > >      if (!mig_target) {
> > > -        main_channel_push_init(mcc, red_dispatcher_count(),
> > > +        main_channel_push_init(mcc, g_list_length(reds->dispatchers),
> > >              reds->mouse_mode, reds->is_client_mouse_allowed,
> > >              reds_get_mm_time() - MM_TIME_DELTA,
> > > -            red_dispatcher_qxl_ram_size());
> > > +            reds_qxl_ram_size(reds));
> > >          if (reds->spice_name)
> > >              main_channel_push_name(mcc, reds->spice_name);
> > >          if (reds->spice_uuid_is_set)
> > > @@ -1815,10 +1827,10 @@ void
> > > reds_on_client_semi_seamless_migrate_complete(RedsState *reds, RedClient
> > > *c
> > >      mcc = red_client_get_main(client);
> > >  
> > >      // TODO: not doing net test. consider doing it on
> > >      client_migrate_info
> > > -    main_channel_push_init(mcc, red_dispatcher_count(),
> > > +    main_channel_push_init(mcc, g_list_length(reds->dispatchers),
> > >                             reds->mouse_mode,
> > >                             reds->is_client_mouse_allowed,
> > >                             reds_get_mm_time() - MM_TIME_DELTA,
> > > -                           red_dispatcher_qxl_ram_size());
> > > +                           reds_qxl_ram_size(reds));
> > >      reds_link_mig_target_channels(reds, client);
> > >      main_channel_migrate_dst_complete(mcc);
> > >  }
> > > @@ -2769,7 +2781,7 @@ static void reds_set_image_compression(RedsState
> > > *reds,
> > > SpiceImageCompression va
> > >          return;
> > >      }
> > >      reds->image_compression = val;
> > > -    red_dispatcher_on_ic_change();
> > > +    reds_on_ic_change(reds);
> > >  }
> > >  
> > >  static void reds_set_one_channel_security(RedsState *reds, int id,
> > >  uint32_t
> > >  security)
> > > @@ -3196,7 +3208,8 @@ SPICE_GNUC_VISIBLE int
> > > spice_server_add_interface(SpiceServer *s,
> > >          pthread_mutex_init(&qxl->st->scanout_mutex, NULL);
> > >          qxl->st->scanout.drm_dma_buf_fd = -1;
> > >          qxl->st->qif = SPICE_CONTAINEROF(interface, QXLInterface, base);
> > > -        red_dispatcher_init(qxl);
> > > +        red_dispatcher_init(qxl, calc_compression_level(reds));
> > > +        reds->dispatchers = g_list_prepend(reds->dispatchers,
> > > qxl->st->dispatcher);
> > >  
> > >      } else if (strcmp(interface->type, SPICE_INTERFACE_TABLET) == 0) {
> > >          SpiceTabletInstance *tablet = SPICE_CONTAINEROF(sin,
> > >          SpiceTabletInstance, base);
> > > @@ -3791,7 +3804,7 @@ SPICE_GNUC_VISIBLE int
> > > spice_server_set_streaming_video(SpiceServer *s, int valu
> > >          value != SPICE_STREAM_VIDEO_FILTER)
> > >          return -1;
> > >      s->streaming_video = value;
> > > -    red_dispatcher_on_sv_change();
> > > +    reds_on_sv_change(reds);
> > >      return 0;
> > >  }
> > >  
> > > @@ -3991,7 +4004,7 @@ SPICE_GNUC_VISIBLE void
> > > spice_server_vm_start(SpiceServer *s)
> > >          st_item = SPICE_CONTAINEROF(item, SpiceCharDeviceStateItem,
> > >          link);
> > >          spice_char_device_start(st_item->st);
> > >      }
> > > -    red_dispatcher_on_vm_start();
> > > +    reds_on_vm_start(reds);
> > >  }
> > >  
> > >  SPICE_GNUC_VISIBLE void spice_server_vm_stop(SpiceServer *s)
> > > @@ -4006,7 +4019,7 @@ SPICE_GNUC_VISIBLE void
> > > spice_server_vm_stop(SpiceServer *s)
> > >          st_item = SPICE_CONTAINEROF(item, SpiceCharDeviceStateItem,
> > >          link);
> > >          spice_char_device_stop(st_item->st);
> > >      }
> > > -    red_dispatcher_on_vm_stop();
> > > +    reds_on_vm_stop(reds);
> > >  }
> > >  
> > >  SPICE_GNUC_VISIBLE void spice_server_set_seamless_migration(SpiceServer
> > >  *s,
> > >  int enable)
> > > @@ -4043,3 +4056,136 @@ SpiceCoreInterfaceInternal*
> > > reds_get_core_interface(RedsState *reds)
> > >  {
> > >      return reds->core;
> > >  }
> > > +
> > > +void reds_update_client_mouse_allowed(RedsState *reds)
> > > +{
> > > +    static int allowed = FALSE;
> > > +    int allow_now = FALSE;
> > > +    int x_res = 0;
> > > +    int y_res = 0;
> > > +    GList *l;
> > > +    int num_active_workers = g_list_length(reds->dispatchers);
> > > +
> > > +    if (num_active_workers > 0) {
> > > +        allow_now = TRUE;
> > > +        for (l = reds->dispatchers; l != NULL && allow_now; l = l->next)
> > > {
> > > +
> > > +            RedDispatcher *now = l->data;
> > > +            if (red_dispatcher_get_primary_active(now)) {
> > > +                allow_now = red_dispatcher_get_allow_client_mouse(now,
> > > &x_res, &y_res);
> > > +                break;
> > > +            }
> > > +        }
> > > +    }
> > > +
> > > +    if (allow_now || allow_now != allowed) {
> > > +        allowed = allow_now;
> > > +        reds_set_client_mouse_allowed(reds, allowed, x_res, y_res);
> > > +    }
> > > +}
> > > +
> > > +gboolean reds_use_client_monitors_config(RedsState *reds)
> > > +{
> > > +    GList *l;
> > > +
> > > +    if (reds->dispatchers == NULL) {
> > > +        return FALSE;
> > > +    }
> > > +
> > > +    for (l = reds->dispatchers; l != NULL ; l = l->next) {
> > > +        RedDispatcher *now = l->data;
> > > +
> > > +        if (!red_dispatcher_use_client_monitors_config(now))
> > > +            return FALSE;
> > > +    }
> > > +    return TRUE;
> > > +}
> > > +
> > > +void reds_client_monitors_config(RedsState *reds, VDAgentMonitorsConfig
> > > *monitors_config)
> > > +{
> > > +    GList *l;
> > > +
> > > +    for (l = reds->dispatchers; l != NULL; l = l->next) {
> > > +        RedDispatcher *now = l->data;
> > > +        if (!red_dispatcher_client_monitors_config(now,
> > > monitors_config)) {
> > > +            /* this is a normal condition, some qemu devices might not
> > > implement it */
> > > +            spice_debug("QXLInterface::client_monitors_config
> > > failed\n");
> > > +        }
> > > +    }
> > > +}
> > > +
> > > +void reds_set_mm_time(RedsState *reds, uint32_t mm_time)
> > > +{
> > > +    GList *l;
> > > +
> > > +    for (l = reds->dispatchers; l != NULL; l = l->next) {
> > > +        RedDispatcher *now = l->data;
> > > +        red_dispatcher_set_mm_time(now, mm_time);
> > > +    }
> > > +}
> > > +
> > > +static int calc_compression_level(RedsState *reds)
> > > +{
> > > +    spice_assert(reds_get_streaming_video(reds) !=
> > > SPICE_STREAM_VIDEO_INVALID);
> > > +
> > > +    if ((reds_get_streaming_video(reds) != SPICE_STREAM_VIDEO_OFF) ||
> > > +        (spice_server_get_image_compression(reds) !=
> > > SPICE_IMAGE_COMPRESSION_QUIC)) {
> > > +        return 0;
> > > +    } else {
> > > +        return 1;
> > > +    }
> > > +}
> > > +
> > > +void reds_on_ic_change(RedsState *reds)
> > > +{
> > > +    int compression_level = calc_compression_level(reds);
> > > +    GList *l;
> > > +
> > > +    for (l = reds->dispatchers; l != NULL; l = l->next) {
> > > +        RedDispatcher *d = l->data;
> > > +        red_dispatcher_set_compression_level(d, compression_level);
> > > +        red_dispatcher_on_ic_change(d,
> > > spice_server_get_image_compression(reds));
> > > +    }
> > > +}
> > > +
> > > +void reds_on_sv_change(RedsState *reds)
> > > +{
> > > +    int compression_level = calc_compression_level(reds);
> > > +    GList *l;
> > > +
> > > +    for (l = reds->dispatchers; l != NULL; l = l->next) {
> > > +        RedDispatcher *d = l->data;
> > > +        red_dispatcher_set_compression_level(d, compression_level);
> > > +        red_dispatcher_on_sv_change(d, reds_get_streaming_video(reds));
> > > +    }
> > > +}
> > > +
> > > +void reds_on_vm_stop(RedsState *reds)
> > > +{
> > > +    GList *l;
> > > +
> > > +    spice_debug(NULL);
> > > +    for (l = reds->dispatchers; l != NULL; l = l->next)
> > > +        red_dispatcher_stop(l->data);
> > > +}
> > > +
> > > +void reds_on_vm_start(RedsState *reds)
> > > +{
> > > +    GList *l;
> > > +
> > > +    spice_debug(NULL);
> > > +    for (l = reds->dispatchers; l != NULL; l = l->next)
> > > +        red_dispatcher_start(l->data);
> > > +}
> > > +
> > > +uint32_t reds_qxl_ram_size(RedsState *reds)
> > > +{
> > > +    RedDispatcher *first;
> > > +    if (!reds->dispatchers) {
> > > +        return 0;
> > > +    }
> > > +
> > > +    first = reds->dispatchers->data;
> > > +    return red_dispatcher_qxl_ram_size(first);
> > > +}
> > > +
> > > diff --git a/server/reds.h b/server/reds.h
> > > index 6caed73..686aaac 100644
> > > --- a/server/reds.h
> > > +++ b/server/reds.h
> > > @@ -111,5 +111,9 @@ uint32_t reds_get_streaming_video(const RedsState
> > > *reds);
> > >  spice_wan_compression_t reds_get_jpeg_state(const RedsState *reds);
> > >  spice_wan_compression_t reds_get_zlib_glz_state(const RedsState *reds);
> > >  SpiceCoreInterfaceInternal* reds_get_core_interface(RedsState *reds);
> > > +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);
> > >  
> > >  #endif
> > 
> > _______________________________________________
> > Spice-devel mailing list
> > Spice-devel at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/spice-devel
> 


More information about the Spice-devel mailing list