[Spice-devel] [PATCH 2/5] server/red_dispatcher: support concurrent asyncs

Yonit Halperin yhalperi at redhat.com
Sun Nov 6 23:39:39 PST 2011


Hi,

Ack after small fixes
On 11/06/2011 06:49 PM, Alon Levy wrote:
> This is part of the dispatcher update, extracting the dispatcher routine
> from red_dispatcher and main_dispatcher into dispatcher.
>
> Supporting multiple async operations will make it natural to support
> async monitor commands and async guest io requests that could overlap in
> time.
>
> Bugzilla: 42463
>
> Related: 41622
>
> rfc->v1:
>   use a Ring for AsyncCommands instead of a singly linked list.
>   s/push_async_command/async_command_alloc/
>   fix missing addressof in update_area_async
shouldn't be in the commit msg
> ---
>   server/red_dispatcher.c |  117 ++++++++++++++++++++++------------------------
>   server/red_dispatcher.h |    3 +-
>   server/red_worker.c     |    6 +-
>   3 files changed, 61 insertions(+), 65 deletions(-)
>
<snip>
>
> -void red_dispatcher_async_complete(struct RedDispatcher *dispatcher, uint64_t cookie)
> +void red_dispatcher_async_complete(struct RedDispatcher *dispatcher,
> +                                   AsyncCommand *async_command)
>   {
>       pthread_mutex_lock(&dispatcher->async_lock);
> -    switch (dispatcher->async_message) {
> +    ring_remove(&async_command->link);
> +    red_printf_debug(2, "%p: cookie %" PRId64, async_command, async_command->cookie);
> +    if (ring_is_empty(&dispatcher->async_commands)) {
> +        red_printf_debug(2, "%s: no more async commands", __func__);
> +    }
> +    pthread_mutex_unlock(&dispatcher->async_lock);
> +    switch (async_command->message) {
>       case RED_WORKER_MESSAGE_UPDATE_ASYNC:
>           break;
>       case RED_WORKER_MESSAGE_ADD_MEMSLOT_ASYNC:
> @@ -863,11 +858,11 @@ void red_dispatcher_async_complete(struct RedDispatcher *dispatcher, uint64_t co
>       case RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC:
>           break;
>       default:
> -        red_printf("unexpected message");
> +        WARN("unexpected message");
>       }
> -    dispatcher->async_message = RED_WORKER_MESSAGE_NOP;
> -    pthread_mutex_unlock(&dispatcher->async_lock);
> -    dispatcher->qxl->st->qif->async_complete(dispatcher->qxl, cookie);
> +    free(async_command);
> +    dispatcher->qxl->st->qif->async_complete(dispatcher->qxl,
> +                                             async_command->cookie);
accessing async_command after it is freed

>   }
>
>   static RedChannel *red_dispatcher_display_channel_create(RedDispatcher *dispatcher)
> @@ -922,6 +917,7 @@ RedDispatcher *red_dispatcher_init(QXLInstance *qxl)
>
>       dispatcher = spice_new0(RedDispatcher, 1);
>       dispatcher->channel = channels[0];
> +    ring_init(&dispatcher->async_commands);
>       init_data.qxl = dispatcher->qxl = qxl;
>       init_data.id = qxl->id;
>       init_data.channel = channels[1];
> @@ -929,7 +925,6 @@ RedDispatcher *red_dispatcher_init(QXLInstance *qxl)
>       init_data.num_renderers = num_renderers;
>       memcpy(init_data.renderers, renderers, sizeof(init_data.renderers));
>
> -    dispatcher->async_message = RED_WORKER_MESSAGE_NOP;
>       pthread_mutex_init(&dispatcher->async_lock, NULL);
>       init_data.image_compression = image_compression;
>       init_data.jpeg_state = jpeg_state;
> diff --git a/server/red_dispatcher.h b/server/red_dispatcher.h
> index 144a40e..c2582f4 100644
> --- a/server/red_dispatcher.h
> +++ b/server/red_dispatcher.h
> @@ -19,6 +19,7 @@
>   #define _H_RED_DISPATCHER
>
>   struct RedChannelClient;
> +typedef struct AsyncCommand AsyncCommand;
>
>   struct RedDispatcher *red_dispatcher_init(QXLInstance *qxl);
>
> @@ -30,6 +31,6 @@ int red_dispatcher_count(void);
>   int red_dispatcher_add_renderer(const char *name);
>   uint32_t red_dispatcher_qxl_ram_size(void);
>   int red_dispatcher_qxl_count(void);
> -void red_dispatcher_async_complete(struct RedDispatcher*, uint64_t);
> +void red_dispatcher_async_complete(struct RedDispatcher *, AsyncCommand *);
>
>   #endif
> diff --git a/server/red_worker.c b/server/red_worker.c
> index 4337d16..a5c2df3 100644
> --- a/server/red_worker.c
> +++ b/server/red_worker.c
> @@ -10383,7 +10383,7 @@ static void handle_dev_input(EventListener *listener, uint32_t events)
>       int ring_is_empty;
>       int call_async_complete = 0;
>       int write_ready = 0;
> -    uint64_t cookie;
> +    AsyncCommand *cmd;
>
>       read_message(worker->channel,&message);
>
> @@ -10398,7 +10398,7 @@ static void handle_dev_input(EventListener *listener, uint32_t events)
>       case RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT_ASYNC:
>       case RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC:
>           call_async_complete = 1;
> -        receive_data(worker->channel,&cookie, sizeof(cookie));
> +        receive_data(worker->channel,&cmd, sizeof(cmd));
>           break;
>       case RED_WORKER_MESSAGE_UPDATE:
>       case RED_WORKER_MESSAGE_ADD_MEMSLOT:
> @@ -10667,7 +10667,7 @@ static void handle_dev_input(EventListener *listener, uint32_t events)
>           red_error("message error");
>       }
>       if (call_async_complete) {
> -        red_dispatcher_async_complete(worker->dispatcher, cookie);
> +        red_dispatcher_async_complete(worker->dispatcher, cmd);
>       }
>       if (write_ready) {
>           message = RED_WORKER_MESSAGE_READY;



More information about the Spice-devel mailing list