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 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel