mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 21:27:40 +00:00
Fix race condition where the source of a copy operation may be altered before the destination is drawn to (thus the copy may not always copy what we THINK it should be copying, especially if many buffers are repeatedly used and quickly discarded).
This commit is contained in:
@@ -372,7 +372,7 @@ Guacamole.Layer = function(width, height) {
|
|||||||
* pending operations are complete.
|
* pending operations are complete.
|
||||||
*/
|
*/
|
||||||
this.sync = function(handler) {
|
this.sync = function(handler) {
|
||||||
scheduleTask(handler);
|
return scheduleTask(handler);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -398,12 +398,18 @@ Guacamole.Layer = function(width, height) {
|
|||||||
*/
|
*/
|
||||||
this.copyRect = function(srcLayer, srcx, srcy, srcw, srch, x, y) {
|
this.copyRect = function(srcLayer, srcx, srcy, srcw, srch, x, y) {
|
||||||
|
|
||||||
|
var srcCopied = null;
|
||||||
|
|
||||||
function doCopyRect() {
|
function doCopyRect() {
|
||||||
if (layer.autosize != 0) fitRect(x, y, srcw, srch);
|
if (layer.autosize != 0) fitRect(x, y, srcw, srch);
|
||||||
|
|
||||||
var srcCanvas = srcLayer.getCanvas();
|
var srcCanvas = srcLayer.getCanvas();
|
||||||
if (srcCanvas.width != 0 && srcCanvas.height != 0)
|
if (srcCanvas.width != 0 && srcCanvas.height != 0)
|
||||||
displayContext.drawImage(srcCanvas, srcx, srcy, srcw, srch, x, y, srcw, srch);
|
displayContext.drawImage(srcCanvas, srcx, srcy, srcw, srch, x, y, srcw, srch);
|
||||||
|
|
||||||
|
// Unblock the copy complete task, if it exists
|
||||||
|
if (srcCopied != null)
|
||||||
|
srcCopied.handler = function() {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we ARE the source layer, no need to sync.
|
// If we ARE the source layer, no need to sync.
|
||||||
@@ -413,8 +419,13 @@ Guacamole.Layer = function(width, height) {
|
|||||||
|
|
||||||
// Otherwise synchronize copy operation with source layer
|
// Otherwise synchronize copy operation with source layer
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
// Task which will be unblocked only when the source layer is ready
|
||||||
|
// This task will perform the copy
|
||||||
var task = scheduleTask(null);
|
var task = scheduleTask(null);
|
||||||
srcLayer.sync(function() {
|
|
||||||
|
// Task which will unblock the drawing task.
|
||||||
|
var srcReady = srcLayer.sync(function() {
|
||||||
|
|
||||||
task.handler = doCopyRect;
|
task.handler = doCopyRect;
|
||||||
|
|
||||||
@@ -423,6 +434,13 @@ Guacamole.Layer = function(width, height) {
|
|||||||
handlePendingTasks();
|
handlePendingTasks();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Task which will be unblocked only after the copy has
|
||||||
|
// occurred (this will only be created if the draw task
|
||||||
|
// was postponed)
|
||||||
|
if (srcReady != null)
|
||||||
|
srcCopied = srcLayer.sync(null);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user