Very quick patch to check Jonathon suggestion, quick tests seems to indicate that it works --- server/dispatcher.c | 11 ----------- server/dispatcher.h | 16 +--------------- server/red-worker.c | 52 +++++++++++++++++++++++++--------------------------- 3 files changed, 26 insertions(+), 53 deletions(-) diff --git a/server/dispatcher.c b/server/dispatcher.c index 4e03ea046..51e09b942 100644 --- a/server/dispatcher.c +++ b/server/dispatcher.c @@ -60,7 +60,6 @@ struct DispatcherPrivate { void *payload; /* allocated as max of message sizes */ size_t payload_size; /* used to track realloc calls */ void *opaque; - dispatcher_handle_async_done handle_async_done; dispatcher_handle_any_message any_handler; }; @@ -305,8 +304,6 @@ static int dispatcher_handle_single_read(Dispatcher *dispatcher) spice_printerr("error writing ack for message %d", type); /* TODO: close socketpair? */ } - } else if (msg->ack == DISPATCHER_ASYNC && dispatcher->priv->handle_async_done) { - dispatcher->priv->handle_async_done(dispatcher->priv->opaque, type, payload); } return 1; } @@ -355,14 +352,6 @@ unlock: pthread_mutex_unlock(&dispatcher->priv->lock); } -void dispatcher_register_async_done_callback( - Dispatcher *dispatcher, - dispatcher_handle_async_done handler) -{ - assert(dispatcher->priv->handle_async_done == NULL); - dispatcher->priv->handle_async_done = handler; -} - void dispatcher_register_handler(Dispatcher *dispatcher, uint32_t message_type, dispatcher_handle_message handler, size_t size, int ack) diff --git a/server/dispatcher.h b/server/dispatcher.h index 97b01de9c..bb3f3943f 100644 --- a/server/dispatcher.h +++ b/server/dispatcher.h @@ -75,7 +75,6 @@ void dispatcher_send_message(Dispatcher *dispatcher, uint32_t message_type, enum { DISPATCHER_NONE = 0, DISPATCHER_ACK, - DISPATCHER_ASYNC }; /* @@ -84,28 +83,15 @@ enum { * @messsage_type: message type * @handler: message handler * @size: message size. Each type has a fixed associated size. - * @ack: One of DISPATCHER_NONE, DISPATCHER_ACK, DISPATCHER_ASYNC. + * @ack: One of DISPATCHER_NONE, DISPATCHER_ACK. * DISPATCHER_NONE - only send the message * DISPATCHER_ACK - send an ack after the message - * DISPATCHER_ASYNC - call send an ack. This is per message type - you can't send the - * same message type with and without. Register two different - * messages if that is what you want. */ void dispatcher_register_handler(Dispatcher *dispatcher, uint32_t message_type, dispatcher_handle_message handler, size_t size, int ack); /* - * dispatcher_register_async_done_callback - * @dispatcher: dispatcher - * @handler: callback on the receiver side called *after* the - * message callback in case ack == DISPATCHER_ASYNC. - */ -void dispatcher_register_async_done_callback( - Dispatcher *dispatcher, - dispatcher_handle_async_done handler); - -/* * Hack to allow red_record to see the message being sent so it can record * it to file. */ diff --git a/server/red-worker.c b/server/red-worker.c index b18e05461..708a431d1 100644 --- a/server/red-worker.c +++ b/server/red-worker.c @@ -432,6 +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); } static void handle_dev_update(void *opaque, void *payload) @@ -582,14 +583,17 @@ 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); } static void handle_dev_flush_surfaces_async(void *opaque, void *payload) { RedWorker *worker = opaque; + RedWorkerMessageFlushSurfacesAsync *msg = (RedWorkerMessageFlushSurfacesAsync*) payload; flush_all_qxl_commands(worker); display_channel_flush_all_surfaces(worker->display_channel); + red_qxl_async_complete(worker->qxl, msg->base.cmd); } static void handle_dev_stop(void *opaque, void *payload) @@ -689,15 +693,19 @@ 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); } static void handle_dev_destroy_surfaces_async(void *opaque, void *payload) { RedWorker *worker = opaque; + RedWorkerMessageDestroySurfacesAsync *msg = (RedWorkerMessageDestroySurfacesAsync *) 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); } static void handle_dev_create_primary_surface_async(void *opaque, void *payload) @@ -706,6 +714,7 @@ 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); } static void handle_dev_display_connect(void *opaque, void *payload) @@ -774,21 +783,21 @@ static void handle_dev_monitors_config_async(void *opaque, void *payload) if (error) { /* TODO: raise guest bug (requires added QXL interface) */ - return; + goto reply; } worker->driver_cap_monitors_config = 1; count = dev_monitors_config->count; max_allowed = dev_monitors_config->max_allowed; if (count == 0) { spice_warning("ignoring an empty monitors config message from driver"); - return; + goto reply; } if (count > max_allowed) { spice_warning("ignoring malformed monitors_config from driver, " "count > max_allowed %d > %d", count, max_allowed); - return; + goto reply; } /* get pointer again to check virtual size */ dev_monitors_config = @@ -797,11 +806,14 @@ static void handle_dev_monitors_config_async(void *opaque, void *payload) msg->group_id, &error); if (error) { /* TODO: raise guest bug (requires added QXL interface) */ - return; + goto reply; } display_channel_update_monitors_config(worker->display_channel, dev_monitors_config, MIN(count, msg->max_monitors), MIN(max_allowed, msg->max_monitors)); + +reply: + red_qxl_async_complete(worker->qxl, msg->base.cmd); } /* TODO: special, perhaps use another dispatcher? */ @@ -928,6 +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); } static void handle_dev_reset_memslots(void *opaque, void *payload) @@ -1000,17 +1013,6 @@ static void handle_dev_loadvm_commands(void *opaque, void *payload) } } -static void worker_handle_dispatcher_async_done(void *opaque, - uint32_t message_type, - void *payload) -{ - RedWorker *worker = opaque; - RedWorkerMessageAsync *msg_async = payload; - - spice_debug("trace"); - red_qxl_async_complete(worker->qxl, msg_async->cmd); -} - static void worker_dispatcher_record(void *opaque, uint32_t message_type, void *payload) { RedWorker *worker = opaque; @@ -1020,10 +1022,6 @@ static void worker_dispatcher_record(void *opaque, uint32_t message_type, void * static void register_callbacks(Dispatcher *dispatcher) { - dispatcher_register_async_done_callback( - dispatcher, - worker_handle_dispatcher_async_done); - /* TODO: register cursor & display specific msg in respective channel files */ dispatcher_register_handler(dispatcher, RED_WORKER_MESSAGE_DISPLAY_CONNECT, @@ -1064,7 +1062,7 @@ static void register_callbacks(Dispatcher *dispatcher) RED_WORKER_MESSAGE_UPDATE_ASYNC, handle_dev_update_async, sizeof(RedWorkerMessageUpdateAsync), - DISPATCHER_ASYNC); + DISPATCHER_NONE); dispatcher_register_handler(dispatcher, RED_WORKER_MESSAGE_ADD_MEMSLOT, handle_dev_add_memslot, @@ -1074,7 +1072,7 @@ static void register_callbacks(Dispatcher *dispatcher) RED_WORKER_MESSAGE_ADD_MEMSLOT_ASYNC, handle_dev_add_memslot_async, sizeof(RedWorkerMessageAddMemslotAsync), - DISPATCHER_ASYNC); + DISPATCHER_NONE); dispatcher_register_handler(dispatcher, RED_WORKER_MESSAGE_DEL_MEMSLOT, handle_dev_del_memslot, @@ -1089,7 +1087,7 @@ static void register_callbacks(Dispatcher *dispatcher) RED_WORKER_MESSAGE_DESTROY_SURFACES_ASYNC, handle_dev_destroy_surfaces_async, sizeof(RedWorkerMessageDestroySurfacesAsync), - DISPATCHER_ASYNC); + DISPATCHER_NONE); dispatcher_register_handler(dispatcher, RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE, handle_dev_destroy_primary_surface, @@ -1099,12 +1097,12 @@ static void register_callbacks(Dispatcher *dispatcher) RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE_ASYNC, handle_dev_destroy_primary_surface_async, sizeof(RedWorkerMessageDestroyPrimarySurfaceAsync), - DISPATCHER_ASYNC); + DISPATCHER_NONE); dispatcher_register_handler(dispatcher, RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE_ASYNC, handle_dev_create_primary_surface_async, sizeof(RedWorkerMessageCreatePrimarySurfaceAsync), - DISPATCHER_ASYNC); + DISPATCHER_NONE); dispatcher_register_handler(dispatcher, RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE, handle_dev_create_primary_surface, @@ -1139,7 +1137,7 @@ static void register_callbacks(Dispatcher *dispatcher) RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC, handle_dev_flush_surfaces_async, sizeof(RedWorkerMessageFlushSurfacesAsync), - DISPATCHER_ASYNC); + DISPATCHER_NONE); dispatcher_register_handler(dispatcher, RED_WORKER_MESSAGE_STOP, handle_dev_stop, @@ -1179,7 +1177,7 @@ static void register_callbacks(Dispatcher *dispatcher) RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT_ASYNC, handle_dev_destroy_surface_wait_async, sizeof(RedWorkerMessageDestroySurfaceWaitAsync), - DISPATCHER_ASYNC); + DISPATCHER_NONE); dispatcher_register_handler(dispatcher, RED_WORKER_MESSAGE_RESET_MEMSLOTS, handle_dev_reset_memslots, @@ -1189,7 +1187,7 @@ static void register_callbacks(Dispatcher *dispatcher) RED_WORKER_MESSAGE_MONITORS_CONFIG_ASYNC, handle_dev_monitors_config_async, sizeof(RedWorkerMessageMonitorsConfigAsync), - DISPATCHER_ASYNC); + DISPATCHER_NONE); dispatcher_register_handler(dispatcher, RED_WORKER_MESSAGE_DRIVER_UNLOAD, handle_dev_driver_unload, -- 2.13.5 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel