mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-29 00:41:33 +00:00
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.
This commit is contained in:
parent
34bfaa302d
commit
7b84db7a74
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -3355,19 +3355,25 @@ 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;
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user