On Mon, Dec 19, 2011 at 12:24:37PM +0100, Hans de Goede wrote: > The new (in usbredir-0.3.2) usbredirhost_open_full() > function allows us to be notified whenever usb packets completing > result in data to be send to the host. This removes the need for using > g_usb_source_set_callback and seeing if there is data to write on > any of the usb channels each time some usb event happens. > > This also bumps the minimum needed libusbredirhost version to 0.3.2 > > Signed-off-by: Hans de Goede <hdego...@redhat.com> > --- > configure.ac | 2 +- > gtk/channel-usbredir-priv.h | 2 -- > gtk/channel-usbredir.c | 43 > +++++++++++++++++++++---------------------- > gtk/usb-device-manager.c | 23 ----------------------- > 4 files changed, 22 insertions(+), 48 deletions(-) > > diff --git a/configure.ac b/configure.ac > index e38aad1..db9ff7d 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -327,7 +327,7 @@ if test "x$enable_usbredir" = "xno"; then > else > PKG_CHECK_MODULES(GUDEV, gudev-1.0) > PKG_CHECK_MODULES(LIBUSB, libusb-1.0 >= 1.0.9) > - PKG_CHECK_MODULES(LIBUSBREDIRHOST, libusbredirhost >= 0.3.1) > + PKG_CHECK_MODULES(LIBUSBREDIRHOST, libusbredirhost >= 0.3.2) > AC_DEFINE(USE_USBREDIR, [1], [Define if supporting usbredir proxying]) > AM_CONDITIONAL(WITH_USBREDIR, true) > if test "x$enable_polkit" = "xno"; then > diff --git a/gtk/channel-usbredir-priv.h b/gtk/channel-usbredir-priv.h > index 8bb42a5..305e897 100644 > --- a/gtk/channel-usbredir-priv.h > +++ b/gtk/channel-usbredir-priv.h > @@ -42,8 +42,6 @@ void spice_usbredir_channel_disconnect(SpiceUsbredirChannel > *channel); > > GUsbDevice *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel); > > -void spice_usbredir_channel_do_write(SpiceUsbredirChannel *channel); > - > G_END_DECLS > > #endif /* __SPICE_CLIENT_USBREDIR_CHANNEL_PRIV_H__ */ > diff --git a/gtk/channel-usbredir.c b/gtk/channel-usbredir.c > index 6574e32..58a4c21 100644 > --- a/gtk/channel-usbredir.c > +++ b/gtk/channel-usbredir.c > @@ -73,7 +73,6 @@ struct _SpiceUsbredirChannelPrivate { > /* Data passed from channel handle msg to the usbredirhost read cb */ > const uint8_t *read_buf; > int read_buf_size; > - SpiceMsgOut *msg_out; > enum SpiceUsbredirChannelState state; > #if USE_POLKIT > GSimpleAsyncResult *result; > @@ -89,6 +88,7 @@ static void usbredir_handle_msg(SpiceChannel *channel, > SpiceMsgIn *in); > static void usbredir_log(void *user_data, int level, const char *msg); > static int usbredir_read_callback(void *user_data, uint8_t *data, int count); > static int usbredir_write_callback(void *user_data, uint8_t *data, int > count); > +static void usbredir_write_flush_callback(void *user_data); > #endif > > G_DEFINE_TYPE(SpiceUsbredirChannel, spice_usbredir_channel, > SPICE_TYPE_CHANNEL) > @@ -178,10 +178,16 @@ static gboolean spice_usbredir_channel_open_device( > } > > priv->catch_error = err; > - priv->host = usbredirhost_open(_g_usb_context_get_context(priv->context), > + priv->host = usbredirhost_open_full( > + _g_usb_context_get_context(priv->context), > handle, usbredir_log, > usbredir_read_callback, > usbredir_write_callback, > + usbredir_write_flush_callback, > + NULL, > + NULL, > + NULL, > + NULL, > channel, PACKAGE_STRING, > spice_util_get_debug() ? > usbredirparser_debug : usbredirparser_warning, > usbredirhost_fl_write_cb_owns_buffer); > @@ -345,26 +351,17 @@ GUsbDevice > *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel) > return channel->priv->device; > } > > -G_GNUC_INTERNAL > -void spice_usbredir_channel_do_write(SpiceUsbredirChannel *channel) > +/* Note that this function must be re-entrant safe, as it can get called > + from both the main thread as well as from the usb event handling thread */ > +static void usbredir_write_flush_callback(void *user_data) > { > + SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(user_data); > SpiceUsbredirChannelPrivate *priv = channel->priv; > > - /* No recursion allowed! */ > - g_return_if_fail(priv->msg_out == NULL); > - > - if (priv->state != STATE_CONNECTED || > - !usbredirhost_has_data_to_write(priv->host)) > + if (priv->state != STATE_CONNECTED)
If this function can run from the usb event handling thread, is there something preventing the check on priv->state from racing with code running in the main thread? Christophe > return; > > - priv->msg_out = spice_msg_out_new(SPICE_CHANNEL(channel), > - SPICE_MSGC_SPICEVMC_DATA); > - > - /* Collect all pending writes in priv->msg_out->marshaller */ > usbredirhost_write_guest_data(priv->host); > - > - spice_msg_out_send(priv->msg_out); > - priv->msg_out = NULL; > } > > /* ------------------------------------------------------------------ */ > @@ -424,10 +421,14 @@ static void usbredir_free_write_cb_data(uint8_t *data, > void *user_data) > static int usbredir_write_callback(void *user_data, uint8_t *data, int count) > { > SpiceUsbredirChannel *channel = user_data; > - SpiceUsbredirChannelPrivate *priv = channel->priv; > - > - spice_marshaller_add_ref_full(priv->msg_out->marshaller, data, count, > + SpiceMsgOut *msg_out; > + > + msg_out = spice_msg_out_new(SPICE_CHANNEL(channel), > + SPICE_MSGC_SPICEVMC_DATA); > + spice_marshaller_add_ref_full(msg_out->marshaller, data, count, > usbredir_free_write_cb_data, channel); > + spice_msg_out_send(msg_out); > + > return count; > } > > @@ -459,7 +460,7 @@ static void spice_usbredir_channel_up(SpiceChannel *c) > > priv->state = STATE_CONNECTED; > /* Flush any pending writes */ > - spice_usbredir_channel_do_write(channel); > + usbredirhost_write_guest_data(priv->host); > } > > static void usbredir_handle_msg(SpiceChannel *c, SpiceMsgIn *in) > @@ -479,8 +480,6 @@ static void usbredir_handle_msg(SpiceChannel *c, > SpiceMsgIn *in) > priv->read_buf_size = size; > > usbredirhost_read_guest_data(priv->host); > - /* Send any acks, etc. which may be queued now */ > - spice_usbredir_channel_do_write(channel); > } > > #endif /* USE_USBREDIR */ > diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c > index ea43b75..fcd1685 100644 > --- a/gtk/usb-device-manager.c > +++ b/gtk/usb-device-manager.c > @@ -404,25 +404,6 @@ static void channel_destroy(SpiceSession *session, > SpiceChannel *channel, > } > > #ifdef USE_USBREDIR > -static gboolean spice_usb_device_manager_source_callback(gpointer user_data) > -{ > - SpiceUsbDeviceManager *self = user_data; > - SpiceUsbDeviceManagerPrivate *priv = self->priv; > - guint i; > - > - /* > - * Flush any writes which may have been caused by async usb packets > - * completing. > - */ > - for (i = 0; i < priv->channels->len; i++) { > - SpiceUsbredirChannel *channel = g_ptr_array_index(priv->channels, i); > - > - spice_usbredir_channel_do_write(channel); > - } > - > - return TRUE; > -} > - > static void spice_usb_device_manager_auto_connect_cb(GObject *gobject, > GAsyncResult *res, > gpointer user_data) > @@ -638,10 +619,6 @@ void > spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self, > g_simple_async_result_take_error(result, e); > goto done; > } > - > - g_usb_source_set_callback(priv->source, > - spice_usb_device_manager_source_callback, > - self, NULL); > } > > for (i = 0; i < priv->channels->len; i++) { > -- > 1.7.7.4 > > _______________________________________________ > Spice-devel mailing list > Spice-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/spice-devel
pgpwUkexDSu6h.pgp
Description: PGP signature
_______________________________________________ Spice-devel mailing list Spice-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/spice-devel