Bug 1229913 - Prevent race conditions when there are many animation mutations; r=miker

This commit is contained in:
Patrick Brosset 2016-02-01 15:58:04 +01:00
parent d2e34e72f8
commit ff1ec5eddf

View File

@ -144,6 +144,13 @@ var AnimationsController = {
// Expose actor capabilities. // Expose actor capabilities.
this.traits = yield getServerTraits(target); this.traits = yield getServerTraits(target);
// We want to handle animation mutation events synchronously to avoid race
// conditions when there are many rapid mutations. So when a mutation occurs
// and animations are removed, we don't release the corresponding actors
// in a blocking way, we just release asynchronously and don't wait for
// completion, but instead store the promise in this array.
this.nonBlockingPlayerReleases = [];
if (this.destroyed) { if (this.destroyed) {
console.warn("Could not fully initialize the AnimationsController"); console.warn("Could not fully initialize the AnimationsController");
return; return;
@ -176,6 +183,9 @@ var AnimationsController = {
yield this.destroyAnimationPlayers(); yield this.destroyAnimationPlayers();
this.nodeFront = null; this.nodeFront = null;
// Finish releasing players that haven't been released yet.
yield Promise.all(this.nonBlockingPlayerReleases);
if (this.animationsFront) { if (this.animationsFront) {
this.animationsFront.destroy(); this.animationsFront.destroy();
this.animationsFront = null; this.animationsFront = null;
@ -331,7 +341,7 @@ var AnimationsController = {
} }
}), }),
onAnimationMutations: Task.async(function*(changes) { onAnimationMutations: function(changes) {
// Insert new players into this.animationPlayers when new animations are // Insert new players into this.animationPlayers when new animations are
// added. // added.
for (let {type, player} of changes) { for (let {type, player} of changes) {
@ -340,7 +350,8 @@ var AnimationsController = {
} }
if (type === "removed") { if (type === "removed") {
yield player.release(); // Don't wait for the release request to complete, we can do that later.
this.nonBlockingPlayerReleases.push(player.release());
let index = this.animationPlayers.indexOf(player); let index = this.animationPlayers.indexOf(player);
this.animationPlayers.splice(index, 1); this.animationPlayers.splice(index, 1);
} }
@ -348,7 +359,7 @@ var AnimationsController = {
// Let the UI know the list has been updated. // Let the UI know the list has been updated.
this.emit(this.PLAYERS_UPDATED_EVENT, this.animationPlayers); this.emit(this.PLAYERS_UPDATED_EVENT, this.animationPlayers);
}), },
/** /**
* Get the latest known current time of document.timeline. * Get the latest known current time of document.timeline.