mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-01-08 21:14:11 +00:00
dcc: Fix seamless migration
Since commitef4b1bdb"red-channel-client: Prevent too tight loop waiting for ACKs", after seamless migration, the display is no longer updated on the client-side, even though the VM is functional (responds to keyboard input, reconnecting the client restores the display functionality, ...). This is mainly caused because after migration, red_channel_client_waiting_for_ack() will be true until red_channel_client_ack_zero_messages_window() is called. What happens is the following: The dcc is created, and dcc_start() pushes a RED_PIPE_ITEM_TYPE_SET_ACK message. This calls prepare_pipe_add(), which will enable write event on the dcc watch. red_channel_client_event() will be called, which will trigger a red_channel_client_push(). Since red_channel_client_waiting_for_ack() returns true, we won't get any item to push, and (because of commitef4b1bdb), we will disable write notifications on the watch. At this point, rcc->priv->pipe is no longer empty, so prepare_pipe_add() is not going to reenable the write notifications. Then red_channel_client_ack_zero_messages_window() is finally called as part of dcc_handle_migrate_data(), so from this point on, red_channel_client_waiting_for_ack() is no longer true. However, nothing ever reenables WRITE events, nor empties rcc->priv->pipe, so nothing ever gets pushed, causing no display updates at all after a migration, even if the VM is functional (input, ...) apart from that. This commit reenables WRITE events in red_channel_client_ack_zero_messages_window() if we were waiting for ack. Signed-off-by: Christophe Fergeau <cfergeau@redhat.com>
This commit is contained in:
parent
8705e3d123
commit
657a1d92e8
@ -1327,6 +1327,10 @@ void red_channel_client_push(RedChannelClient *rcc)
|
||||
while ((pipe_item = red_channel_client_pipe_item_get(rcc))) {
|
||||
red_channel_client_send_item(rcc, pipe_item);
|
||||
}
|
||||
/* prepare_pipe_add() will reenable WRITE events when the rcc->priv->pipe is empty
|
||||
* red_channel_client_ack_zero_messages_window() will reenable WRITE events
|
||||
* if we were waiting for acks to be received
|
||||
*/
|
||||
if ((red_channel_client_no_item_being_sent(rcc) && g_queue_is_empty(&rcc->priv->pipe)) ||
|
||||
red_channel_client_waiting_for_ack(rcc)) {
|
||||
red_channel_client_watch_update_mask(rcc, SPICE_WATCH_EVENT_READ);
|
||||
@ -1677,6 +1681,8 @@ static void red_channel_client_pipe_clear(RedChannelClient *rcc)
|
||||
|
||||
void red_channel_client_ack_zero_messages_window(RedChannelClient *rcc)
|
||||
{
|
||||
red_channel_client_watch_update_mask(rcc,
|
||||
SPICE_WATCH_EVENT_READ|SPICE_WATCH_EVENT_WRITE);
|
||||
rcc->priv->ack_data.messages_window = 0;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user