[Spice-commits] vdagent/vdagent.cpp

Marc-André Lureau elmarco at kemper.freedesktop.org
Mon May 28 04:12:21 PDT 2012


 vdagent/vdagent.cpp |   23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

New commits:
commit 0cef8ba42b88132343306d1dca097f5cb61e493b
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date:   Fri May 25 20:02:54 2012 +0200

    vdagent: reset clipboard event
    
    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.

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()


More information about the Spice-commits mailing list