[Spice-devel] [PATCH spice-server 1/2] red-qxl: Remove AsyncCommand
Frediano Ziglio
fziglio at redhat.com
Mon Sep 18 07:11:25 UTC 2017
ping
>
> This structure was used to store the cookie for the async
> reply and the message for the generic async callback.
> Most async messages do not require extra action beside
> sending back the cookie for the reply so instead of using
> a switch inline the replies and remove store the cookie
> directory instead of a pointer to AsyncCommand.
>
> Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> ---
> server/red-qxl.c | 71
> +++++++++++++----------------------------------------
> server/red-qxl.h | 1 +
> server/red-worker.c | 18 ++++++++------
> server/red-worker.h | 5 ++--
> 4 files changed, 31 insertions(+), 64 deletions(-)
>
> Not a regression but this change shows that
> red_qxl_destroy_primary_surface_complete and
> red_qxl_create_primary_surface_complete are called from the worker
> thread. This possibly can be a race condition as they call some
> functions in red-qxl.c and reds.c that possibly use structures that
> should only be used in the main thread.
>
> diff --git a/server/red-qxl.c b/server/red-qxl.c
> index 4ef293060..5815e4406 100644
> --- a/server/red-qxl.c
> +++ b/server/red-qxl.c
> @@ -41,11 +41,6 @@
> #include "red-qxl.h"
>
>
> -struct AsyncCommand {
> - RedWorkerMessage message;
> - uint64_t cookie;
> -};
> -
> struct QXLState {
> QXLWorker qxl_worker;
> QXLInstance *qxl;
> @@ -205,19 +200,6 @@ gboolean red_qxl_client_monitors_config(QXLInstance
> *qxl,
> qxl_get_interface(qxl)->client_monitors_config(qxl,
> monitors_config));
> }
>
> -static AsyncCommand *async_command_alloc(QXLState *qxl_state,
> - RedWorkerMessage message,
> - uint64_t cookie)
> -{
> - AsyncCommand *async_command = spice_new0(AsyncCommand, 1);
> -
> - async_command->cookie = cookie;
> - async_command->message = message;
> -
> - spice_debug("%p", async_command);
> - return async_command;
> -}
> -
> static void red_qxl_update_area_async(QXLState *qxl_state,
> uint32_t surface_id,
> QXLRect *qxl_area,
> @@ -227,7 +209,7 @@ static void red_qxl_update_area_async(QXLState
> *qxl_state,
> RedWorkerMessage message = RED_WORKER_MESSAGE_UPDATE_ASYNC;
> RedWorkerMessageUpdateAsync payload;
>
> - payload.base.cmd = async_command_alloc(qxl_state, message, cookie);
> + payload.base.cookie = cookie;
> payload.surface_id = surface_id;
> payload.qxl_area = *qxl_area;
> payload.clear_dirty_region = clear_dirty_region;
> @@ -266,7 +248,7 @@ static void red_qxl_add_memslot_async(QXLState
> *qxl_state, QXLDevMemSlot *mem_sl
> RedWorkerMessageAddMemslotAsync payload;
> RedWorkerMessage message = RED_WORKER_MESSAGE_ADD_MEMSLOT_ASYNC;
>
> - payload.base.cmd = async_command_alloc(qxl_state, message, cookie);
> + payload.base.cookie = cookie;
> payload.mem_slot = *mem_slot;
> dispatcher_send_message(qxl_state->dispatcher, message, &payload);
> }
> @@ -307,11 +289,11 @@ static void red_qxl_destroy_surfaces_async(QXLState
> *qxl_state, uint64_t cookie)
> RedWorkerMessageDestroySurfacesAsync payload;
> RedWorkerMessage message = RED_WORKER_MESSAGE_DESTROY_SURFACES_ASYNC;
>
> - payload.base.cmd = async_command_alloc(qxl_state, message, cookie);
> + payload.base.cookie = cookie;
> dispatcher_send_message(qxl_state->dispatcher, message, &payload);
> }
>
> -static void red_qxl_destroy_primary_surface_complete(QXLState *qxl_state)
> +void red_qxl_destroy_primary_surface_complete(QXLState *qxl_state)
> {
> qxl_state->x_res = 0;
> qxl_state->y_res = 0;
> @@ -340,7 +322,7 @@ red_qxl_destroy_primary_surface_async(QXLState
> *qxl_state,
> RedWorkerMessageDestroyPrimarySurfaceAsync payload;
> RedWorkerMessage message =
> RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE_ASYNC;
>
> - payload.base.cmd = async_command_alloc(qxl_state, message, cookie);
> + payload.base.cookie = cookie;
> payload.surface_id = surface_id;
> dispatcher_send_message(qxl_state->dispatcher, message, &payload);
> }
> @@ -362,7 +344,7 @@ static void qxl_worker_destroy_primary_surface(QXLWorker
> *qxl_worker, uint32_t s
> red_qxl_destroy_primary_surface(qxl_state, surface_id, 0, 0);
> }
>
> -static void red_qxl_create_primary_surface_complete(QXLState *qxl_state)
> +void red_qxl_create_primary_surface_complete(QXLState *qxl_state)
> {
> QXLDevSurfaceCreate *surface = &qxl_state->surface_create;
>
> @@ -383,7 +365,7 @@ red_qxl_create_primary_surface_async(QXLState *qxl_state,
> uint32_t surface_id,
> RedWorkerMessage message =
> RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE_ASYNC;
>
> qxl_state->surface_create = *surface;
> - payload.base.cmd = async_command_alloc(qxl_state, message, cookie);
> + payload.base.cookie = cookie;
> payload.surface_id = surface_id;
> payload.surface = *surface;
> dispatcher_send_message(qxl_state->dispatcher, message, &payload);
> @@ -470,7 +452,7 @@ static void red_qxl_destroy_surface_wait_async(QXLState
> *qxl_state,
> RedWorkerMessageDestroySurfaceWaitAsync payload;
> RedWorkerMessage message =
> RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT_ASYNC;
>
> - payload.base.cmd = async_command_alloc(qxl_state, message, cookie);
> + payload.base.cookie = cookie;
> payload.surface_id = surface_id;
> dispatcher_send_message(qxl_state->dispatcher, message, &payload);
> }
> @@ -574,7 +556,7 @@ static void red_qxl_flush_surfaces_async(QXLState
> *qxl_state, uint64_t cookie)
> RedWorkerMessageFlushSurfacesAsync payload;
> RedWorkerMessage message = RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC;
>
> - payload.base.cmd = async_command_alloc(qxl_state, message, cookie);
> + payload.base.cookie = cookie;
> dispatcher_send_message(qxl_state->dispatcher, message, &payload);
> }
>
> @@ -586,7 +568,7 @@ static void red_qxl_monitors_config_async(QXLState
> *qxl_state,
> RedWorkerMessageMonitorsConfigAsync payload;
> RedWorkerMessage message = RED_WORKER_MESSAGE_MONITORS_CONFIG_ASYNC;
>
> - payload.base.cmd = async_command_alloc(qxl_state, message, cookie);
> + payload.base.cookie = cookie;
> payload.monitors_config = monitors_config;
> payload.group_id = group_id;
> payload.max_monitors = qxl_state->max_monitors;
> @@ -891,32 +873,6 @@ void spice_qxl_gl_draw_async(QXLInstance *qxl,
> dispatcher_send_message(qxl_state->dispatcher, message, &draw);
> }
>
> -void red_qxl_async_complete(QXLInstance *qxl, AsyncCommand *async_command)
> -{
> - QXLInterface *interface = qxl_get_interface(qxl);
> -
> - spice_debug("%p: cookie %" PRId64, async_command,
> async_command->cookie);
> - switch (async_command->message) {
> - case RED_WORKER_MESSAGE_UPDATE_ASYNC:
> - case RED_WORKER_MESSAGE_ADD_MEMSLOT_ASYNC:
> - case RED_WORKER_MESSAGE_DESTROY_SURFACES_ASYNC:
> - case RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT_ASYNC:
> - case RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC:
> - case RED_WORKER_MESSAGE_MONITORS_CONFIG_ASYNC:
> - break;
> - case RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE_ASYNC:
> - red_qxl_create_primary_surface_complete(qxl->st);
> - break;
> - case RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE_ASYNC:
> - red_qxl_destroy_primary_surface_complete(qxl->st);
> - break;
> - default:
> - spice_warning("unexpected message %d", async_command->message);
> - }
> - interface->async_complete(qxl, async_command->cookie);
> - free(async_command);
> -}
> -
> void red_qxl_gl_draw_async_complete(QXLInstance *qxl)
> {
> QXLInterface *interface = qxl_get_interface(qxl);
> @@ -1151,3 +1107,10 @@ void red_qxl_set_client_capabilities(QXLInstance *qxl,
>
> interface->set_client_capabilities(qxl, client_present, caps);
> }
> +
> +void red_qxl_async_complete(QXLInstance *qxl, uint64_t cookie)
> +{
> + QXLInterface *interface = qxl_get_interface(qxl);
> +
> + interface->async_complete(qxl, cookie);
> +}
> diff --git a/server/red-qxl.h b/server/red-qxl.h
> index 5896113e1..51ec14562 100644
> --- a/server/red-qxl.h
> +++ b/server/red-qxl.h
> @@ -51,6 +51,7 @@ int red_qxl_get_cursor_command(QXLInstance *qxl, struct
> QXLCommandExt *cmd);
> int red_qxl_req_cursor_notification(QXLInstance *qxl);
> void red_qxl_notify_update(QXLInstance *qxl, uint32_t update_id);
> int red_qxl_flush_resources(QXLInstance *qxl);
> +void red_qxl_async_complete(QXLInstance *qxl, uint64_t cookie);
> void red_qxl_update_area_complete(QXLInstance *qxl, uint32_t surface_id,
> struct QXLRect *updated_rects,
> uint32_t num_updated_rects);
> diff --git a/server/red-worker.c b/server/red-worker.c
> index 58d9e0add..7238a66e8 100644
> --- a/server/red-worker.c
> +++ b/server/red-worker.c
> @@ -432,7 +432,7 @@ static void handle_dev_update_async(void *opaque, void
> *payload)
> red_qxl_update_area_complete(worker->qxl, msg->surface_id,
> qxl_dirty_rects, num_dirty_rects);
> free(qxl_dirty_rects);
> - red_qxl_async_complete(worker->qxl, msg->base.cmd);
> + red_qxl_async_complete(worker->qxl, msg->base.cookie);
> }
>
> static void handle_dev_update(void *opaque, void *payload)
> @@ -583,7 +583,8 @@ static void handle_dev_destroy_primary_surface_async(void
> *opaque, void *payload
> uint32_t surface_id = msg->surface_id;
>
> destroy_primary_surface(worker, surface_id);
> - red_qxl_async_complete(worker->qxl, msg->base.cmd);
> + red_qxl_destroy_primary_surface_complete(worker->qxl->st);
> + red_qxl_async_complete(worker->qxl, msg->base.cookie);
> }
>
> static void handle_dev_flush_surfaces_async(void *opaque, void *payload)
> @@ -593,7 +594,7 @@ static void handle_dev_flush_surfaces_async(void *opaque,
> void *payload)
>
> flush_all_qxl_commands(worker);
> display_channel_flush_all_surfaces(worker->display_channel);
> - red_qxl_async_complete(worker->qxl, msg->base.cmd);
> + red_qxl_async_complete(worker->qxl, msg->base.cookie);
> }
>
> static void handle_dev_stop(void *opaque, void *payload)
> @@ -693,7 +694,7 @@ static void handle_dev_destroy_surface_wait_async(void
> *opaque, void *payload)
> RedWorker *worker = opaque;
>
> display_channel_destroy_surface_wait(worker->display_channel,
> msg->surface_id);
> - red_qxl_async_complete(worker->qxl, msg->base.cmd);
> + red_qxl_async_complete(worker->qxl, msg->base.cookie);
> }
>
> static void handle_dev_destroy_surfaces_async(void *opaque, void *payload)
> @@ -704,7 +705,7 @@ static void handle_dev_destroy_surfaces_async(void
> *opaque, void *payload)
> flush_all_qxl_commands(worker);
> display_channel_destroy_surfaces(worker->display_channel);
> cursor_channel_reset(worker->cursor_channel);
> - red_qxl_async_complete(worker->qxl, msg->base.cmd);
> + red_qxl_async_complete(worker->qxl, msg->base.cookie);
> }
>
> static void handle_dev_create_primary_surface_async(void *opaque, void
> *payload)
> @@ -713,7 +714,8 @@ static void handle_dev_create_primary_surface_async(void
> *opaque, void *payload)
> RedWorker *worker = opaque;
>
> dev_create_primary_surface(worker, msg->surface_id, msg->surface);
> - red_qxl_async_complete(worker->qxl, msg->base.cmd);
> + red_qxl_create_primary_surface_complete(worker->qxl->st);
> + red_qxl_async_complete(worker->qxl, msg->base.cookie);
> }
>
> static void handle_dev_display_connect(void *opaque, void *payload)
> @@ -811,7 +813,7 @@ static void handle_dev_monitors_config_async(void
> *opaque, void *payload)
> MIN(count, msg->max_monitors),
> MIN(max_allowed,
> msg->max_monitors));
> async_complete:
> - red_qxl_async_complete(worker->qxl, msg->base.cmd);
> + red_qxl_async_complete(worker->qxl, msg->base.cookie);
> }
>
> /* TODO: special, perhaps use another dispatcher? */
> @@ -938,7 +940,7 @@ static void handle_dev_add_memslot_async(void *opaque,
> void *payload)
> RedWorker *worker = opaque;
>
> dev_add_memslot(worker, msg->mem_slot);
> - red_qxl_async_complete(worker->qxl, msg->base.cmd);
> + red_qxl_async_complete(worker->qxl, msg->base.cookie);
> }
>
> static void handle_dev_reset_memslots(void *opaque, void *payload)
> diff --git a/server/red-worker.h b/server/red-worker.h
> index 3d918575c..f29840c4e 100644
> --- a/server/red-worker.h
> +++ b/server/red-worker.h
> @@ -36,8 +36,9 @@ RedWorker* red_worker_new(QXLInstance *qxl,
> bool red_worker_run(RedWorker *worker);
> void red_worker_free(RedWorker *worker);
>
> -void red_qxl_async_complete(QXLInstance *qxl, AsyncCommand *async_command);
> struct Dispatcher *red_qxl_get_dispatcher(QXLInstance *qxl);
> +void red_qxl_destroy_primary_surface_complete(QXLState *qxl_state);
> +void red_qxl_create_primary_surface_complete(QXLState *qxl_state);
>
> typedef uint32_t RedWorkerMessage;
>
> @@ -137,7 +138,7 @@ typedef struct RedWorkerMessageUpdate {
> } RedWorkerMessageUpdate;
>
> typedef struct RedWorkerMessageAsync {
> - AsyncCommand *cmd;
> + uint64_t cookie;
> } RedWorkerMessageAsync;
>
> typedef struct RedWorkerMessageUpdateAsync {
More information about the Spice-devel
mailing list