[Spice-devel] [PATCH win-agent] vdagent: reset clipboard event

Arnon Gilboa agilboa at redhat.com
Sun May 27 23:50:36 PDT 2012


Seems like the right hack. ACK.

Marc-André Lureau wrote:
> 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()
>   



More information about the Spice-devel mailing list