[Spice-devel] Is it possible to put spice channels into different threads?

Frediano Ziglio fziglio at redhat.com
Tue Jun 16 13:46:02 UTC 2020


Hi, 
I have an old patch on that code that instead checks if there are pending 
data to send and exit the loop instead of a simple counter. 

But I think that both solutions are not perfect. The reason is that a channel 
is either reading or writing. If there's for instance a very big message to read 
the code will be stuck on reading until all message is received. For the same 
reason if network buffer on the socket is pretty full writing a big message 
will avoid receiving data till the server will read some data decreasing our 
socket send buffer. So a read could block writes while a write could block reads 
(note that other channels are not blocked, we are speaking about reads/writes 
on a single channel). 

Maybe would be good if the socket polling code would poll both read and write 
so to avoid one blocking the other. 

One issue of the loop (current code) on read is that if you manage to get 
stuck on it and the read messages cause messages to be queued for writing 
the queue can grow indefinitely. 

Frediano 

----- Original Message -----

> Hi,

> For now I simply used a counter to work around this issue.

> while (... g_pollable_input_stream_is_readable ) {
> if (loop > 10)
> break;
> }

> Ugly but seems useful.

> BR
> Don

> At 2020-06-15 20:59:00, "Jakub Janku" <jjanku at redhat.com> wrote:
> >Hi,
> >
> >yes, I think this is a real issue. I feel like I've stumbled across
> >something similar in the past when working on webdav.
> >
> >So yeah, it seems like the channel might get blocked in one direction
> >-- meaning data isn't sent until you read all available data.
> >
> >However, that doesn't mean that other channels won't work imho. In a
> >more realistic scenario, you wold read the data from vdagent in chunks
> >and actually do something with it. Webdav uses the code in vmcstream.c
> >to read the data in coroutine and the buffer is delivered to the
> >WebdavChannel using an idle callback. This gives other events the
> >opportunity to fire and be processed and the code can yield to another
> >coroutine. So important channels, like Display, should continue
> >working just fine.
> >
> >PS, it's been quite some time, so I might not remember it correctly.
> >But anyway, if you look at channel-webdav.c and vmcstream.c, you
> >should hopefully get a better idea.
> >
> >Cheers,
> >Jakub
> >
> >On Mon, Jun 15, 2020 at 12:52 PM 陈炤 <qishiyexu2 at 126.com> wrote:
> >>
> >> Hi,
> >>
> >> After debugging, I  think my problem is probably not accociated with
> >> cooperative multitasking.
> >> Here is where spice-gtk read data:
> >>
> >>     /* treat all incoming data (block on message completion) */
> >>     while (!c->has_error &&
> >>            c->state != SPICE_CHANNEL_STATE_MIGRATING &&
> >>            g_pollable_input_stream_is_readable(G_POLLABLE_INPUT_STREAM(c->in))
> >>     ) { do
> >>             spice_channel_recv_msg(channel,
> >>                                    (handler_msg_in)SPICE_CHANNEL_GET_CLASS(channel)->handle_msg,
> >>                                    NULL);
> >> #ifdef HAVE_SASL
> >>             /* flush the sasl buffer too */
> >>         while (c->sasl_decoded != NULL);
> >> #else
> >>         while (FALSE);
> >> #endif
> >>     }
> >>
> >>
> >> If vdagent sends lots of data, spice_channel_recv_msg will be called the
> >> whole time, so iterate_write will not be called, and data will not be
> >> sent out unless vdagent stops sending data.
> >>
> >> BR
> >> Don
> >>
> >>
> >>
> >>
> >> At 2020-06-13 14:40:02, "Frediano Ziglio" <fziglio at redhat.com> wrote:
> >>
> >> Hi,
> >>   the pattern used in spice-gtk is called cooperative multitasking (see
> >>   https://en.wikipedia.org/wiki/Cooperative_multitasking), if you add
> >>   code that is not cooperative you get what you described. Use coroutine
> >>   functions to read remote data so the read won't stop other code. If you
> >>   need to run expensive or blocking code it's a good idea to run it in
> >>   another thread removing the blockage.
> >>
> >> Frediano
> >>
> >> ________________________________
> >>
> >>
> >>
> >> Hi
> >>
> >> Here is my experiment:
> >> I created a new port-channel to transfer data between vdagent and
> >> spice-gtk. I used a while loop to send 2kb data to gtk, gtk received and
> >> drop the data. In the mean time I used a timer(1ms) to send 2kb data to
> >> vdagent.
> >> Strange thing is that gtk will continually receive data for a while(10secs
> >> - 70secs) then send a whole bunch of data to vdagent. When receiving
> >> data, send data will be added to tcp buffer but will not be sent out.
> >>
> >> So I think send event will be affected by receive event, then I guess
> >> using different thread would help.
> >> Could you please correct me if I’m wrong?
> >>
> >> BR
> >> Don
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >> 在 2020-06-12 20:03:30,"Marc-André Lureau" <marcandre.lureau at gmail.com> 写道:
> >>
> >> Hi
> >>
> >> On Fri, Jun 12, 2020 at 12:57 PM 陈炤 <qishiyexu2 at 126.com> wrote:
> >>>
> >>> Hi,
> >>>
> >>> Spice-gtk is now using co-routine to handle different channel
> >>> connections. When a channel is handling data, other channels would have
> >>> to wait, rather than handling synchronously.  That would bring us
> >>> following issues:
> >>>  1. If some less important channels (like usb channels) are transfering
> >>>  big data, important channels (main-channel,
> >>>  display-channel,input-channel) will be affected.
> >>>  2. When receiving big data like file transfering(G_IO_IN), send event
> >>>  (G_IO_OUT) will not be triggered.
> >>>  3. Flow control between different channels will be hard to do.
> >>>
> >>> Is is possible(and make sense) to put channels into different threads so
> >>> they can synchronously receive & send msg, without affect each other?
> >>>
> >>
> >> Switching to threads would be possible, but that wouldn't help in the
> >> situation you describe, as you are very likely bound on IO. Using several
> >> threads would actually create more problems to synchronize and schedule
> >> the different channels.
> >>
> >> Io operations in coroutines are non-blocking, so they shouldn't affect
> >> other spice-gtk task. If you however observe a blocking CPU-task in some
> >> channel, this may affect the performance of other channels. But in
> >> general, except for video/image decoding which may be done in a separate
> >> thread, the client side doesn't do much work.
> >>
> >> USB, clipboard and file sharing may use large amounts of data, and we rely
> >> on the glib source and kernel to prioritize channels: this isn't great in
> >> some cases and may receive improvements.
> >>
> >>
> >> --
> >> Marc-André Lureau
> >>
> >>
> >>
> >>
> >>
> >>
> >> _______________________________________________
> >> Spice-devel mailing list
> >> Spice-devel at lists.freedesktop.org
> >> https://lists.freedesktop.org/mailman/listinfo/spice-devel
> >>
> >>
> >> _______________________________________________
> >> Spice-devel mailing list
> >> Spice-devel at lists.freedesktop.org
> >> https://lists.freedesktop.org/mailman/listinfo/spice-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/spice-devel/attachments/20200616/98e6a545/attachment.htm>


More information about the Spice-devel mailing list