diff options
Diffstat (limited to 'ui/vnc.c')
-rw-r--r-- | ui/vnc.c | 28 |
1 files changed, 24 insertions, 4 deletions
@@ -1021,14 +1021,28 @@ static bool vnc_should_update(VncState *vs) break; case VNC_STATE_UPDATE_INCREMENTAL: /* Only allow incremental updates if the pending send queue - * is less than the permitted threshold + * is less than the permitted threshold, and the job worker + * is completely idle. */ - if (vs->output.offset < vs->throttle_output_offset) { + if (vs->output.offset < vs->throttle_output_offset && + vs->job_update == VNC_STATE_UPDATE_NONE) { return true; } break; case VNC_STATE_UPDATE_FORCE: - return true; + /* Only allow forced updates if the pending send queue + * does not contain a previous forced update, and the + * job worker is completely idle. + * + * Note this means we'll queue a forced update, even if + * the output buffer size is otherwise over the throttle + * output limit. + */ + if (vs->force_update_offset == 0 && + vs->job_update == VNC_STATE_UPDATE_NONE) { + return true; + } + break; } return false; } @@ -1096,8 +1110,9 @@ static int vnc_update_client(VncState *vs, int has_dirty) } } - vnc_job_push(job); + vs->job_update = vs->update; vs->update = VNC_STATE_UPDATE_NONE; + vnc_job_push(job); vs->has_dirty = 0; return n; } @@ -1332,6 +1347,11 @@ static ssize_t vnc_client_write_plain(VncState *vs) if (!ret) return 0; + if (ret >= vs->force_update_offset) { + vs->force_update_offset = 0; + } else { + vs->force_update_offset -= ret; + } buffer_advance(&vs->output, ret); if (vs->output.offset == 0) { |