Commit 22b626e2 authored by Gerd Hoffmann's avatar Gerd Hoffmann
Browse files

spice: workaround a spice server bug.

spice server might call the channel_event callback from spice server
thread context.  Detect that and aquire iothread lock if needed,
parent 7e79cf40
Loading
Loading
Loading
Loading
+24 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <spice-experimental.h>

#include <netdb.h>
#include <pthread.h>

#include "qemu-common.h"
#include "qemu-spice.h"
@@ -44,6 +45,8 @@ static char *auth_passwd;
static time_t auth_expires = TIME_MAX;
int using_spice = 0;

static pthread_t me;

struct SpiceTimer {
    QEMUTimer *timer;
    QTAILQ_ENTRY(SpiceTimer) next;
@@ -217,6 +220,20 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
    QDict *server, *client;
    QObject *data;

    /*
     * Spice server might have called us from spice worker thread
     * context (happens on display channel disconnects).  Spice should
     * not do that.  It isn't that easy to fix it in spice and even
     * when it is fixed we still should cover the already released
     * spice versions.  So detect that we've been called from another
     * thread and grab the iothread lock if so before calling qemu
     * functions.
     */
    bool need_lock = !pthread_equal(me, pthread_self());
    if (need_lock) {
        qemu_mutex_lock_iothread();
    }

    client = qdict_new();
    add_addr_info(client, &info->paddr, info->plen);

@@ -236,6 +253,10 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
                              QOBJECT(client), QOBJECT(server));
    monitor_protocol_event(qevent[event], data);
    qobject_decref(data);

    if (need_lock) {
        qemu_mutex_unlock_iothread();
    }
}

#else /* SPICE_INTERFACE_CORE_MINOR >= 3 */
@@ -482,6 +503,8 @@ void qemu_spice_init(void)
    spice_image_compression_t compression;
    spice_wan_compression_t wan_compr;

    me = pthread_self();

   if (!opts) {
        return;
    }