69 lines
1.9 KiB
JavaScript
69 lines
1.9 KiB
JavaScript
|
function SyncChannel() {
|
||
|
this.writers = [];
|
||
|
this.readers = [];
|
||
|
this.syncing = false;
|
||
|
}
|
||
|
|
||
|
SyncChannel.prototype.tryRead = function () {
|
||
|
if (this.writers.length > 0) {
|
||
|
var writer = this.writers.shift();
|
||
|
writer.continuation();
|
||
|
return { value: writer.value };
|
||
|
} else {
|
||
|
return null;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
SyncChannel.prototype.tryWrite = function (value) {
|
||
|
if (this.readers.length > 0) {
|
||
|
var reader = this.readers.shift();
|
||
|
reader.continuation(value);
|
||
|
return true;
|
||
|
} else {
|
||
|
return false;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
SyncChannel.prototype.read = function (continuation) {
|
||
|
var channel = this;
|
||
|
var reader = { continuation: continuation };
|
||
|
channel.readers.push(reader);
|
||
|
if (!channel.syncing) channel.sync();
|
||
|
return function cancel() {
|
||
|
var index = channel.readers.indexOf(reader);
|
||
|
channel.readers.splice(index, 1);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
SyncChannel.prototype.write = function (value, continuation) {
|
||
|
continuation = continuation || function () { };
|
||
|
var channel = this;
|
||
|
var writer = { continuation: continuation, value: value };
|
||
|
channel.writers.push(writer);
|
||
|
if (!channel.syncing) channel.sync();
|
||
|
return function cancel() {
|
||
|
var index = channel.writers.indexOf(writer);
|
||
|
channel.writers.splice(index, 1);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
SyncChannel.prototype.sync = function () {
|
||
|
var channel = this;
|
||
|
channel.syncing = true;
|
||
|
(function loop() {
|
||
|
setImmediate(function () {
|
||
|
if (channel.readers.length > 0 && channel.writers.length > 0) {
|
||
|
var reader = channel.readers.shift();
|
||
|
var writer = channel.writers.shift();
|
||
|
reader.continuation(writer.value);
|
||
|
writer.continuation();
|
||
|
loop();
|
||
|
} else {
|
||
|
channel.syncing = false;
|
||
|
}
|
||
|
});
|
||
|
})();
|
||
|
};
|
||
|
|
||
|
module.exports = SyncChannel;
|