[Spice-devel] [PATCH win-agent] vdagent: reset clipboard event
Marc-André Lureau
marcandre.lureau at gmail.com
Fri May 25 11:23:35 PDT 2012
Waiting for a Windows event will not last if it is already set.
For example, the client may send clipboard_release() messages
while we are not waiting in on_clipboard_request(), and this will
SetEvent(clipboard_event)
The following clipboard request will thus not wait for the data,
resulting in an empty clipboard & paste for the guest application.
We could say there is fundamentally a race as there is no obvious
way to know if a received message is related to the current request,
but by reseting the event before waiting for new events to come, we
at least clear the past events.
---
vdagent/vdagent.cpp | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index 9046476..eb6ffd4 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -918,13 +918,32 @@ void VDAgent::on_clipboard_request(UINT format)
VD_AGENT_CAP_CLIPBOARD_BY_DEMAND)) {
return;
}
+
VDAgentClipboardRequest request = {type};
if (!write_message(VD_AGENT_CLIPBOARD_REQUEST, sizeof(request), &request)) {
return;
}
+
+ // next clipboard event will be considered a reply to this request
+ ResetEvent(_clipboard_event);
+
DWORD start_tick = GetTickCount();
- while (WaitForSingleObjectEx(_clipboard_event, 1000, TRUE) != WAIT_OBJECT_0 &&
- GetTickCount() < start_tick + VD_CLIPBOARD_TIMEOUT_MS);
+ do {
+ DWORD wait_result = WaitForSingleObjectEx(_clipboard_event, 1000, TRUE);
+
+ switch (wait_result) {
+ case WAIT_OBJECT_0:
+ return;
+ case WAIT_IO_COMPLETION:
+ case WAIT_TIMEOUT:
+ break;
+ default:
+ vd_printf("Wait error (%d)\n", GetLastError());
+ return;
+ }
+ } while (GetTickCount() < start_tick + VD_CLIPBOARD_TIMEOUT_MS);
+
+ vd_printf("wait timeout.. ");
}
void VDAgent::on_clipboard_release()
--
1.7.10.1
More information about the Spice-devel
mailing list