Flush accumulated patch at least once per turn, rather than only when pid or action-type changes

This commit is contained in:
Tony Garnock-Jones 2016-08-07 21:42:40 -04:00
parent 747e96714d
commit 5dc1d99a3b
1 changed files with 19 additions and 5 deletions

View File

@ -31,6 +31,7 @@ function terminateDataspace() {
/* Dataspace */ /* Dataspace */
function Dataspace(bootFn) { function Dataspace(bootFn) {
this.pendingPatch = null; // null or [pid, Patch]
this.pendingActions = Immutable.List(); // of [pid, Action] this.pendingActions = Immutable.List(); // of [pid, Action]
this.processTable = Immutable.Map(); // pid -> Behavior this.processTable = Immutable.Map(); // pid -> Behavior
this.runnablePids = Immutable.Set(); // of pid this.runnablePids = Immutable.Set(); // of pid
@ -142,7 +143,7 @@ Dataspace.prototype.asChild = function (pid, f, omitLivenessCheck) {
return; return;
} }
return Dataspace.withDataspaceStack( var result = Dataspace.withDataspaceStack(
Dataspace.stack.push({ dataspace: this, activePid: pid }), Dataspace.stack.push({ dataspace: this, activePid: pid }),
function () { function () {
try { try {
@ -151,6 +152,8 @@ Dataspace.prototype.asChild = function (pid, f, omitLivenessCheck) {
self.kill(pid, e); self.kill(pid, e);
} }
}); });
self.flushPendingPatch();
return result;
}; };
Dataspace.prototype.kill = function (pid, exn) { Dataspace.prototype.kill = function (pid, exn) {
@ -202,16 +205,27 @@ Dataspace.prototype.step = function () {
&& ((this.pendingActions.size > 0) || (this.runnablePids.size > 0)); && ((this.pendingActions.size > 0) || (this.runnablePids.size > 0));
}; };
Dataspace.prototype.flushPendingPatch = function () {
if (this.pendingPatch) {
this.pendingActions = this.pendingActions.push([this.pendingPatch[0],
stateChange(this.pendingPatch[1])]);
this.pendingPatch = null;
}
};
Dataspace.prototype.enqueueAction = function (pid, action) { Dataspace.prototype.enqueueAction = function (pid, action) {
if (action.type === 'stateChange') { if (action.type === 'stateChange') {
var newestEntry = this.pendingActions.last(); if (!this.pendingPatch) {
if (newestEntry && newestEntry[0] === pid && newestEntry[1].type === 'stateChange') { this.pendingPatch = [pid, action.patch];
var combinedPatch = newestEntry[1].patch.andThen(action.patch); return;
this.pendingActions = this.pendingActions.pop().push([pid, stateChange(combinedPatch)]); }
if (this.pendingPatch[0] === pid) {
this.pendingPatch[1] = this.pendingPatch[1].andThen(action.patch);
return; return;
} }
/* fall through */ /* fall through */
} }
this.flushPendingPatch();
this.pendingActions = this.pendingActions.push([pid, action]); this.pendingActions = this.pendingActions.push([pid, action]);
}; };