[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