diff options
author | Corentin Chary <corentin.chary@gmail.com> | 2012-03-14 07:58:47 +0100 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2012-03-14 16:22:46 -0500 |
commit | 175b2a6e4be06422da59d3a82c28d9a0e738e282 (patch) | |
tree | 109f343f1e5207c3c6a2fc4c339465f4a1e81dc6 /ui/vnc.c | |
parent | 418ba9e5d6849ef2e8512d8853628ce4bf37937a (diff) | |
download | qemu-175b2a6e4be06422da59d3a82c28d9a0e738e282.zip qemu-175b2a6e4be06422da59d3a82c28d9a0e738e282.tar.gz qemu-175b2a6e4be06422da59d3a82c28d9a0e738e282.tar.bz2 |
vnc: don't mess up with iohandlers in the vnc thread
The threaded VNC servers messed up with QEMU fd handlers without
any kind of locking, and that can cause some nasty race conditions.
Using qemu_mutex_lock_iothread() won't work because vnc_dpy_cpy(),
which will wait for the current job queue to finish, can be called with
the iothread lock held.
Instead, we now store the data in a temporary buffer, and use a bottom
half to notify the main thread that new data is available.
vnc_[un]lock_ouput() is still needed to access VncState members like
abort, csock or jobs_buffer.
Signed-off-by: Corentin Chary <corentin.chary@gmail.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'ui/vnc.c')
-rw-r--r-- | ui/vnc.c | 12 |
1 files changed, 12 insertions, 0 deletions
@@ -1068,7 +1068,10 @@ static void vnc_disconnect_finish(VncState *vs) #ifdef CONFIG_VNC_THREAD qemu_mutex_destroy(&vs->output_mutex); + qemu_bh_delete(vs->bh); + buffer_free(&vs->jobs_buffer); #endif + for (i = 0; i < VNC_STAT_ROWS; ++i) { g_free(vs->lossy_rect[i]); } @@ -1283,6 +1286,14 @@ static long vnc_client_read_plain(VncState *vs) return ret; } +#ifdef CONFIG_VNC_THREAD +static void vnc_jobs_bh(void *opaque) +{ + VncState *vs = opaque; + + vnc_jobs_consume_buffer(vs); +} +#endif /* * First function called whenever there is more data to be read from @@ -2687,6 +2698,7 @@ static void vnc_connect(VncDisplay *vd, int csock, int skipauth) #ifdef CONFIG_VNC_THREAD qemu_mutex_init(&vs->output_mutex); + vs->bh = qemu_bh_new(vnc_jobs_bh, vs); #endif QTAILQ_INSERT_HEAD(&vd->clients, vs, next); |