Hi, On 12/27/2012 07:23 AM, Jackson wrote:
OK! in my situation, my webcam can redirect to VM, then, I open amcap and check the code. I find that there are two ways running into the same for loop, and I'm not sure it is normal or not? first route the client receive message through usbredir channel, then 1. usbredir_handle_msg 2. usbredirparser_do_read 3. case usb_redir_stop_interrupt_receiving: parser->callb.stop_interrupt_receiving_func(...) 4. usbredirhost_stop_interrupt_receiving 5. usbredir_write_flush_callback 6. usbredirparser_do_write 7. in loop, for(;;){} second route another thread run while loop rc = libusb_handle_events(priv->context); 1. spice_usb_device_manager_usb_ev_thread 2. libusb_handle_events 3. libusb_handle_events_timeout_completed 4. handle_events 5. windows_handle_events 6. windows_handle_callback case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: windows_transfer_callback(itransfer, io_result, io_size); 7. windows_transfer_callback 8. usbi_handle_transfer_completion 9. usbredirhost_interrupt_packet_complete 10. usbredir_write_flush_callback 11. usbredirparser_do_write 12. in loop, for(;;){}
Yes this is normal, note that both threads can *not* enter the loop at the same time, as usbredirparser_do_write starts like this: int usbredirparser_do_write(struct usbredirparser *parser_pub) { struct usbredirparser_priv *parser = (struct usbredirparser_priv *)parser_pub; struct usbredirparser_buf* wbuf; int w, ret = 0; LOCK(parser); for (;;) { Notice the LOCK call there, now that may be a nop when the user of usbredirparser does not use any locks, but spice-gtk does use the locks, it creates the parser through usbredirhost with locking functions, from spice-gtk/gtk/gtk/channel-usbredir.c void spice_usbredir_channel_set_context(SpiceUsbredirChannel *channel, libusb_context *context) { SpiceUsbredirChannelPrivate *priv = channel->priv; g_return_if_fail(priv->host == NULL); priv->context = context; priv->host = usbredirhost_open_full( context, NULL, usbredir_log, usbredir_read_callback, usbredir_write_callback, usbredir_write_flush_callback, usbredir_alloc_lock, usbredir_lock_lock, usbredir_unlock_lock, usbredir_free_lock, channel, PACKAGE_STRING, spice_util_get_debug() ? usbredirparser_debu usbredirhost_fl_write_cb_owns_buffer); Note how it specifies lock alloc, lock, unlock and free functions, so usbredirhost / usbredirparser will use locking and only one thread can be running in the for loop at a time (and once the second thread loop runs it will exit immediately since the flush is already done). Regards, Hans _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel