mirror of https://github.com/xemu-project/xemu.git
main-loop: Add an outer lock on QEMU main loop
Ensures monitor commands run from the UI thread are synchronous and not interfered with by things running on the QEMU main loop. e.g. savevm which gives up the iothread lock. There's likely a nicer way to do this, but for now this will do.
This commit is contained in:
parent
60d3dc8ae1
commit
7d2b038ef6
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue