<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jul 7, 2015 at 1:47 PM, Christophe Fergeau <span dir="ltr"><<a href="mailto:cfergeau@redhat.com" target="_blank">cfergeau@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">On Mon, Jul 06, 2015 at 08:59:02PM +0300, Kirill Moizik wrote:<br>
> wnd_proc callback should not query usb devices in the middle of redirecting flow. Caller may get inconsistent enumeration results due to device resets performed by UsbDk and Windows mechanisms handling those resets.<br>
<br>
</span>Please wrap all your logs to 72 chars or so.<br>
<div><div class="h5"><br>
><br>
> Signed-off-by: Kirill Moizik <<a href="mailto:kirill@daynix.com">kirill@daynix.com</a>><br>
> ---<br>
>  src/map-file      |  2 ++<br>
>  src/win-usb-dev.c | 15 +++++++++++++++<br>
>  src/win-usb-dev.h |  2 ++<br>
>  3 files changed, 19 insertions(+)<br>
><br>
> diff --git a/src/map-file b/src/map-file<br>
> index d5a073f..d0c24a4 100644<br>
> --- a/src/map-file<br>
> +++ b/src/map-file<br>
> @@ -117,6 +117,8 @@ spice_uri_to_string;<br>
>  spice_usb_device_get_description;<br>
>  spice_usb_device_get_libusb_device;<br>
>  spice_usb_device_get_type;<br>
> +spice_g_udev_set_redirecting;<br>
> +spice_g_udev_handle_device_change;<br>
>  spice_usb_device_manager_can_redirect_device;<br>
>  spice_usb_device_manager_connect_device_async;<br>
>  spice_usb_device_manager_connect_device_finish;<br>
> diff --git a/src/win-usb-dev.c b/src/win-usb-dev.c<br>
> index 1e4b2d6..23bea42 100644<br>
> --- a/src/win-usb-dev.c<br>
> +++ b/src/win-usb-dev.c<br>
> @@ -37,6 +37,7 @@ struct _GUdevClientPrivate {<br>
>      gssize udev_list_size;<br>
>      GList *udev_list;<br>
>      HWND hwnd;<br>
> +    gboolean redirecting;<br>
>  };<br>
><br>
>  #define G_UDEV_CLIENT_WINCLASS_NAME  TEXT("G_UDEV_CLIENT")<br>
> @@ -186,6 +187,7 @@ g_udev_client_initable_init(GInitable *initable, GCancellable *cancellable,<br>
>      self = G_UDEV_CLIENT(initable);<br>
>      priv = self->priv;<br>
><br>
> +    priv->redirecting = FALSE;<br>
>      rc = libusb_init(&priv->ctx);<br>
>      if (rc < 0) {<br>
>          const char *errstr = spice_usbutil_libusb_strerror(rc);<br>
> @@ -334,6 +336,11 @@ static gboolean gudev_devices_are_equal(GUdevDevice *a, GUdevDevice *b)<br>
>      return (same_pid && same_vid);<br>
>  }<br>
><br>
> +void spice_g_udev_set_redirecting (gboolean val)<br>
> +{<br>
> +    GUdevClientPrivate *priv = singleton->priv;<br>
> +    priv->redirecting = val;<br>
> +}<br>
<br>
</div></div>I still think we should have something like<br>
if (priv->redirecting && !val) {<br>
    handle_dev_change(singleton);<br>
}<br>
<br>
and not export spice_g_udev_handle_device_change() as updating the<br>
device list is required anyway when redirecting changes from TRUE to<br>
FALSE. Doing it automatically makes using the API less error-prone...<br>
<span class=""><br></span></blockquote><div><br></div><div>The problem is not to prevent call  handle_dev_change from  the usb-device-widget.c</div><div>I agree with you here, in this case it is better solution. The problem is here</div><div><br></div><div><p style="margin:0px;font-size:14px;font-family:Menlo"><span style="color:rgb(52,189,38)">static</span> LRESULT CALLBACK wnd_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)</p>
<p style="margin:0px;font-size:14px;font-family:Menlo">{</p>
<p style="margin:0px;font-size:14px;font-family:Menlo;color:rgb(83,48,225)"><span style="color:rgb(0,0,0)">    </span>/* Only DBT_DEVNODES_CHANGED recieved */</p>
<p style="margin:0px;font-size:14px;font-family:Menlo">    <span style="color:rgb(206,121,36)">if</span> (message == WM_DEVICECHANGE) {</p>
<p style="margin:0px;font-size:14px;font-family:Menlo">        <span style="background-color:rgb(230,230,0)">handle_dev_change</span>(singleton);</p>
<p style="margin:0px;font-size:14px;font-family:Menlo">    }</p>
<p style="margin:0px;font-size:14px;font-family:Menlo">    <span style="color:rgb(206,121,36)">return</span> DefWindowProc(hwnd, message, wparam, lparam);</p>
<p style="margin:0px;font-size:14px;font-family:Menlo">}</p><p style="margin:0px;font-size:14px;font-family:Menlo"><br></p><p style="margin:0px;font-size:14px;font-family:Menlo">It is a registered system callback. The only context available when it is called is GUdevClient singleton object.</p><p style="margin:0px;font-size:14px;font-family:Menlo"><br></p></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
><br>
>  /* Assumes each event stands for a single device change (at most) */<br>
>  static void handle_dev_change(GUdevClient *self)<br>
> @@ -347,6 +354,9 @@ static void handle_dev_change(GUdevClient *self)<br>
>      GList *llist, *slist; /* long-list and short-list*/<br>
>      GList *lit, *sit; /* iterators for long-list and short-list */<br>
>      GUdevDevice *ldev, *sdev; /* devices on long-list and short-list */<br>
> +    if (priv->redirecting == TRUE) {<br>
<br>
</span>Just if (priv->redirecting) { }, especially as g_udev_set_redirecting()<br>
does not do priv->redirecting = !!val; to ensure this only gets set to 0<br>
or 1<br>
<span class=""><font color="#888888"><br>
Christophe<br>
</font></span></blockquote></div><br></div></div>