- From: James Browning <notifications@github.com>
- Date: Sat, 27 Feb 2021 18:32:59 -0800
- To: whatwg/dom <dom@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/dom/issues/948/787222182@github.com>
Just to clarify how I'd imagine this working, if `AbortSignal` were implemented in pure js I would imagine doing something like this.
I've added an explicit `synchronizeAborted` method to this example, rather than having `.aborted` do this implictly (previously I was thinking `.aborted` getter would trigger `.synchronizationSteps()`, but it adds work for code paths that don't need it).
```js
// Structured serialize steps
function serializeAbortSignal(abortSignal) {
if (abortSignal.aborted) {
return { type: "AbortSignal", aborted: true };
} else {
const messageChannel = new MessageChannel();
abortSignal.addEventListener("abort", () => {
// Update so aborted can be observed synchronously
Atomics.store(sharedAbort, 0, 1));
// And send it in case it's listening asynchronously
messageChannel.port1.postMessage("aborted");
messageChannel.port1.close();
});
const sharedAborted = new Uint8Array(new SharedArrayBuffer(1));
return {
type: "AbortSignal",
aborted: false,
abortPort: messageChannel.port2,
sharedAborted,
};
}
}
// Structured deserialize steps
function deserializeAbortSignal(serializedAbortSignal) {
const abortSignal = new AbortSignal();
if (serializedAbortSignal.aborted) {
abortSignal.[[aborted]] = true;
return abortSignal;
}
const { abortPort, sharedAborted } = serializedAbortSignal;
// When a request to synchronize abort state with the main thread
// happens we need to potentially fire "abort", and return
abortSignal.[[synchronizeSteps]] = () => {
if (Atomics.load(sharedAborted, 0)) { // If aborted is set
// Set the aborted flag synchronously
abortSignal.[[aborted]] = true;
// Fire the abort event and run any handlers synchronously
abortSignal.dispatchEvent(new Event("abort"));
}
};
}
class AbortSignal extends EventTarget {
[[aborted]] = false;
[[synchronizeSteps]] = () => void;
get aborted() {
return this.[[aborted]];
}
// This asks the abort signal to synchronize with the other thread
// by default the synchronize steps are to do nothing, this is the
// case today and would remain the case when the abort signal does
// not come from another thread
synchronizeAborted() {
if (this.[[aborted]]) {
return true;
}
this.[[synchronizeSteps]]();
return this.[[aborted]];
}
}
```
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/dom/issues/948#issuecomment-787222182
Received on Sunday, 28 February 2021 02:33:12 UTC