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,
This commit is contained in:
parent
7e79cf4083
commit
22b626e28e
@ -19,6 +19,7 @@
|
|||||||
#include <spice-experimental.h>
|
#include <spice-experimental.h>
|
||||||
|
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "qemu-spice.h"
|
#include "qemu-spice.h"
|
||||||
@ -44,6 +45,8 @@ static char *auth_passwd;
|
|||||||
static time_t auth_expires = TIME_MAX;
|
static time_t auth_expires = TIME_MAX;
|
||||||
int using_spice = 0;
|
int using_spice = 0;
|
||||||
|
|
||||||
|
static pthread_t me;
|
||||||
|
|
||||||
struct SpiceTimer {
|
struct SpiceTimer {
|
||||||
QEMUTimer *timer;
|
QEMUTimer *timer;
|
||||||
QTAILQ_ENTRY(SpiceTimer) next;
|
QTAILQ_ENTRY(SpiceTimer) next;
|
||||||
@ -217,6 +220,20 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
|
|||||||
QDict *server, *client;
|
QDict *server, *client;
|
||||||
QObject *data;
|
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();
|
client = qdict_new();
|
||||||
add_addr_info(client, &info->paddr, info->plen);
|
add_addr_info(client, &info->paddr, info->plen);
|
||||||
|
|
||||||
@ -236,6 +253,10 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
|
|||||||
QOBJECT(client), QOBJECT(server));
|
QOBJECT(client), QOBJECT(server));
|
||||||
monitor_protocol_event(qevent[event], data);
|
monitor_protocol_event(qevent[event], data);
|
||||||
qobject_decref(data);
|
qobject_decref(data);
|
||||||
|
|
||||||
|
if (need_lock) {
|
||||||
|
qemu_mutex_unlock_iothread();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* SPICE_INTERFACE_CORE_MINOR >= 3 */
|
#else /* SPICE_INTERFACE_CORE_MINOR >= 3 */
|
||||||
@ -482,7 +503,9 @@ void qemu_spice_init(void)
|
|||||||
spice_image_compression_t compression;
|
spice_image_compression_t compression;
|
||||||
spice_wan_compression_t wan_compr;
|
spice_wan_compression_t wan_compr;
|
||||||
|
|
||||||
if (!opts) {
|
me = pthread_self();
|
||||||
|
|
||||||
|
if (!opts) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
port = qemu_opt_get_number(opts, "port", 0);
|
port = qemu_opt_get_number(opts, "port", 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user