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
[email protected]
http://lists.freedesktop.org/mailman/listinfo/spice-devel