mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-01-05 06:00:43 +00:00
red-channel-client: Allows to block receiving data
If the client is keeping sending data while we can't handle them (for instance because we need to forward to a device but the device is not fast enough to receive that amount of data) allows to stop RedChannelClient to read data. This after a bit will stop the client sending data as its output buffer will become full. Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
This commit is contained in:
parent
1157588cc1
commit
726b1824e3
@ -145,6 +145,7 @@ struct RedChannelClientPrivate
|
||||
} urgent;
|
||||
} send_data;
|
||||
|
||||
bool block_read;
|
||||
bool during_send;
|
||||
GQueue pipe;
|
||||
|
||||
@ -969,10 +970,32 @@ red_channel_client_watch_update_mask(RedChannelClient *rcc, int event_mask)
|
||||
return;
|
||||
}
|
||||
|
||||
if (rcc->priv->block_read) {
|
||||
event_mask &= ~SPICE_WATCH_EVENT_READ;
|
||||
}
|
||||
|
||||
core = red_channel_get_core_interface(rcc->priv->channel);
|
||||
core->watch_update_mask(core, rcc->priv->stream->watch, event_mask);
|
||||
}
|
||||
|
||||
void red_channel_client_block_read(RedChannelClient *rcc)
|
||||
{
|
||||
if (rcc->priv->block_read) {
|
||||
return;
|
||||
}
|
||||
rcc->priv->block_read = true;
|
||||
red_channel_client_watch_update_mask(rcc, SPICE_WATCH_EVENT_WRITE);
|
||||
}
|
||||
|
||||
void red_channel_client_unblock_read(RedChannelClient *rcc)
|
||||
{
|
||||
if (!rcc->priv->block_read) {
|
||||
return;
|
||||
}
|
||||
rcc->priv->block_read = false;
|
||||
red_channel_client_watch_update_mask(rcc, SPICE_WATCH_EVENT_READ|SPICE_WATCH_EVENT_WRITE);
|
||||
}
|
||||
|
||||
static void red_channel_client_seamless_migration_done(RedChannelClient *rcc)
|
||||
{
|
||||
rcc->priv->wait_migrate_data = FALSE;
|
||||
@ -1213,6 +1236,11 @@ static void red_channel_client_handle_incoming(RedChannelClient *rcc)
|
||||
if (buffer->msg_pos < msg_size) {
|
||||
if (!buffer->msg) {
|
||||
buffer->msg = red_channel_client_alloc_msg_buf(rcc, msg_type, msg_size);
|
||||
if (buffer->msg == NULL && rcc->priv->block_read) {
|
||||
// if we are blocked by flow control just return, message will be read
|
||||
// when data will be available
|
||||
return;
|
||||
}
|
||||
if (buffer->msg == NULL) {
|
||||
red_channel_warning(channel, "ERROR: channel refused to allocate buffer.");
|
||||
red_channel_client_disconnect(rcc);
|
||||
|
||||
@ -137,6 +137,10 @@ gboolean red_channel_client_set_migration_seamless(RedChannelClient *rcc);
|
||||
void red_channel_client_set_destroying(RedChannelClient *rcc);
|
||||
bool red_channel_client_is_destroying(RedChannelClient *rcc);
|
||||
|
||||
/* allow to block or unblock reading */
|
||||
void red_channel_client_block_read(RedChannelClient *rcc);
|
||||
void red_channel_client_unblock_read(RedChannelClient *rcc);
|
||||
|
||||
struct RedChannelClient
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user