diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h index a6d20b0719..4c29dedd97 100644 --- a/include/qemu/main-loop.h +++ b/include/qemu/main-loop.h @@ -325,4 +325,10 @@ typedef struct MainLoopPoll { void main_loop_poll_add_notifier(Notifier *notify); void main_loop_poll_remove_notifier(Notifier *notify); +#ifdef XBOX +void qemu_init_main_loop_lock(void); +void qemu_mutex_lock_main_loop(void); +void qemu_mutex_unlock_main_loop(void); +#endif + #endif diff --git a/softmmu/vl.c b/softmmu/vl.c index 0d1eb7d5e0..63da28ebd4 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -2993,6 +2993,10 @@ void qemu_init(int argc, char **argv, char **envp) qemu_init_cpu_list(); qemu_init_cpu_loop(); +#ifdef XBOX + qemu_init_main_loop_lock(); + qemu_mutex_lock_main_loop(); +#endif qemu_mutex_lock_iothread(); atexit(qemu_run_exit_notifiers); diff --git a/ui/xemu.c b/ui/xemu.c index 709a7e04d1..73a0ead944 100644 --- a/ui/xemu.c +++ b/ui/xemu.c @@ -1085,9 +1085,11 @@ static void xemu_sdl2_gl_render_surface(struct sdl2_console *scon) glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, NULL); // FIXME: Finer locking + qemu_mutex_lock_main_loop(); qemu_mutex_lock_iothread(); xemu_hud_render(); qemu_mutex_unlock_iothread(); + qemu_mutex_unlock_main_loop(); // xb_surface_gl_render_texture(scon->surface); pre_swap(); @@ -1172,6 +1174,7 @@ void sdl2_gl_refresh(DisplayChangeListener *dcl) SDL_GL_MakeCurrent(scon->real_window, scon->winctx); + qemu_mutex_lock_main_loop(); qemu_mutex_lock_iothread(); graphic_hw_update(dcl->con); @@ -1180,6 +1183,7 @@ void sdl2_gl_refresh(DisplayChangeListener *dcl) } sdl2_poll_events(scon); qemu_mutex_unlock_iothread(); + qemu_mutex_unlock_main_loop(); xemu_sdl2_gl_render_surface(scon); } diff --git a/util/main-loop.c b/util/main-loop.c index 9d7ad8dd4c..bf5e590bd3 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -48,6 +48,12 @@ */ GMainContext *qemu_main_context = NULL; GMainLoop *qemu_main_loop_obj = NULL; + +/* *Another* main loop lock. Used for ensuring the main loop does not get a + * chance to continue when some action is being handled on the UI interaction + * thread that gives up the BQL but expects the main loop to not be running. + */ +QemuMutex qemu_main_loop_lock; #endif #ifndef _WIN32 @@ -160,6 +166,23 @@ void qemu_notify_event(void) static GArray *gpollfds; +#ifdef XBOX +void qemu_init_main_loop_lock(void) +{ + qemu_mutex_init(&qemu_main_loop_lock); +} + +void qemu_mutex_lock_main_loop(void) +{ + qemu_mutex_lock(&qemu_main_loop_lock); +} + +void qemu_mutex_unlock_main_loop(void) +{ + qemu_mutex_unlock(&qemu_main_loop_lock); +} +#endif + int qemu_init_main_loop(Error **errp) { int ret; @@ -277,7 +300,13 @@ static int os_host_main_loop_wait(int64_t timeout) qemu_mutex_unlock_iothread(); replay_mutex_unlock(); +#ifdef XBOX + qemu_mutex_unlock_main_loop(); +#endif ret = qemu_poll_ns((GPollFD *)gpollfds->data, gpollfds->len, timeout); +#ifdef XBOX + qemu_mutex_lock_main_loop(); +#endif replay_mutex_lock(); qemu_mutex_lock_iothread(); @@ -494,7 +523,13 @@ static int os_host_main_loop_wait(int64_t timeout) replay_mutex_unlock(); +#ifdef XBOX + qemu_mutex_unlock_main_loop(); +#endif g_poll_ret = qemu_poll_ns(poll_fds, n_poll_fds + w->num, poll_timeout_ns); +#ifdef XBOX + qemu_mutex_lock_main_loop(); +#endif replay_mutex_lock();