From: Frediano Ziglio <fziglio@xxxxxxxxxx> This is a preparatory patch that states the running property in QXLState and provides accessor functions that allows us to check whether the QXL device is running from different threads. Signed-off-by: Jonathon Jongsma <jjongsma@xxxxxxxxxx> --- Alternate proposal for patch 7/10. I also rebased the rest of Frediano's branch that follows this commit, which can be found in the dispatcher_red_channel branch at https://gitlab.freedesktop.org/jjongsma/spice.git server/display-channel-private.h | 1 + server/red-qxl.c | 19 +++++++++++++++++++ server/red-qxl.h | 2 ++ server/red-worker.c | 23 +++++++++++------------ 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/server/display-channel-private.h b/server/display-channel-private.h index 58179531d..067c64188 100644 --- a/server/display-channel-private.h +++ b/server/display-channel-private.h @@ -89,6 +89,7 @@ struct DisplayChannelPrivate uint32_t renderer; int enable_jpeg; int enable_zlib_glz_wrap; + bool running; /* A ring of pending drawables for this DisplayChannel, regardless of which * surface they're associated with. This list is mainly used to flush older diff --git a/server/red-qxl.c b/server/red-qxl.c index 8274be567..152e9f068 100644 --- a/server/red-qxl.c +++ b/server/red-qxl.c @@ -59,6 +59,9 @@ struct QXLState { uint32_t device_display_ids[MAX_MONITORS_COUNT]; size_t monitors_count; // length of ^^^ + bool running; + pthread_mutex_t running_mutex; + pthread_mutex_t scanout_mutex; SpiceMsgDisplayGlScanoutUnix scanout; uint64_t gl_draw_cookie; @@ -66,6 +69,21 @@ struct QXLState { #define GL_DRAW_COOKIE_INVALID (~((uint64_t) 0)) +bool red_qxl_is_running(QXLInstance *qxl) { + bool running; + pthread_mutex_lock(&qxl->st->running_mutex); + running = qxl->st->running; + pthread_mutex_unlock(&qxl->st->running_mutex); + return running; +} + +void red_qxl_set_running(QXLInstance *qxl, bool running) { + pthread_mutex_lock(&qxl->st->running_mutex); + qxl->st->running = running; + pthread_mutex_unlock(&qxl->st->running_mutex); +} + + int red_qxl_check_qxl_version(QXLInstance *qxl, int major, int minor) { int qxl_major = qxl_get_interface(qxl)->base.major_version; @@ -825,6 +843,7 @@ void red_qxl_init(RedsState *reds, QXLInstance *qxl) qxl_state->reds = reds; qxl_state->qxl = qxl; pthread_mutex_init(&qxl_state->scanout_mutex, NULL); + pthread_mutex_init(&qxl_state->running_mutex, NULL); qxl_state->scanout.drm_dma_buf_fd = -1; qxl_state->gl_draw_cookie = GL_DRAW_COOKIE_INVALID; qxl_state->dispatcher = dispatcher_new(RED_WORKER_MESSAGE_COUNT); diff --git a/server/red-qxl.h b/server/red-qxl.h index 947539482..97d28d67c 100644 --- a/server/red-qxl.h +++ b/server/red-qxl.h @@ -60,5 +60,7 @@ void red_qxl_update_area_complete(QXLInstance *qxl, uint32_t surface_id, void red_qxl_set_client_capabilities(QXLInstance *qxl, uint8_t client_present, uint8_t caps[SPICE_CAPABILITIES_SIZE]); +void red_qxl_set_running(QXLInstance *qxl, bool running); +bool red_qxl_is_running(QXLInstance *qxl); #endif /* RED_QXL_H_ */ diff --git a/server/red-worker.c b/server/red-worker.c index 27fe04ccb..b80fefabe 100644 --- a/server/red-worker.c +++ b/server/red-worker.c @@ -63,7 +63,6 @@ struct RedWorker { pthread_t thread; QXLInstance *qxl; SpiceWatch *dispatch_watch; - int running; SpiceCoreInterfaceInternal core; unsigned int event_timeout; @@ -115,7 +114,7 @@ static int red_process_cursor(RedWorker *worker, int *ring_is_empty) QXLCommandExt ext_cmd; int n = 0; - if (!worker->running) { + if (!red_qxl_is_running(worker->qxl)) { *ring_is_empty = TRUE; return n; } @@ -173,7 +172,7 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty) int n = 0; uint64_t start = spice_get_monotonic_time_ns(); - if (!worker->running) { + if (!red_qxl_is_running(worker->qxl)) { *ring_is_empty = TRUE; return n; } @@ -378,7 +377,7 @@ static void guest_set_client_capabilities(RedWorker *worker) #define CLEAR_CAP(a,c) \ ((a)[(c) / 8] &= ~(1 << ((c) % 8))) - if (!worker->running) { + if (!red_qxl_is_running(worker->qxl)) { return; } if ((worker->display_channel == NULL) || @@ -406,7 +405,7 @@ static void handle_dev_update_async(void *opaque, void *payload) QXLRect *qxl_dirty_rects = NULL; uint32_t num_dirty_rects = 0; - spice_return_if_fail(worker->running); + spice_return_if_fail(red_qxl_is_running(worker->qxl)); spice_return_if_fail(qxl_get_interface(worker->qxl)->update_area_complete); flush_display_commands(worker); @@ -426,7 +425,7 @@ static void handle_dev_update(void *opaque, void *payload) RedWorkerMessageUpdate *msg = payload; QXLRect *qxl_dirty_rects = msg->qxl_dirty_rects; - spice_return_if_fail(worker->running); + spice_return_if_fail(red_qxl_is_running(worker->qxl)); flush_display_commands(worker); display_channel_update(worker->display_channel, @@ -586,9 +585,9 @@ static void handle_dev_stop(void *opaque, void *payload) RedWorker *worker = opaque; spice_debug("stop"); - spice_assert(worker->running); + spice_assert(red_qxl_is_running(worker->qxl)); - worker->running = FALSE; + red_qxl_set_running(worker->qxl, false); display_channel_free_glz_drawables(worker->display_channel); display_channel_flush_all_surfaces(worker->display_channel); @@ -606,7 +605,7 @@ static void handle_dev_start(void *opaque, void *payload) { RedWorker *worker = opaque; - spice_assert(!worker->running); + spice_assert(!red_qxl_is_running(worker->qxl)); if (worker->cursor_channel) { CommonGraphicsChannel *common = COMMON_GRAPHICS_CHANNEL(worker->cursor_channel); common_graphics_channel_set_during_target_migrate(common, FALSE); @@ -616,7 +615,7 @@ static void handle_dev_start(void *opaque, void *payload) common_graphics_channel_set_during_target_migrate(common, FALSE); display_channel_wait_for_migrate_data(worker->display_channel); } - worker->running = TRUE; + red_qxl_set_running(worker->qxl, true); worker->event_timeout = 0; guest_set_client_capabilities(worker); } @@ -637,7 +636,7 @@ static void handle_dev_oom(void *opaque, void *payload) RedChannel *display_red_channel = RED_CHANNEL(display); int ring_is_empty; - spice_return_if_fail(worker->running); + spice_return_if_fail(red_qxl_is_running(worker->qxl)); // streams? but without streams also leak display_channel_debug_oom(display, "OOM1"); while (red_process_display(worker, &ring_is_empty)) { @@ -1153,7 +1152,7 @@ static gboolean worker_source_check(GSource *source) RedWorkerSource *wsource = SPICE_CONTAINEROF(source, RedWorkerSource, source); RedWorker *worker = wsource->worker; - return worker->running /* TODO && worker->pending_process */; + return red_qxl_is_running(worker->qxl) /* TODO && worker->pending_process */; } static gboolean worker_source_dispatch(GSource *source, GSourceFunc callback, -- 2.17.2 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel