diff options
author | Hans de Goede <hdegoede@redhat.com> | 2010-10-06 12:37:05 +0200 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2010-10-06 19:17:08 +0200 |
commit | 7b84db7a7484b58fdde21029ef374baeaa0a4b51 (patch) | |
tree | b60ecf190ce59021b7e57c3d4b9d4c076536ae9a /client | |
parent | 34bfaa302d5da8e08620d31d3f40d55ee9d14b98 (diff) | |
download | spice-7b84db7a7484b58fdde21029ef374baeaa0a4b51.tar.gz spice-7b84db7a7484b58fdde21029ef374baeaa0a4b51.tar.xz spice-7b84db7a7484b58fdde21029ef374baeaa0a4b51.zip |
spicec: Move setting of clipboard_owner to guest to platform code
Atleast under x11 there is a race condition when setting the clipboard
owner to guest from the RedClient code rather then doing it in Platform.
After the XSetSelectionOwner() in Platform::on_clipboard_grab(), which runs
from the main message loop thread, the x11 event thread can receive a
SelectionRequest event from another x11 app, before the RedClient code
has set the clipboard owner, which will trigger the owner != guest
check in the SelectionRequest event handling code.
By moving the setting of the owner in to Platform::on_clipboard_grab() it
gets protected by the clipboard lock, which closes this tiny race.
Diffstat (limited to 'client')
-rw-r--r-- | client/platform.h | 2 | ||||
-rw-r--r-- | client/red_client.cpp | 1 | ||||
-rw-r--r-- | client/windows/platform.cpp | 7 | ||||
-rw-r--r-- | client/x11/platform.cpp | 10 |
4 files changed, 17 insertions, 3 deletions
diff --git a/client/platform.h b/client/platform.h index af4a0f6c..a9a1715b 100644 --- a/client/platform.h +++ b/client/platform.h @@ -132,6 +132,8 @@ public: static int get_clipboard_owner() { return _clipboard_owner; } private: + static void set_clipboard_owner_unlocked(int new_owner); + static int _clipboard_owner; }; diff --git a/client/red_client.cpp b/client/red_client.cpp index 8e7dfe0e..0650e35a 100644 --- a/client/red_client.cpp +++ b/client/red_client.cpp @@ -1118,7 +1118,6 @@ void RedClient::dispatch_agent_message(VDAgentMessage* msg, void* data) case VD_AGENT_CLIPBOARD_GRAB: Platform::on_clipboard_grab((uint32_t *)data, msg->size / sizeof(uint32_t)); - Platform::set_clipboard_owner(Platform::owner_guest); break; case VD_AGENT_CLIPBOARD_REQUEST: if (Platform::get_clipboard_owner() != Platform::owner_client) { diff --git a/client/windows/platform.cpp b/client/windows/platform.cpp index 580a40ae..075d2690 100644 --- a/client/windows/platform.cpp +++ b/client/windows/platform.cpp @@ -859,6 +859,11 @@ void WinPlatform::exit_modal_loop() int Platform::_clipboard_owner = Platform::owner_none; +void Platform::set_clipboard_owner_unlocked(int new_owner) +{ + set_clipboard_owner(new_owner); +} + void Platform::set_clipboard_owner(int new_owner) { if (new_owner == owner_none) { @@ -885,6 +890,8 @@ bool Platform::on_clipboard_grab(uint32_t *types, uint32_t type_count) EmptyClipboard(); SetClipboardData(format, NULL); CloseClipboard(); + + set_clipboard_owner(owner_guest); return true; } diff --git a/client/x11/platform.cpp b/client/x11/platform.cpp index 29b5f753..8f0665cb 100644 --- a/client/x11/platform.cpp +++ b/client/x11/platform.cpp @@ -3355,6 +3355,8 @@ bool Platform::on_clipboard_grab(uint32_t *types, uint32_t type_count) XSetSelectionOwner(x_display, clipboard_prop, platform_win, CurrentTime); XFlush(x_display); + + set_clipboard_owner_unlocked(owner_guest); return true; } @@ -3362,12 +3364,16 @@ int Platform::_clipboard_owner = Platform::owner_none; void Platform::set_clipboard_owner(int new_owner) { + Lock lock(clipboard_lock); + set_clipboard_owner_unlocked(new_owner); +} + +void Platform::set_clipboard_owner_unlocked(int new_owner) +{ const char * const owner_str[] = { "none", "guest", "client" }; /* Clear pending requests and clipboard data */ { - Lock lock(clipboard_lock); - if (next_selection_request) { LOG_INFO("selection requests pending upon clipboard owner change, clearing"); while (next_selection_request) |