diff mbox

Remove support for non-threaded VNC server

Message ID 1340198668-21307-1-git-send-email-berrange@redhat.com
State New
Headers show

Commit Message

Daniel P. Berrangé June 20, 2012, 1:24 p.m. UTC
From: "Daniel P. Berrange" <berrange@redhat.com>

QEMU now has a fundamental requirement for pthreads, so there
is no compelling reason to retain support for the non-threaded
VNC server. Remove the --{enable,disable}-vnc-thread configure
arguments, and all CONFIG_VNC_THREAD conditionals

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 configure           |    9 --
 ui/Makefile.objs    |    6 +-
 ui/vnc-jobs-async.c |  351 ---------------------------------------------------
 ui/vnc-jobs-sync.c  |   73 -----------
 ui/vnc-jobs.c       |  351 +++++++++++++++++++++++++++++++++++++++++++++++++++
 ui/vnc-jobs.h       |   16 ---
 ui/vnc.c            |   21 ---
 ui/vnc.h            |   17 ---
 8 files changed, 352 insertions(+), 492 deletions(-)
 delete mode 100644 ui/vnc-jobs-async.c
 delete mode 100644 ui/vnc-jobs-sync.c
 create mode 100644 ui/vnc-jobs.c

Comments

Michael Tokarev June 21, 2012, 9:57 a.m. UTC | #1
20.06.2012 16:24, Daniel P. Berrange wrote:
>   delete mode 100644 ui/vnc-jobs-async.c
>   delete mode 100644 ui/vnc-jobs-sync.c
>   create mode 100644 ui/vnc-jobs.c

Is there a reason to rename vnc-jobs-foo.c to vnc-jobs.c ?
I'd leave it alone at this stage, omiting just the rename...

/mjt
Daniel P. Berrangé June 21, 2012, 9:59 a.m. UTC | #2
On Thu, Jun 21, 2012 at 12:57:44PM +0300, Michael Tokarev wrote:
> 20.06.2012 16:24, Daniel P. Berrange wrote:
> >  delete mode 100644 ui/vnc-jobs-async.c
> >  delete mode 100644 ui/vnc-jobs-sync.c
> >  create mode 100644 ui/vnc-jobs.c
> 
> Is there a reason to rename vnc-jobs-foo.c to vnc-jobs.c ?

The corresponding header file is vnc-jobs.h, and since we only
have one impl of it now, using the same name is normal practice.

> I'd leave it alone at this stage, omiting just the rename...

I disagree, GIT handles renames like this fine, so there's no
reason not to do this.

Daniel
Gerd Hoffmann June 21, 2012, 10:23 a.m. UTC | #3
On 06/21/12 11:59, Daniel P. Berrange wrote:
> On Thu, Jun 21, 2012 at 12:57:44PM +0300, Michael Tokarev wrote:
>> 20.06.2012 16:24, Daniel P. Berrange wrote:
>>>  delete mode 100644 ui/vnc-jobs-async.c
>>>  delete mode 100644 ui/vnc-jobs-sync.c
>>>  create mode 100644 ui/vnc-jobs.c
>>
>> Is there a reason to rename vnc-jobs-foo.c to vnc-jobs.c ?
> 
> The corresponding header file is vnc-jobs.h, and since we only
> have one impl of it now, using the same name is normal practice.
> 
>> I'd leave it alone at this stage, omiting just the rename...
> 
> I disagree, GIT handles renames like this fine, so there's no
> reason not to do this.

/me suggests "git format-patch -M" so the patch shows the rename.

cheers,
  Gerd
Anthony Liguori June 27, 2012, 9:32 p.m. UTC | #4
On 06/20/2012 08:24 AM, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange"<berrange@redhat.com>
>
> QEMU now has a fundamental requirement for pthreads, so there
> is no compelling reason to retain support for the non-threaded
> VNC server. Remove the --{enable,disable}-vnc-thread configure
> arguments, and all CONFIG_VNC_THREAD conditionals
>
> Signed-off-by: Daniel P. Berrange<berrange@redhat.com>

Applied.  Thanks.

Regards,

Anthony Liguori

> ---
>   configure           |    9 --
>   ui/Makefile.objs    |    6 +-
>   ui/vnc-jobs-async.c |  351 ---------------------------------------------------
>   ui/vnc-jobs-sync.c  |   73 -----------
>   ui/vnc-jobs.c       |  351 +++++++++++++++++++++++++++++++++++++++++++++++++++
>   ui/vnc-jobs.h       |   16 ---
>   ui/vnc.c            |   21 ---
>   ui/vnc.h            |   17 ---
>   8 files changed, 352 insertions(+), 492 deletions(-)
>   delete mode 100644 ui/vnc-jobs-async.c
>   delete mode 100644 ui/vnc-jobs-sync.c
>   create mode 100644 ui/vnc-jobs.c
>
> diff --git a/configure b/configure
> index b68c0ca..4767532 100755
> --- a/configure
> +++ b/configure
> @@ -134,7 +134,6 @@ vnc_tls=""
>   vnc_sasl=""
>   vnc_jpeg=""
>   vnc_png=""
> -vnc_thread="no"
>   xen=""
>   xen_ctrl_version=""
>   linux_aio=""
> @@ -666,10 +665,6 @@ for opt do
>     ;;
>     --enable-vnc-png) vnc_png="yes"
>     ;;
> -  --disable-vnc-thread) vnc_thread="no"
> -  ;;
> -  --enable-vnc-thread) vnc_thread="yes"
> -  ;;
>     --disable-slirp) slirp="no"
>     ;;
>     --disable-uuid) uuid="no"
> @@ -2998,7 +2993,6 @@ if test "$vnc" = "yes" ; then
>       echo "VNC SASL support  $vnc_sasl"
>       echo "VNC JPEG support  $vnc_jpeg"
>       echo "VNC PNG support   $vnc_png"
> -    echo "VNC thread        $vnc_thread"
>   fi
>   if test -n "$sparc_cpu"; then
>       echo "Target Sparc Arch $sparc_cpu"
> @@ -3174,9 +3168,6 @@ if test "$vnc_png" = "yes" ; then
>     echo "CONFIG_VNC_PNG=y">>  $config_host_mak
>     echo "VNC_PNG_CFLAGS=$vnc_png_cflags">>  $config_host_mak
>   fi
> -if test "$vnc_thread" = "yes" ; then
> -  echo "CONFIG_VNC_THREAD=y">>  $config_host_mak
> -fi
>   if test "$fnmatch" = "yes" ; then
>     echo "CONFIG_FNMATCH=y">>  $config_host_mak
>   fi
> diff --git a/ui/Makefile.objs b/ui/Makefile.objs
> index 3687c8a..adc07be 100644
> --- a/ui/Makefile.objs
> +++ b/ui/Makefile.objs
> @@ -4,11 +4,7 @@ vnc-obj-y += vnc-enc-tight.o vnc-palette.o
>   vnc-obj-y += vnc-enc-zrle.o
>   vnc-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o
>   vnc-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o
> -ifdef CONFIG_VNC_THREAD
> -vnc-obj-y += vnc-jobs-async.o
> -else
> -vnc-obj-y += vnc-jobs-sync.o
> -endif
> +vnc-obj-y += vnc-jobs.o
>
>   common-obj-y += keymaps.o
>   common-obj-$(CONFIG_SPICE) += spice-core.o spice-input.o spice-display.o
> diff --git a/ui/vnc-jobs-async.c b/ui/vnc-jobs-async.c
> deleted file mode 100644
> index 087b84d..0000000
> --- a/ui/vnc-jobs-async.c
> +++ /dev/null
> @@ -1,351 +0,0 @@
> -/*
> - * QEMU VNC display driver
> - *
> - * Copyright (C) 2006 Anthony Liguori<anthony@codemonkey.ws>
> - * Copyright (C) 2006 Fabrice Bellard
> - * Copyright (C) 2009 Red Hat, Inc
> - * Copyright (C) 2010 Corentin Chary<corentin.chary@gmail.com>
> - *
> - * Permission is hereby granted, free of charge, to any person obtaining a copy
> - * of this software and associated documentation files (the "Software"), to deal
> - * in the Software without restriction, including without limitation the rights
> - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> - * copies of the Software, and to permit persons to whom the Software is
> - * furnished to do so, subject to the following conditions:
> - *
> - * The above copyright notice and this permission notice shall be included in
> - * all copies or substantial portions of the Software.
> - *
> - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> - * THE SOFTWARE.
> - */
> -
> -
> -#include "vnc.h"
> -#include "vnc-jobs.h"
> -#include "qemu_socket.h"
> -
> -/*
> - * Locking:
> - *
> - * There is three levels of locking:
> - * - jobs queue lock: for each operation on the queue (push, pop, isEmpty?)
> - * - VncDisplay global lock: mainly used for framebuffer updates to avoid
> - *                      screen corruption if the framebuffer is updated
> - *			while the worker is doing something.
> - * - VncState::output lock: used to make sure the output buffer is not corrupted
> - * 		   	 if two threads try to write on it at the same time
> - *
> - * While the VNC worker thread is working, the VncDisplay global lock is hold
> - * to avoid screen corruptions (this does not block vnc_refresh() because it
> - * uses trylock()) but the output lock is not hold because the thread work on
> - * its own output buffer.
> - * When the encoding job is done, the worker thread will hold the output lock
> - * and copy its output buffer in vs->output.
> -*/
> -
> -struct VncJobQueue {
> -    QemuCond cond;
> -    QemuMutex mutex;
> -    QemuThread thread;
> -    Buffer buffer;
> -    bool exit;
> -    QTAILQ_HEAD(, VncJob) jobs;
> -};
> -
> -typedef struct VncJobQueue VncJobQueue;
> -
> -/*
> - * We use a single global queue, but most of the functions are
> - * already reetrant, so we can easilly add more than one encoding thread
> - */
> -static VncJobQueue *queue;
> -
> -static void vnc_lock_queue(VncJobQueue *queue)
> -{
> -    qemu_mutex_lock(&queue->mutex);
> -}
> -
> -static void vnc_unlock_queue(VncJobQueue *queue)
> -{
> -    qemu_mutex_unlock(&queue->mutex);
> -}
> -
> -VncJob *vnc_job_new(VncState *vs)
> -{
> -    VncJob *job = g_malloc0(sizeof(VncJob));
> -
> -    job->vs = vs;
> -    vnc_lock_queue(queue);
> -    QLIST_INIT(&job->rectangles);
> -    vnc_unlock_queue(queue);
> -    return job;
> -}
> -
> -int vnc_job_add_rect(VncJob *job, int x, int y, int w, int h)
> -{
> -    VncRectEntry *entry = g_malloc0(sizeof(VncRectEntry));
> -
> -    entry->rect.x = x;
> -    entry->rect.y = y;
> -    entry->rect.w = w;
> -    entry->rect.h = h;
> -
> -    vnc_lock_queue(queue);
> -    QLIST_INSERT_HEAD(&job->rectangles, entry, next);
> -    vnc_unlock_queue(queue);
> -    return 1;
> -}
> -
> -void vnc_job_push(VncJob *job)
> -{
> -    vnc_lock_queue(queue);
> -    if (queue->exit || QLIST_EMPTY(&job->rectangles)) {
> -        g_free(job);
> -    } else {
> -        QTAILQ_INSERT_TAIL(&queue->jobs, job, next);
> -        qemu_cond_broadcast(&queue->cond);
> -    }
> -    vnc_unlock_queue(queue);
> -}
> -
> -static bool vnc_has_job_locked(VncState *vs)
> -{
> -    VncJob *job;
> -
> -    QTAILQ_FOREACH(job,&queue->jobs, next) {
> -        if (job->vs == vs || !vs) {
> -            return true;
> -        }
> -    }
> -    return false;
> -}
> -
> -bool vnc_has_job(VncState *vs)
> -{
> -    bool ret;
> -
> -    vnc_lock_queue(queue);
> -    ret = vnc_has_job_locked(vs);
> -    vnc_unlock_queue(queue);
> -    return ret;
> -}
> -
> -void vnc_jobs_clear(VncState *vs)
> -{
> -    VncJob *job, *tmp;
> -
> -    vnc_lock_queue(queue);
> -    QTAILQ_FOREACH_SAFE(job,&queue->jobs, next, tmp) {
> -        if (job->vs == vs || !vs) {
> -            QTAILQ_REMOVE(&queue->jobs, job, next);
> -        }
> -    }
> -    vnc_unlock_queue(queue);
> -}
> -
> -void vnc_jobs_join(VncState *vs)
> -{
> -    vnc_lock_queue(queue);
> -    while (vnc_has_job_locked(vs)) {
> -        qemu_cond_wait(&queue->cond,&queue->mutex);
> -    }
> -    vnc_unlock_queue(queue);
> -    vnc_jobs_consume_buffer(vs);
> -}
> -
> -void vnc_jobs_consume_buffer(VncState *vs)
> -{
> -    bool flush;
> -
> -    vnc_lock_output(vs);
> -    if (vs->jobs_buffer.offset) {
> -        vnc_write(vs, vs->jobs_buffer.buffer, vs->jobs_buffer.offset);
> -        buffer_reset(&vs->jobs_buffer);
> -    }
> -    flush = vs->csock != -1&&  vs->abort != true;
> -    vnc_unlock_output(vs);
> -
> -    if (flush) {
> -      vnc_flush(vs);
> -    }
> -}
> -
> -/*
> - * Copy data for local use
> - */
> -static void vnc_async_encoding_start(VncState *orig, VncState *local)
> -{
> -    local->vnc_encoding = orig->vnc_encoding;
> -    local->features = orig->features;
> -    local->ds = orig->ds;
> -    local->vd = orig->vd;
> -    local->lossy_rect = orig->lossy_rect;
> -    local->write_pixels = orig->write_pixels;
> -    local->clientds = orig->clientds;
> -    local->tight = orig->tight;
> -    local->zlib = orig->zlib;
> -    local->hextile = orig->hextile;
> -    local->zrle = orig->zrle;
> -    local->output =  queue->buffer;
> -    local->csock = -1; /* Don't do any network work on this thread */
> -
> -    buffer_reset(&local->output);
> -}
> -
> -static void vnc_async_encoding_end(VncState *orig, VncState *local)
> -{
> -    orig->tight = local->tight;
> -    orig->zlib = local->zlib;
> -    orig->hextile = local->hextile;
> -    orig->zrle = local->zrle;
> -    orig->lossy_rect = local->lossy_rect;
> -
> -    queue->buffer = local->output;
> -}
> -
> -static int vnc_worker_thread_loop(VncJobQueue *queue)
> -{
> -    VncJob *job;
> -    VncRectEntry *entry, *tmp;
> -    VncState vs;
> -    int n_rectangles;
> -    int saved_offset;
> -
> -    vnc_lock_queue(queue);
> -    while (QTAILQ_EMPTY(&queue->jobs)&&  !queue->exit) {
> -        qemu_cond_wait(&queue->cond,&queue->mutex);
> -    }
> -    /* Here job can only be NULL if queue->exit is true */
> -    job = QTAILQ_FIRST(&queue->jobs);
> -    vnc_unlock_queue(queue);
> -
> -    if (queue->exit) {
> -        return -1;
> -    }
> -
> -    vnc_lock_output(job->vs);
> -    if (job->vs->csock == -1 || job->vs->abort == true) {
> -        vnc_unlock_output(job->vs);
> -        goto disconnected;
> -    }
> -    vnc_unlock_output(job->vs);
> -
> -    /* Make a local copy of vs and switch output buffers */
> -    vnc_async_encoding_start(job->vs,&vs);
> -
> -    /* Start sending rectangles */
> -    n_rectangles = 0;
> -    vnc_write_u8(&vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
> -    vnc_write_u8(&vs, 0);
> -    saved_offset = vs.output.offset;
> -    vnc_write_u16(&vs, 0);
> -
> -    vnc_lock_display(job->vs->vd);
> -    QLIST_FOREACH_SAFE(entry,&job->rectangles, next, tmp) {
> -        int n;
> -
> -        if (job->vs->csock == -1) {
> -            vnc_unlock_display(job->vs->vd);
> -            goto disconnected;
> -        }
> -
> -        n = vnc_send_framebuffer_update(&vs, entry->rect.x, entry->rect.y,
> -                                        entry->rect.w, entry->rect.h);
> -
> -        if (n>= 0) {
> -            n_rectangles += n;
> -        }
> -        g_free(entry);
> -    }
> -    vnc_unlock_display(job->vs->vd);
> -
> -    /* Put n_rectangles at the beginning of the message */
> -    vs.output.buffer[saved_offset] = (n_rectangles>>  8)&  0xFF;
> -    vs.output.buffer[saved_offset + 1] = n_rectangles&  0xFF;
> -
> -    vnc_lock_output(job->vs);
> -    if (job->vs->csock != -1) {
> -        buffer_reserve(&job->vs->jobs_buffer, vs.output.offset);
> -        buffer_append(&job->vs->jobs_buffer, vs.output.buffer,
> -                      vs.output.offset);
> -        /* Copy persistent encoding data */
> -        vnc_async_encoding_end(job->vs,&vs);
> -
> -	qemu_bh_schedule(job->vs->bh);
> -    }
> -    vnc_unlock_output(job->vs);
> -
> -disconnected:
> -    vnc_lock_queue(queue);
> -    QTAILQ_REMOVE(&queue->jobs, job, next);
> -    vnc_unlock_queue(queue);
> -    qemu_cond_broadcast(&queue->cond);
> -    g_free(job);
> -    return 0;
> -}
> -
> -static VncJobQueue *vnc_queue_init(void)
> -{
> -    VncJobQueue *queue = g_malloc0(sizeof(VncJobQueue));
> -
> -    qemu_cond_init(&queue->cond);
> -    qemu_mutex_init(&queue->mutex);
> -    QTAILQ_INIT(&queue->jobs);
> -    return queue;
> -}
> -
> -static void vnc_queue_clear(VncJobQueue *q)
> -{
> -    qemu_cond_destroy(&queue->cond);
> -    qemu_mutex_destroy(&queue->mutex);
> -    buffer_free(&queue->buffer);
> -    g_free(q);
> -    queue = NULL; /* Unset global queue */
> -}
> -
> -static void *vnc_worker_thread(void *arg)
> -{
> -    VncJobQueue *queue = arg;
> -
> -    qemu_thread_get_self(&queue->thread);
> -
> -    while (!vnc_worker_thread_loop(queue)) ;
> -    vnc_queue_clear(queue);
> -    return NULL;
> -}
> -
> -void vnc_start_worker_thread(void)
> -{
> -    VncJobQueue *q;
> -
> -    if (vnc_worker_thread_running())
> -        return ;
> -
> -    q = vnc_queue_init();
> -    qemu_thread_create(&q->thread, vnc_worker_thread, q, QEMU_THREAD_DETACHED);
> -    queue = q; /* Set global queue */
> -}
> -
> -bool vnc_worker_thread_running(void)
> -{
> -    return queue; /* Check global queue */
> -}
> -
> -void vnc_stop_worker_thread(void)
> -{
> -    if (!vnc_worker_thread_running())
> -        return ;
> -
> -    /* Remove all jobs and wake up the thread */
> -    vnc_lock_queue(queue);
> -    queue->exit = true;
> -    vnc_unlock_queue(queue);
> -    vnc_jobs_clear(NULL);
> -    qemu_cond_broadcast(&queue->cond);
> -}
> diff --git a/ui/vnc-jobs-sync.c b/ui/vnc-jobs-sync.c
> deleted file mode 100644
> index 49b77af..0000000
> --- a/ui/vnc-jobs-sync.c
> +++ /dev/null
> @@ -1,73 +0,0 @@
> -/*
> - * QEMU VNC display driver
> - *
> - * Copyright (C) 2006 Anthony Liguori<anthony@codemonkey.ws>
> - * Copyright (C) 2006 Fabrice Bellard
> - * Copyright (C) 2009 Red Hat, Inc
> - * Copyright (C) 2010 Corentin Chary<corentin.chary@gmail.com>
> - *
> - * Permission is hereby granted, free of charge, to any person obtaining a copy
> - * of this software and associated documentation files (the "Software"), to deal
> - * in the Software without restriction, including without limitation the rights
> - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> - * copies of the Software, and to permit persons to whom the Software is
> - * furnished to do so, subject to the following conditions:
> - *
> - * The above copyright notice and this permission notice shall be included in
> - * all copies or substantial portions of the Software.
> - *
> - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> - * THE SOFTWARE.
> - */
> -
> -#include "vnc.h"
> -#include "vnc-jobs.h"
> -
> -void vnc_jobs_clear(VncState *vs)
> -{
> -}
> -
> -void vnc_jobs_join(VncState *vs)
> -{
> -}
> -
> -VncJob *vnc_job_new(VncState *vs)
> -{
> -    vs->job.vs = vs;
> -    vs->job.rectangles = 0;
> -
> -    vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
> -    vnc_write_u8(vs, 0);
> -    vs->job.saved_offset = vs->output.offset;
> -    vnc_write_u16(vs, 0);
> -    return&vs->job;
> -}
> -
> -void vnc_job_push(VncJob *job)
> -{
> -    VncState *vs = job->vs;
> -
> -    vs->output.buffer[job->saved_offset] = (job->rectangles>>  8)&  0xFF;
> -    vs->output.buffer[job->saved_offset + 1] = job->rectangles&  0xFF;
> -    vnc_flush(job->vs);
> -}
> -
> -int vnc_job_add_rect(VncJob *job, int x, int y, int w, int h)
> -{
> -    int n;
> -
> -    n = vnc_send_framebuffer_update(job->vs, x, y, w, h);
> -    if (n>= 0)
> -        job->rectangles += n;
> -    return n;
> -}
> -
> -bool vnc_has_job(VncState *vs)
> -{
> -    return false;
> -}
> diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c
> new file mode 100644
> index 0000000..087b84d
> --- /dev/null
> +++ b/ui/vnc-jobs.c
> @@ -0,0 +1,351 @@
> +/*
> + * QEMU VNC display driver
> + *
> + * Copyright (C) 2006 Anthony Liguori<anthony@codemonkey.ws>
> + * Copyright (C) 2006 Fabrice Bellard
> + * Copyright (C) 2009 Red Hat, Inc
> + * Copyright (C) 2010 Corentin Chary<corentin.chary@gmail.com>
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to deal
> + * in the Software without restriction, including without limitation the rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +
> +#include "vnc.h"
> +#include "vnc-jobs.h"
> +#include "qemu_socket.h"
> +
> +/*
> + * Locking:
> + *
> + * There is three levels of locking:
> + * - jobs queue lock: for each operation on the queue (push, pop, isEmpty?)
> + * - VncDisplay global lock: mainly used for framebuffer updates to avoid
> + *                      screen corruption if the framebuffer is updated
> + *			while the worker is doing something.
> + * - VncState::output lock: used to make sure the output buffer is not corrupted
> + * 		   	 if two threads try to write on it at the same time
> + *
> + * While the VNC worker thread is working, the VncDisplay global lock is hold
> + * to avoid screen corruptions (this does not block vnc_refresh() because it
> + * uses trylock()) but the output lock is not hold because the thread work on
> + * its own output buffer.
> + * When the encoding job is done, the worker thread will hold the output lock
> + * and copy its output buffer in vs->output.
> +*/
> +
> +struct VncJobQueue {
> +    QemuCond cond;
> +    QemuMutex mutex;
> +    QemuThread thread;
> +    Buffer buffer;
> +    bool exit;
> +    QTAILQ_HEAD(, VncJob) jobs;
> +};
> +
> +typedef struct VncJobQueue VncJobQueue;
> +
> +/*
> + * We use a single global queue, but most of the functions are
> + * already reetrant, so we can easilly add more than one encoding thread
> + */
> +static VncJobQueue *queue;
> +
> +static void vnc_lock_queue(VncJobQueue *queue)
> +{
> +    qemu_mutex_lock(&queue->mutex);
> +}
> +
> +static void vnc_unlock_queue(VncJobQueue *queue)
> +{
> +    qemu_mutex_unlock(&queue->mutex);
> +}
> +
> +VncJob *vnc_job_new(VncState *vs)
> +{
> +    VncJob *job = g_malloc0(sizeof(VncJob));
> +
> +    job->vs = vs;
> +    vnc_lock_queue(queue);
> +    QLIST_INIT(&job->rectangles);
> +    vnc_unlock_queue(queue);
> +    return job;
> +}
> +
> +int vnc_job_add_rect(VncJob *job, int x, int y, int w, int h)
> +{
> +    VncRectEntry *entry = g_malloc0(sizeof(VncRectEntry));
> +
> +    entry->rect.x = x;
> +    entry->rect.y = y;
> +    entry->rect.w = w;
> +    entry->rect.h = h;
> +
> +    vnc_lock_queue(queue);
> +    QLIST_INSERT_HEAD(&job->rectangles, entry, next);
> +    vnc_unlock_queue(queue);
> +    return 1;
> +}
> +
> +void vnc_job_push(VncJob *job)
> +{
> +    vnc_lock_queue(queue);
> +    if (queue->exit || QLIST_EMPTY(&job->rectangles)) {
> +        g_free(job);
> +    } else {
> +        QTAILQ_INSERT_TAIL(&queue->jobs, job, next);
> +        qemu_cond_broadcast(&queue->cond);
> +    }
> +    vnc_unlock_queue(queue);
> +}
> +
> +static bool vnc_has_job_locked(VncState *vs)
> +{
> +    VncJob *job;
> +
> +    QTAILQ_FOREACH(job,&queue->jobs, next) {
> +        if (job->vs == vs || !vs) {
> +            return true;
> +        }
> +    }
> +    return false;
> +}
> +
> +bool vnc_has_job(VncState *vs)
> +{
> +    bool ret;
> +
> +    vnc_lock_queue(queue);
> +    ret = vnc_has_job_locked(vs);
> +    vnc_unlock_queue(queue);
> +    return ret;
> +}
> +
> +void vnc_jobs_clear(VncState *vs)
> +{
> +    VncJob *job, *tmp;
> +
> +    vnc_lock_queue(queue);
> +    QTAILQ_FOREACH_SAFE(job,&queue->jobs, next, tmp) {
> +        if (job->vs == vs || !vs) {
> +            QTAILQ_REMOVE(&queue->jobs, job, next);
> +        }
> +    }
> +    vnc_unlock_queue(queue);
> +}
> +
> +void vnc_jobs_join(VncState *vs)
> +{
> +    vnc_lock_queue(queue);
> +    while (vnc_has_job_locked(vs)) {
> +        qemu_cond_wait(&queue->cond,&queue->mutex);
> +    }
> +    vnc_unlock_queue(queue);
> +    vnc_jobs_consume_buffer(vs);
> +}
> +
> +void vnc_jobs_consume_buffer(VncState *vs)
> +{
> +    bool flush;
> +
> +    vnc_lock_output(vs);
> +    if (vs->jobs_buffer.offset) {
> +        vnc_write(vs, vs->jobs_buffer.buffer, vs->jobs_buffer.offset);
> +        buffer_reset(&vs->jobs_buffer);
> +    }
> +    flush = vs->csock != -1&&  vs->abort != true;
> +    vnc_unlock_output(vs);
> +
> +    if (flush) {
> +      vnc_flush(vs);
> +    }
> +}
> +
> +/*
> + * Copy data for local use
> + */
> +static void vnc_async_encoding_start(VncState *orig, VncState *local)
> +{
> +    local->vnc_encoding = orig->vnc_encoding;
> +    local->features = orig->features;
> +    local->ds = orig->ds;
> +    local->vd = orig->vd;
> +    local->lossy_rect = orig->lossy_rect;
> +    local->write_pixels = orig->write_pixels;
> +    local->clientds = orig->clientds;
> +    local->tight = orig->tight;
> +    local->zlib = orig->zlib;
> +    local->hextile = orig->hextile;
> +    local->zrle = orig->zrle;
> +    local->output =  queue->buffer;
> +    local->csock = -1; /* Don't do any network work on this thread */
> +
> +    buffer_reset(&local->output);
> +}
> +
> +static void vnc_async_encoding_end(VncState *orig, VncState *local)
> +{
> +    orig->tight = local->tight;
> +    orig->zlib = local->zlib;
> +    orig->hextile = local->hextile;
> +    orig->zrle = local->zrle;
> +    orig->lossy_rect = local->lossy_rect;
> +
> +    queue->buffer = local->output;
> +}
> +
> +static int vnc_worker_thread_loop(VncJobQueue *queue)
> +{
> +    VncJob *job;
> +    VncRectEntry *entry, *tmp;
> +    VncState vs;
> +    int n_rectangles;
> +    int saved_offset;
> +
> +    vnc_lock_queue(queue);
> +    while (QTAILQ_EMPTY(&queue->jobs)&&  !queue->exit) {
> +        qemu_cond_wait(&queue->cond,&queue->mutex);
> +    }
> +    /* Here job can only be NULL if queue->exit is true */
> +    job = QTAILQ_FIRST(&queue->jobs);
> +    vnc_unlock_queue(queue);
> +
> +    if (queue->exit) {
> +        return -1;
> +    }
> +
> +    vnc_lock_output(job->vs);
> +    if (job->vs->csock == -1 || job->vs->abort == true) {
> +        vnc_unlock_output(job->vs);
> +        goto disconnected;
> +    }
> +    vnc_unlock_output(job->vs);
> +
> +    /* Make a local copy of vs and switch output buffers */
> +    vnc_async_encoding_start(job->vs,&vs);
> +
> +    /* Start sending rectangles */
> +    n_rectangles = 0;
> +    vnc_write_u8(&vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
> +    vnc_write_u8(&vs, 0);
> +    saved_offset = vs.output.offset;
> +    vnc_write_u16(&vs, 0);
> +
> +    vnc_lock_display(job->vs->vd);
> +    QLIST_FOREACH_SAFE(entry,&job->rectangles, next, tmp) {
> +        int n;
> +
> +        if (job->vs->csock == -1) {
> +            vnc_unlock_display(job->vs->vd);
> +            goto disconnected;
> +        }
> +
> +        n = vnc_send_framebuffer_update(&vs, entry->rect.x, entry->rect.y,
> +                                        entry->rect.w, entry->rect.h);
> +
> +        if (n>= 0) {
> +            n_rectangles += n;
> +        }
> +        g_free(entry);
> +    }
> +    vnc_unlock_display(job->vs->vd);
> +
> +    /* Put n_rectangles at the beginning of the message */
> +    vs.output.buffer[saved_offset] = (n_rectangles>>  8)&  0xFF;
> +    vs.output.buffer[saved_offset + 1] = n_rectangles&  0xFF;
> +
> +    vnc_lock_output(job->vs);
> +    if (job->vs->csock != -1) {
> +        buffer_reserve(&job->vs->jobs_buffer, vs.output.offset);
> +        buffer_append(&job->vs->jobs_buffer, vs.output.buffer,
> +                      vs.output.offset);
> +        /* Copy persistent encoding data */
> +        vnc_async_encoding_end(job->vs,&vs);
> +
> +	qemu_bh_schedule(job->vs->bh);
> +    }
> +    vnc_unlock_output(job->vs);
> +
> +disconnected:
> +    vnc_lock_queue(queue);
> +    QTAILQ_REMOVE(&queue->jobs, job, next);
> +    vnc_unlock_queue(queue);
> +    qemu_cond_broadcast(&queue->cond);
> +    g_free(job);
> +    return 0;
> +}
> +
> +static VncJobQueue *vnc_queue_init(void)
> +{
> +    VncJobQueue *queue = g_malloc0(sizeof(VncJobQueue));
> +
> +    qemu_cond_init(&queue->cond);
> +    qemu_mutex_init(&queue->mutex);
> +    QTAILQ_INIT(&queue->jobs);
> +    return queue;
> +}
> +
> +static void vnc_queue_clear(VncJobQueue *q)
> +{
> +    qemu_cond_destroy(&queue->cond);
> +    qemu_mutex_destroy(&queue->mutex);
> +    buffer_free(&queue->buffer);
> +    g_free(q);
> +    queue = NULL; /* Unset global queue */
> +}
> +
> +static void *vnc_worker_thread(void *arg)
> +{
> +    VncJobQueue *queue = arg;
> +
> +    qemu_thread_get_self(&queue->thread);
> +
> +    while (!vnc_worker_thread_loop(queue)) ;
> +    vnc_queue_clear(queue);
> +    return NULL;
> +}
> +
> +void vnc_start_worker_thread(void)
> +{
> +    VncJobQueue *q;
> +
> +    if (vnc_worker_thread_running())
> +        return ;
> +
> +    q = vnc_queue_init();
> +    qemu_thread_create(&q->thread, vnc_worker_thread, q, QEMU_THREAD_DETACHED);
> +    queue = q; /* Set global queue */
> +}
> +
> +bool vnc_worker_thread_running(void)
> +{
> +    return queue; /* Check global queue */
> +}
> +
> +void vnc_stop_worker_thread(void)
> +{
> +    if (!vnc_worker_thread_running())
> +        return ;
> +
> +    /* Remove all jobs and wake up the thread */
> +    vnc_lock_queue(queue);
> +    queue->exit = true;
> +    vnc_unlock_queue(queue);
> +    vnc_jobs_clear(NULL);
> +    qemu_cond_broadcast(&queue->cond);
> +}
> diff --git a/ui/vnc-jobs.h b/ui/vnc-jobs.h
> index 4c661f9..86e6d88 100644
> --- a/ui/vnc-jobs.h
> +++ b/ui/vnc-jobs.h
> @@ -38,51 +38,35 @@ bool vnc_has_job(VncState *vs);
>   void vnc_jobs_clear(VncState *vs);
>   void vnc_jobs_join(VncState *vs);
>
> -#ifdef CONFIG_VNC_THREAD
> -
>   void vnc_jobs_consume_buffer(VncState *vs);
>   void vnc_start_worker_thread(void);
>   bool vnc_worker_thread_running(void);
>   void vnc_stop_worker_thread(void);
>
> -#endif /* CONFIG_VNC_THREAD */
> -
>   /* Locks */
>   static inline int vnc_trylock_display(VncDisplay *vd)
>   {
> -#ifdef CONFIG_VNC_THREAD
>       return qemu_mutex_trylock(&vd->mutex);
> -#else
> -    return 0;
> -#endif
>   }
>
>   static inline void vnc_lock_display(VncDisplay *vd)
>   {
> -#ifdef CONFIG_VNC_THREAD
>       qemu_mutex_lock(&vd->mutex);
> -#endif
>   }
>
>   static inline void vnc_unlock_display(VncDisplay *vd)
>   {
> -#ifdef CONFIG_VNC_THREAD
>       qemu_mutex_unlock(&vd->mutex);
> -#endif
>   }
>
>   static inline void vnc_lock_output(VncState *vs)
>   {
> -#ifdef CONFIG_VNC_THREAD
>       qemu_mutex_lock(&vs->output_mutex);
> -#endif
>   }
>
>   static inline void vnc_unlock_output(VncState *vs)
>   {
> -#ifdef CONFIG_VNC_THREAD
>       qemu_mutex_unlock(&vs->output_mutex);
> -#endif
>   }
>
>   #endif /* VNC_JOBS_H */
> diff --git a/ui/vnc.c b/ui/vnc.c
> index 54bc5ad..cf1cae2 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -526,7 +526,6 @@ static void vnc_desktop_resize(VncState *vs)
>       vnc_flush(vs);
>   }
>
> -#ifdef CONFIG_VNC_THREAD
>   static void vnc_abort_display_jobs(VncDisplay *vd)
>   {
>       VncState *vs;
> @@ -545,11 +544,6 @@ static void vnc_abort_display_jobs(VncDisplay *vd)
>           vnc_unlock_output(vs);
>       }
>   }
> -#else
> -static void vnc_abort_display_jobs(VncDisplay *vd)
> -{
> -}
> -#endif
>
>   static void vnc_dpy_resize(DisplayState *ds)
>   {
> @@ -867,19 +861,12 @@ static int find_and_clear_dirty_height(struct VncState *vs,
>       return h;
>   }
>
> -#ifdef CONFIG_VNC_THREAD
>   static int vnc_update_client_sync(VncState *vs, int has_dirty)
>   {
>       int ret = vnc_update_client(vs, has_dirty);
>       vnc_jobs_join(vs);
>       return ret;
>   }
> -#else
> -static int vnc_update_client_sync(VncState *vs, int has_dirty)
> -{
> -    return vnc_update_client(vs, has_dirty);
> -}
> -#endif
>
>   static int vnc_update_client(VncState *vs, int has_dirty)
>   {
> @@ -1066,11 +1053,9 @@ static void vnc_disconnect_finish(VncState *vs)
>           qemu_remove_led_event_handler(vs->led);
>       vnc_unlock_output(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]);
> @@ -1286,14 +1271,12 @@ 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
> @@ -2699,10 +2682,8 @@ static void vnc_connect(VncDisplay *vd, int csock, int skipauth)
>       vs->as.fmt = AUD_FMT_S16;
>       vs->as.endianness = 0;
>
> -#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);
>
> @@ -2762,10 +2743,8 @@ void vnc_display_init(DisplayState *ds)
>       if (!vs->kbd_layout)
>           exit(1);
>
> -#ifdef CONFIG_VNC_THREAD
>       qemu_mutex_init(&vs->mutex);
>       vnc_start_worker_thread();
> -#endif
>
>       dcl->dpy_copy = vnc_dpy_copy;
>       dcl->dpy_update = vnc_dpy_update;
> diff --git a/ui/vnc.h b/ui/vnc.h
> index a851ebd..068c2fc 100644
> --- a/ui/vnc.h
> +++ b/ui/vnc.h
> @@ -29,9 +29,7 @@
>
>   #include "qemu-common.h"
>   #include "qemu-queue.h"
> -#ifdef CONFIG_VNC_THREAD
>   #include "qemu-thread.h"
> -#endif
>   #include "console.h"
>   #include "monitor.h"
>   #include "audio/audio.h"
> @@ -146,9 +144,7 @@ struct VncDisplay
>       DisplayState *ds;
>       kbd_layout_t *kbd_layout;
>       int lock_key_sync;
> -#ifdef CONFIG_VNC_THREAD
>       QemuMutex mutex;
> -#endif
>
>       QEMUCursor *cursor;
>       int cursor_msize;
> @@ -216,7 +212,6 @@ typedef struct VncZywrle {
>       int buf[VNC_ZRLE_TILE_WIDTH * VNC_ZRLE_TILE_HEIGHT];
>   } VncZywrle;
>
> -#ifdef CONFIG_VNC_THREAD
>   struct VncRect
>   {
>       int x;
> @@ -238,14 +233,6 @@ struct VncJob
>       QLIST_HEAD(, VncRectEntry) rectangles;
>       QTAILQ_ENTRY(VncJob) next;
>   };
> -#else
> -struct VncJob
> -{
> -    VncState *vs;
> -    int rectangles;
> -    size_t saved_offset;
> -};
> -#endif
>
>   struct VncState
>   {
> @@ -300,13 +287,9 @@ struct VncState
>       QEMUPutLEDEntry *led;
>
>       bool abort;
> -#ifndef CONFIG_VNC_THREAD
> -    VncJob job;
> -#else
>       QemuMutex output_mutex;
>       QEMUBH *bh;
>       Buffer jobs_buffer;
> -#endif
>
>       /* Encoding specific, if you add something here, don't forget to
>        *  update vnc_async_encoding_start()
diff mbox

Patch

diff --git a/configure b/configure
index b68c0ca..4767532 100755
--- a/configure
+++ b/configure
@@ -134,7 +134,6 @@  vnc_tls=""
 vnc_sasl=""
 vnc_jpeg=""
 vnc_png=""
-vnc_thread="no"
 xen=""
 xen_ctrl_version=""
 linux_aio=""
@@ -666,10 +665,6 @@  for opt do
   ;;
   --enable-vnc-png) vnc_png="yes"
   ;;
-  --disable-vnc-thread) vnc_thread="no"
-  ;;
-  --enable-vnc-thread) vnc_thread="yes"
-  ;;
   --disable-slirp) slirp="no"
   ;;
   --disable-uuid) uuid="no"
@@ -2998,7 +2993,6 @@  if test "$vnc" = "yes" ; then
     echo "VNC SASL support  $vnc_sasl"
     echo "VNC JPEG support  $vnc_jpeg"
     echo "VNC PNG support   $vnc_png"
-    echo "VNC thread        $vnc_thread"
 fi
 if test -n "$sparc_cpu"; then
     echo "Target Sparc Arch $sparc_cpu"
@@ -3174,9 +3168,6 @@  if test "$vnc_png" = "yes" ; then
   echo "CONFIG_VNC_PNG=y" >> $config_host_mak
   echo "VNC_PNG_CFLAGS=$vnc_png_cflags" >> $config_host_mak
 fi
-if test "$vnc_thread" = "yes" ; then
-  echo "CONFIG_VNC_THREAD=y" >> $config_host_mak
-fi
 if test "$fnmatch" = "yes" ; then
   echo "CONFIG_FNMATCH=y" >> $config_host_mak
 fi
diff --git a/ui/Makefile.objs b/ui/Makefile.objs
index 3687c8a..adc07be 100644
--- a/ui/Makefile.objs
+++ b/ui/Makefile.objs
@@ -4,11 +4,7 @@  vnc-obj-y += vnc-enc-tight.o vnc-palette.o
 vnc-obj-y += vnc-enc-zrle.o
 vnc-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o
 vnc-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o
-ifdef CONFIG_VNC_THREAD
-vnc-obj-y += vnc-jobs-async.o
-else
-vnc-obj-y += vnc-jobs-sync.o
-endif
+vnc-obj-y += vnc-jobs.o
 
 common-obj-y += keymaps.o
 common-obj-$(CONFIG_SPICE) += spice-core.o spice-input.o spice-display.o
diff --git a/ui/vnc-jobs-async.c b/ui/vnc-jobs-async.c
deleted file mode 100644
index 087b84d..0000000
--- a/ui/vnc-jobs-async.c
+++ /dev/null
@@ -1,351 +0,0 @@ 
-/*
- * QEMU VNC display driver
- *
- * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
- * Copyright (C) 2006 Fabrice Bellard
- * Copyright (C) 2009 Red Hat, Inc
- * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-
-#include "vnc.h"
-#include "vnc-jobs.h"
-#include "qemu_socket.h"
-
-/*
- * Locking:
- *
- * There is three levels of locking:
- * - jobs queue lock: for each operation on the queue (push, pop, isEmpty?)
- * - VncDisplay global lock: mainly used for framebuffer updates to avoid
- *                      screen corruption if the framebuffer is updated
- *			while the worker is doing something.
- * - VncState::output lock: used to make sure the output buffer is not corrupted
- * 		   	 if two threads try to write on it at the same time
- *
- * While the VNC worker thread is working, the VncDisplay global lock is hold
- * to avoid screen corruptions (this does not block vnc_refresh() because it
- * uses trylock()) but the output lock is not hold because the thread work on
- * its own output buffer.
- * When the encoding job is done, the worker thread will hold the output lock
- * and copy its output buffer in vs->output.
-*/
-
-struct VncJobQueue {
-    QemuCond cond;
-    QemuMutex mutex;
-    QemuThread thread;
-    Buffer buffer;
-    bool exit;
-    QTAILQ_HEAD(, VncJob) jobs;
-};
-
-typedef struct VncJobQueue VncJobQueue;
-
-/*
- * We use a single global queue, but most of the functions are
- * already reetrant, so we can easilly add more than one encoding thread
- */
-static VncJobQueue *queue;
-
-static void vnc_lock_queue(VncJobQueue *queue)
-{
-    qemu_mutex_lock(&queue->mutex);
-}
-
-static void vnc_unlock_queue(VncJobQueue *queue)
-{
-    qemu_mutex_unlock(&queue->mutex);
-}
-
-VncJob *vnc_job_new(VncState *vs)
-{
-    VncJob *job = g_malloc0(sizeof(VncJob));
-
-    job->vs = vs;
-    vnc_lock_queue(queue);
-    QLIST_INIT(&job->rectangles);
-    vnc_unlock_queue(queue);
-    return job;
-}
-
-int vnc_job_add_rect(VncJob *job, int x, int y, int w, int h)
-{
-    VncRectEntry *entry = g_malloc0(sizeof(VncRectEntry));
-
-    entry->rect.x = x;
-    entry->rect.y = y;
-    entry->rect.w = w;
-    entry->rect.h = h;
-
-    vnc_lock_queue(queue);
-    QLIST_INSERT_HEAD(&job->rectangles, entry, next);
-    vnc_unlock_queue(queue);
-    return 1;
-}
-
-void vnc_job_push(VncJob *job)
-{
-    vnc_lock_queue(queue);
-    if (queue->exit || QLIST_EMPTY(&job->rectangles)) {
-        g_free(job);
-    } else {
-        QTAILQ_INSERT_TAIL(&queue->jobs, job, next);
-        qemu_cond_broadcast(&queue->cond);
-    }
-    vnc_unlock_queue(queue);
-}
-
-static bool vnc_has_job_locked(VncState *vs)
-{
-    VncJob *job;
-
-    QTAILQ_FOREACH(job, &queue->jobs, next) {
-        if (job->vs == vs || !vs) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool vnc_has_job(VncState *vs)
-{
-    bool ret;
-
-    vnc_lock_queue(queue);
-    ret = vnc_has_job_locked(vs);
-    vnc_unlock_queue(queue);
-    return ret;
-}
-
-void vnc_jobs_clear(VncState *vs)
-{
-    VncJob *job, *tmp;
-
-    vnc_lock_queue(queue);
-    QTAILQ_FOREACH_SAFE(job, &queue->jobs, next, tmp) {
-        if (job->vs == vs || !vs) {
-            QTAILQ_REMOVE(&queue->jobs, job, next);
-        }
-    }
-    vnc_unlock_queue(queue);
-}
-
-void vnc_jobs_join(VncState *vs)
-{
-    vnc_lock_queue(queue);
-    while (vnc_has_job_locked(vs)) {
-        qemu_cond_wait(&queue->cond, &queue->mutex);
-    }
-    vnc_unlock_queue(queue);
-    vnc_jobs_consume_buffer(vs);
-}
-
-void vnc_jobs_consume_buffer(VncState *vs)
-{
-    bool flush;
-
-    vnc_lock_output(vs);
-    if (vs->jobs_buffer.offset) {
-        vnc_write(vs, vs->jobs_buffer.buffer, vs->jobs_buffer.offset);
-        buffer_reset(&vs->jobs_buffer);
-    }
-    flush = vs->csock != -1 && vs->abort != true;
-    vnc_unlock_output(vs);
-
-    if (flush) {
-      vnc_flush(vs);
-    }
-}
-
-/*
- * Copy data for local use
- */
-static void vnc_async_encoding_start(VncState *orig, VncState *local)
-{
-    local->vnc_encoding = orig->vnc_encoding;
-    local->features = orig->features;
-    local->ds = orig->ds;
-    local->vd = orig->vd;
-    local->lossy_rect = orig->lossy_rect;
-    local->write_pixels = orig->write_pixels;
-    local->clientds = orig->clientds;
-    local->tight = orig->tight;
-    local->zlib = orig->zlib;
-    local->hextile = orig->hextile;
-    local->zrle = orig->zrle;
-    local->output =  queue->buffer;
-    local->csock = -1; /* Don't do any network work on this thread */
-
-    buffer_reset(&local->output);
-}
-
-static void vnc_async_encoding_end(VncState *orig, VncState *local)
-{
-    orig->tight = local->tight;
-    orig->zlib = local->zlib;
-    orig->hextile = local->hextile;
-    orig->zrle = local->zrle;
-    orig->lossy_rect = local->lossy_rect;
-
-    queue->buffer = local->output;
-}
-
-static int vnc_worker_thread_loop(VncJobQueue *queue)
-{
-    VncJob *job;
-    VncRectEntry *entry, *tmp;
-    VncState vs;
-    int n_rectangles;
-    int saved_offset;
-
-    vnc_lock_queue(queue);
-    while (QTAILQ_EMPTY(&queue->jobs) && !queue->exit) {
-        qemu_cond_wait(&queue->cond, &queue->mutex);
-    }
-    /* Here job can only be NULL if queue->exit is true */
-    job = QTAILQ_FIRST(&queue->jobs);
-    vnc_unlock_queue(queue);
-
-    if (queue->exit) {
-        return -1;
-    }
-
-    vnc_lock_output(job->vs);
-    if (job->vs->csock == -1 || job->vs->abort == true) {
-        vnc_unlock_output(job->vs);
-        goto disconnected;
-    }
-    vnc_unlock_output(job->vs);
-
-    /* Make a local copy of vs and switch output buffers */
-    vnc_async_encoding_start(job->vs, &vs);
-
-    /* Start sending rectangles */
-    n_rectangles = 0;
-    vnc_write_u8(&vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
-    vnc_write_u8(&vs, 0);
-    saved_offset = vs.output.offset;
-    vnc_write_u16(&vs, 0);
-
-    vnc_lock_display(job->vs->vd);
-    QLIST_FOREACH_SAFE(entry, &job->rectangles, next, tmp) {
-        int n;
-
-        if (job->vs->csock == -1) {
-            vnc_unlock_display(job->vs->vd);
-            goto disconnected;
-        }
-
-        n = vnc_send_framebuffer_update(&vs, entry->rect.x, entry->rect.y,
-                                        entry->rect.w, entry->rect.h);
-
-        if (n >= 0) {
-            n_rectangles += n;
-        }
-        g_free(entry);
-    }
-    vnc_unlock_display(job->vs->vd);
-
-    /* Put n_rectangles at the beginning of the message */
-    vs.output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
-    vs.output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
-
-    vnc_lock_output(job->vs);
-    if (job->vs->csock != -1) {
-        buffer_reserve(&job->vs->jobs_buffer, vs.output.offset);
-        buffer_append(&job->vs->jobs_buffer, vs.output.buffer,
-                      vs.output.offset);
-        /* Copy persistent encoding data */
-        vnc_async_encoding_end(job->vs, &vs);
-
-	qemu_bh_schedule(job->vs->bh);
-    }
-    vnc_unlock_output(job->vs);
-
-disconnected:
-    vnc_lock_queue(queue);
-    QTAILQ_REMOVE(&queue->jobs, job, next);
-    vnc_unlock_queue(queue);
-    qemu_cond_broadcast(&queue->cond);
-    g_free(job);
-    return 0;
-}
-
-static VncJobQueue *vnc_queue_init(void)
-{
-    VncJobQueue *queue = g_malloc0(sizeof(VncJobQueue));
-
-    qemu_cond_init(&queue->cond);
-    qemu_mutex_init(&queue->mutex);
-    QTAILQ_INIT(&queue->jobs);
-    return queue;
-}
-
-static void vnc_queue_clear(VncJobQueue *q)
-{
-    qemu_cond_destroy(&queue->cond);
-    qemu_mutex_destroy(&queue->mutex);
-    buffer_free(&queue->buffer);
-    g_free(q);
-    queue = NULL; /* Unset global queue */
-}
-
-static void *vnc_worker_thread(void *arg)
-{
-    VncJobQueue *queue = arg;
-
-    qemu_thread_get_self(&queue->thread);
-
-    while (!vnc_worker_thread_loop(queue)) ;
-    vnc_queue_clear(queue);
-    return NULL;
-}
-
-void vnc_start_worker_thread(void)
-{
-    VncJobQueue *q;
-
-    if (vnc_worker_thread_running())
-        return ;
-
-    q = vnc_queue_init();
-    qemu_thread_create(&q->thread, vnc_worker_thread, q, QEMU_THREAD_DETACHED);
-    queue = q; /* Set global queue */
-}
-
-bool vnc_worker_thread_running(void)
-{
-    return queue; /* Check global queue */
-}
-
-void vnc_stop_worker_thread(void)
-{
-    if (!vnc_worker_thread_running())
-        return ;
-
-    /* Remove all jobs and wake up the thread */
-    vnc_lock_queue(queue);
-    queue->exit = true;
-    vnc_unlock_queue(queue);
-    vnc_jobs_clear(NULL);
-    qemu_cond_broadcast(&queue->cond);
-}
diff --git a/ui/vnc-jobs-sync.c b/ui/vnc-jobs-sync.c
deleted file mode 100644
index 49b77af..0000000
--- a/ui/vnc-jobs-sync.c
+++ /dev/null
@@ -1,73 +0,0 @@ 
-/*
- * QEMU VNC display driver
- *
- * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
- * Copyright (C) 2006 Fabrice Bellard
- * Copyright (C) 2009 Red Hat, Inc
- * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vnc.h"
-#include "vnc-jobs.h"
-
-void vnc_jobs_clear(VncState *vs)
-{
-}
-
-void vnc_jobs_join(VncState *vs)
-{
-}
-
-VncJob *vnc_job_new(VncState *vs)
-{
-    vs->job.vs = vs;
-    vs->job.rectangles = 0;
-
-    vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
-    vnc_write_u8(vs, 0);
-    vs->job.saved_offset = vs->output.offset;
-    vnc_write_u16(vs, 0);
-    return &vs->job;
-}
-
-void vnc_job_push(VncJob *job)
-{
-    VncState *vs = job->vs;
-
-    vs->output.buffer[job->saved_offset] = (job->rectangles >> 8) & 0xFF;
-    vs->output.buffer[job->saved_offset + 1] = job->rectangles & 0xFF;
-    vnc_flush(job->vs);
-}
-
-int vnc_job_add_rect(VncJob *job, int x, int y, int w, int h)
-{
-    int n;
-
-    n = vnc_send_framebuffer_update(job->vs, x, y, w, h);
-    if (n >= 0)
-        job->rectangles += n;
-    return n;
-}
-
-bool vnc_has_job(VncState *vs)
-{
-    return false;
-}
diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c
new file mode 100644
index 0000000..087b84d
--- /dev/null
+++ b/ui/vnc-jobs.c
@@ -0,0 +1,351 @@ 
+/*
+ * QEMU VNC display driver
+ *
+ * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
+ * Copyright (C) 2006 Fabrice Bellard
+ * Copyright (C) 2009 Red Hat, Inc
+ * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+#include "vnc.h"
+#include "vnc-jobs.h"
+#include "qemu_socket.h"
+
+/*
+ * Locking:
+ *
+ * There is three levels of locking:
+ * - jobs queue lock: for each operation on the queue (push, pop, isEmpty?)
+ * - VncDisplay global lock: mainly used for framebuffer updates to avoid
+ *                      screen corruption if the framebuffer is updated
+ *			while the worker is doing something.
+ * - VncState::output lock: used to make sure the output buffer is not corrupted
+ * 		   	 if two threads try to write on it at the same time
+ *
+ * While the VNC worker thread is working, the VncDisplay global lock is hold
+ * to avoid screen corruptions (this does not block vnc_refresh() because it
+ * uses trylock()) but the output lock is not hold because the thread work on
+ * its own output buffer.
+ * When the encoding job is done, the worker thread will hold the output lock
+ * and copy its output buffer in vs->output.
+*/
+
+struct VncJobQueue {
+    QemuCond cond;
+    QemuMutex mutex;
+    QemuThread thread;
+    Buffer buffer;
+    bool exit;
+    QTAILQ_HEAD(, VncJob) jobs;
+};
+
+typedef struct VncJobQueue VncJobQueue;
+
+/*
+ * We use a single global queue, but most of the functions are
+ * already reetrant, so we can easilly add more than one encoding thread
+ */
+static VncJobQueue *queue;
+
+static void vnc_lock_queue(VncJobQueue *queue)
+{
+    qemu_mutex_lock(&queue->mutex);
+}
+
+static void vnc_unlock_queue(VncJobQueue *queue)
+{
+    qemu_mutex_unlock(&queue->mutex);
+}
+
+VncJob *vnc_job_new(VncState *vs)
+{
+    VncJob *job = g_malloc0(sizeof(VncJob));
+
+    job->vs = vs;
+    vnc_lock_queue(queue);
+    QLIST_INIT(&job->rectangles);
+    vnc_unlock_queue(queue);
+    return job;
+}
+
+int vnc_job_add_rect(VncJob *job, int x, int y, int w, int h)
+{
+    VncRectEntry *entry = g_malloc0(sizeof(VncRectEntry));
+
+    entry->rect.x = x;
+    entry->rect.y = y;
+    entry->rect.w = w;
+    entry->rect.h = h;
+
+    vnc_lock_queue(queue);
+    QLIST_INSERT_HEAD(&job->rectangles, entry, next);
+    vnc_unlock_queue(queue);
+    return 1;
+}
+
+void vnc_job_push(VncJob *job)
+{
+    vnc_lock_queue(queue);
+    if (queue->exit || QLIST_EMPTY(&job->rectangles)) {
+        g_free(job);
+    } else {
+        QTAILQ_INSERT_TAIL(&queue->jobs, job, next);
+        qemu_cond_broadcast(&queue->cond);
+    }
+    vnc_unlock_queue(queue);
+}
+
+static bool vnc_has_job_locked(VncState *vs)
+{
+    VncJob *job;
+
+    QTAILQ_FOREACH(job, &queue->jobs, next) {
+        if (job->vs == vs || !vs) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool vnc_has_job(VncState *vs)
+{
+    bool ret;
+
+    vnc_lock_queue(queue);
+    ret = vnc_has_job_locked(vs);
+    vnc_unlock_queue(queue);
+    return ret;
+}
+
+void vnc_jobs_clear(VncState *vs)
+{
+    VncJob *job, *tmp;
+
+    vnc_lock_queue(queue);
+    QTAILQ_FOREACH_SAFE(job, &queue->jobs, next, tmp) {
+        if (job->vs == vs || !vs) {
+            QTAILQ_REMOVE(&queue->jobs, job, next);
+        }
+    }
+    vnc_unlock_queue(queue);
+}
+
+void vnc_jobs_join(VncState *vs)
+{
+    vnc_lock_queue(queue);
+    while (vnc_has_job_locked(vs)) {
+        qemu_cond_wait(&queue->cond, &queue->mutex);
+    }
+    vnc_unlock_queue(queue);
+    vnc_jobs_consume_buffer(vs);
+}
+
+void vnc_jobs_consume_buffer(VncState *vs)
+{
+    bool flush;
+
+    vnc_lock_output(vs);
+    if (vs->jobs_buffer.offset) {
+        vnc_write(vs, vs->jobs_buffer.buffer, vs->jobs_buffer.offset);
+        buffer_reset(&vs->jobs_buffer);
+    }
+    flush = vs->csock != -1 && vs->abort != true;
+    vnc_unlock_output(vs);
+
+    if (flush) {
+      vnc_flush(vs);
+    }
+}
+
+/*
+ * Copy data for local use
+ */
+static void vnc_async_encoding_start(VncState *orig, VncState *local)
+{
+    local->vnc_encoding = orig->vnc_encoding;
+    local->features = orig->features;
+    local->ds = orig->ds;
+    local->vd = orig->vd;
+    local->lossy_rect = orig->lossy_rect;
+    local->write_pixels = orig->write_pixels;
+    local->clientds = orig->clientds;
+    local->tight = orig->tight;
+    local->zlib = orig->zlib;
+    local->hextile = orig->hextile;
+    local->zrle = orig->zrle;
+    local->output =  queue->buffer;
+    local->csock = -1; /* Don't do any network work on this thread */
+
+    buffer_reset(&local->output);
+}
+
+static void vnc_async_encoding_end(VncState *orig, VncState *local)
+{
+    orig->tight = local->tight;
+    orig->zlib = local->zlib;
+    orig->hextile = local->hextile;
+    orig->zrle = local->zrle;
+    orig->lossy_rect = local->lossy_rect;
+
+    queue->buffer = local->output;
+}
+
+static int vnc_worker_thread_loop(VncJobQueue *queue)
+{
+    VncJob *job;
+    VncRectEntry *entry, *tmp;
+    VncState vs;
+    int n_rectangles;
+    int saved_offset;
+
+    vnc_lock_queue(queue);
+    while (QTAILQ_EMPTY(&queue->jobs) && !queue->exit) {
+        qemu_cond_wait(&queue->cond, &queue->mutex);
+    }
+    /* Here job can only be NULL if queue->exit is true */
+    job = QTAILQ_FIRST(&queue->jobs);
+    vnc_unlock_queue(queue);
+
+    if (queue->exit) {
+        return -1;
+    }
+
+    vnc_lock_output(job->vs);
+    if (job->vs->csock == -1 || job->vs->abort == true) {
+        vnc_unlock_output(job->vs);
+        goto disconnected;
+    }
+    vnc_unlock_output(job->vs);
+
+    /* Make a local copy of vs and switch output buffers */
+    vnc_async_encoding_start(job->vs, &vs);
+
+    /* Start sending rectangles */
+    n_rectangles = 0;
+    vnc_write_u8(&vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
+    vnc_write_u8(&vs, 0);
+    saved_offset = vs.output.offset;
+    vnc_write_u16(&vs, 0);
+
+    vnc_lock_display(job->vs->vd);
+    QLIST_FOREACH_SAFE(entry, &job->rectangles, next, tmp) {
+        int n;
+
+        if (job->vs->csock == -1) {
+            vnc_unlock_display(job->vs->vd);
+            goto disconnected;
+        }
+
+        n = vnc_send_framebuffer_update(&vs, entry->rect.x, entry->rect.y,
+                                        entry->rect.w, entry->rect.h);
+
+        if (n >= 0) {
+            n_rectangles += n;
+        }
+        g_free(entry);
+    }
+    vnc_unlock_display(job->vs->vd);
+
+    /* Put n_rectangles at the beginning of the message */
+    vs.output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
+    vs.output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
+
+    vnc_lock_output(job->vs);
+    if (job->vs->csock != -1) {
+        buffer_reserve(&job->vs->jobs_buffer, vs.output.offset);
+        buffer_append(&job->vs->jobs_buffer, vs.output.buffer,
+                      vs.output.offset);
+        /* Copy persistent encoding data */
+        vnc_async_encoding_end(job->vs, &vs);
+
+	qemu_bh_schedule(job->vs->bh);
+    }
+    vnc_unlock_output(job->vs);
+
+disconnected:
+    vnc_lock_queue(queue);
+    QTAILQ_REMOVE(&queue->jobs, job, next);
+    vnc_unlock_queue(queue);
+    qemu_cond_broadcast(&queue->cond);
+    g_free(job);
+    return 0;
+}
+
+static VncJobQueue *vnc_queue_init(void)
+{
+    VncJobQueue *queue = g_malloc0(sizeof(VncJobQueue));
+
+    qemu_cond_init(&queue->cond);
+    qemu_mutex_init(&queue->mutex);
+    QTAILQ_INIT(&queue->jobs);
+    return queue;
+}
+
+static void vnc_queue_clear(VncJobQueue *q)
+{
+    qemu_cond_destroy(&queue->cond);
+    qemu_mutex_destroy(&queue->mutex);
+    buffer_free(&queue->buffer);
+    g_free(q);
+    queue = NULL; /* Unset global queue */
+}
+
+static void *vnc_worker_thread(void *arg)
+{
+    VncJobQueue *queue = arg;
+
+    qemu_thread_get_self(&queue->thread);
+
+    while (!vnc_worker_thread_loop(queue)) ;
+    vnc_queue_clear(queue);
+    return NULL;
+}
+
+void vnc_start_worker_thread(void)
+{
+    VncJobQueue *q;
+
+    if (vnc_worker_thread_running())
+        return ;
+
+    q = vnc_queue_init();
+    qemu_thread_create(&q->thread, vnc_worker_thread, q, QEMU_THREAD_DETACHED);
+    queue = q; /* Set global queue */
+}
+
+bool vnc_worker_thread_running(void)
+{
+    return queue; /* Check global queue */
+}
+
+void vnc_stop_worker_thread(void)
+{
+    if (!vnc_worker_thread_running())
+        return ;
+
+    /* Remove all jobs and wake up the thread */
+    vnc_lock_queue(queue);
+    queue->exit = true;
+    vnc_unlock_queue(queue);
+    vnc_jobs_clear(NULL);
+    qemu_cond_broadcast(&queue->cond);
+}
diff --git a/ui/vnc-jobs.h b/ui/vnc-jobs.h
index 4c661f9..86e6d88 100644
--- a/ui/vnc-jobs.h
+++ b/ui/vnc-jobs.h
@@ -38,51 +38,35 @@  bool vnc_has_job(VncState *vs);
 void vnc_jobs_clear(VncState *vs);
 void vnc_jobs_join(VncState *vs);
 
-#ifdef CONFIG_VNC_THREAD
-
 void vnc_jobs_consume_buffer(VncState *vs);
 void vnc_start_worker_thread(void);
 bool vnc_worker_thread_running(void);
 void vnc_stop_worker_thread(void);
 
-#endif /* CONFIG_VNC_THREAD */
-
 /* Locks */
 static inline int vnc_trylock_display(VncDisplay *vd)
 {
-#ifdef CONFIG_VNC_THREAD
     return qemu_mutex_trylock(&vd->mutex);
-#else
-    return 0;
-#endif
 }
 
 static inline void vnc_lock_display(VncDisplay *vd)
 {
-#ifdef CONFIG_VNC_THREAD
     qemu_mutex_lock(&vd->mutex);
-#endif
 }
 
 static inline void vnc_unlock_display(VncDisplay *vd)
 {
-#ifdef CONFIG_VNC_THREAD
     qemu_mutex_unlock(&vd->mutex);
-#endif
 }
 
 static inline void vnc_lock_output(VncState *vs)
 {
-#ifdef CONFIG_VNC_THREAD
     qemu_mutex_lock(&vs->output_mutex);
-#endif
 }
 
 static inline void vnc_unlock_output(VncState *vs)
 {
-#ifdef CONFIG_VNC_THREAD
     qemu_mutex_unlock(&vs->output_mutex);
-#endif
 }
 
 #endif /* VNC_JOBS_H */
diff --git a/ui/vnc.c b/ui/vnc.c
index 54bc5ad..cf1cae2 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -526,7 +526,6 @@  static void vnc_desktop_resize(VncState *vs)
     vnc_flush(vs);
 }
 
-#ifdef CONFIG_VNC_THREAD
 static void vnc_abort_display_jobs(VncDisplay *vd)
 {
     VncState *vs;
@@ -545,11 +544,6 @@  static void vnc_abort_display_jobs(VncDisplay *vd)
         vnc_unlock_output(vs);
     }
 }
-#else
-static void vnc_abort_display_jobs(VncDisplay *vd)
-{
-}
-#endif
 
 static void vnc_dpy_resize(DisplayState *ds)
 {
@@ -867,19 +861,12 @@  static int find_and_clear_dirty_height(struct VncState *vs,
     return h;
 }
 
-#ifdef CONFIG_VNC_THREAD
 static int vnc_update_client_sync(VncState *vs, int has_dirty)
 {
     int ret = vnc_update_client(vs, has_dirty);
     vnc_jobs_join(vs);
     return ret;
 }
-#else
-static int vnc_update_client_sync(VncState *vs, int has_dirty)
-{
-    return vnc_update_client(vs, has_dirty);
-}
-#endif
 
 static int vnc_update_client(VncState *vs, int has_dirty)
 {
@@ -1066,11 +1053,9 @@  static void vnc_disconnect_finish(VncState *vs)
         qemu_remove_led_event_handler(vs->led);
     vnc_unlock_output(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]);
@@ -1286,14 +1271,12 @@  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
@@ -2699,10 +2682,8 @@  static void vnc_connect(VncDisplay *vd, int csock, int skipauth)
     vs->as.fmt = AUD_FMT_S16;
     vs->as.endianness = 0;
 
-#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);
 
@@ -2762,10 +2743,8 @@  void vnc_display_init(DisplayState *ds)
     if (!vs->kbd_layout)
         exit(1);
 
-#ifdef CONFIG_VNC_THREAD
     qemu_mutex_init(&vs->mutex);
     vnc_start_worker_thread();
-#endif
 
     dcl->dpy_copy = vnc_dpy_copy;
     dcl->dpy_update = vnc_dpy_update;
diff --git a/ui/vnc.h b/ui/vnc.h
index a851ebd..068c2fc 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -29,9 +29,7 @@ 
 
 #include "qemu-common.h"
 #include "qemu-queue.h"
-#ifdef CONFIG_VNC_THREAD
 #include "qemu-thread.h"
-#endif
 #include "console.h"
 #include "monitor.h"
 #include "audio/audio.h"
@@ -146,9 +144,7 @@  struct VncDisplay
     DisplayState *ds;
     kbd_layout_t *kbd_layout;
     int lock_key_sync;
-#ifdef CONFIG_VNC_THREAD
     QemuMutex mutex;
-#endif
 
     QEMUCursor *cursor;
     int cursor_msize;
@@ -216,7 +212,6 @@  typedef struct VncZywrle {
     int buf[VNC_ZRLE_TILE_WIDTH * VNC_ZRLE_TILE_HEIGHT];
 } VncZywrle;
 
-#ifdef CONFIG_VNC_THREAD
 struct VncRect
 {
     int x;
@@ -238,14 +233,6 @@  struct VncJob
     QLIST_HEAD(, VncRectEntry) rectangles;
     QTAILQ_ENTRY(VncJob) next;
 };
-#else
-struct VncJob
-{
-    VncState *vs;
-    int rectangles;
-    size_t saved_offset;
-};
-#endif
 
 struct VncState
 {
@@ -300,13 +287,9 @@  struct VncState
     QEMUPutLEDEntry *led;
 
     bool abort;
-#ifndef CONFIG_VNC_THREAD
-    VncJob job;
-#else
     QemuMutex output_mutex;
     QEMUBH *bh;
     Buffer jobs_buffer;
-#endif
 
     /* Encoding specific, if you add something here, don't forget to
      *  update vnc_async_encoding_start()