@ai-ecoverse/slicc-kernel 1.53.3 → 1.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/dist/index.js +76 -2
- package/dist/index.js.map +4 -4
- package/dist/kernel-worker.js +133 -11
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node.js +199 -12
- package/dist/node.js.map +3 -3
- package/package.json +2 -2
package/dist/kernel-worker.js
CHANGED
|
@@ -10614,9 +10614,11 @@ var JobTable = class {
|
|
|
10614
10614
|
const member = this.member(pid);
|
|
10615
10615
|
const id2 = this.idOf(pid);
|
|
10616
10616
|
if (member.pgid === id2) throw new KernelError("EPERM");
|
|
10617
|
+
const left = member.pgid;
|
|
10617
10618
|
member.sid = id2;
|
|
10618
10619
|
member.pgid = id2;
|
|
10619
10620
|
this.terminals.delete(id2);
|
|
10621
|
+
this.prune(left);
|
|
10620
10622
|
return id2;
|
|
10621
10623
|
}
|
|
10622
10624
|
terminalNamed(name2) {
|
|
@@ -10660,18 +10662,18 @@ var JobTable = class {
|
|
|
10660
10662
|
const inSession = [...this.members.values()].some((m) => m.pgid === pgid && m.sid === self.sid);
|
|
10661
10663
|
if (!inSession) throw new KernelError("EPERM");
|
|
10662
10664
|
const current = this.foreground.get(tty);
|
|
10663
|
-
if (settling && pgid === self.pgid && current !== pgid && this.reclaimed(pgid,
|
|
10664
|
-
|
|
10665
|
-
if (pgid !== self.pgid) this.handoffs.set(pgid, { by
|
|
10665
|
+
if (settling && pgid === self.pgid && current !== pgid && this.reclaimed(pgid, caller)) return;
|
|
10666
|
+
const by = this.shown(caller);
|
|
10667
|
+
if (pgid !== self.pgid) this.handoffs.set(pgid, { by, reclaimed: false });
|
|
10666
10668
|
else if (current !== void 0) {
|
|
10667
10669
|
const handoff = this.handoffs.get(current);
|
|
10668
|
-
if (handoff?.by ===
|
|
10670
|
+
if (handoff?.by === by) handoff.reclaimed = true;
|
|
10669
10671
|
}
|
|
10670
10672
|
this.foreground.set(tty, pgid);
|
|
10671
10673
|
}
|
|
10672
|
-
reclaimed(pgid,
|
|
10674
|
+
reclaimed(pgid, caller) {
|
|
10673
10675
|
const handoff = this.handoffs.get(pgid);
|
|
10674
|
-
return handoff?.reclaimed === true && handoff.by ===
|
|
10676
|
+
return handoff?.reclaimed === true && handoff.by === this.shownParent(caller);
|
|
10675
10677
|
}
|
|
10676
10678
|
signalOwnedForeground(tty, sig) {
|
|
10677
10679
|
const pgid = this.foreground.get(tty);
|
|
@@ -11399,7 +11401,7 @@ function hostfsHandlers(current) {
|
|
|
11399
11401
|
const handles = /* @__PURE__ */ new Map();
|
|
11400
11402
|
let nextFh = 0;
|
|
11401
11403
|
const fresh = (remote) => {
|
|
11402
|
-
if (remote.client.token === remote.token) return remote;
|
|
11404
|
+
if (remote.client.token === remote.token && !remote.client.gone) return remote;
|
|
11403
11405
|
throw fsError2("ESTALE", "the folder was granted again, so this open file is gone");
|
|
11404
11406
|
};
|
|
11405
11407
|
const live = (fh) => {
|
|
@@ -11604,10 +11606,126 @@ function keepWatching(loop, signal) {
|
|
|
11604
11606
|
function invalidation(event) {
|
|
11605
11607
|
return event.paths ?? true;
|
|
11606
11608
|
}
|
|
11607
|
-
|
|
11609
|
+
var PORT_REQUEST_MS = 6e4;
|
|
11610
|
+
var PORT_MS_PER_MIB = 1e3;
|
|
11611
|
+
var nextPortToken = 0;
|
|
11612
|
+
var PortTransport = class {
|
|
11613
|
+
capabilities;
|
|
11614
|
+
token;
|
|
11615
|
+
port;
|
|
11616
|
+
requestMs;
|
|
11617
|
+
waiting = /* @__PURE__ */ new Map();
|
|
11618
|
+
next = 0;
|
|
11619
|
+
dead;
|
|
11620
|
+
constructor(grant, requestMs = PORT_REQUEST_MS) {
|
|
11621
|
+
this.port = grant.port;
|
|
11622
|
+
this.requestMs = requestMs;
|
|
11623
|
+
this.capabilities = grant.capabilities ?? {};
|
|
11624
|
+
this.token = grant.token ?? `port-${++nextPortToken}`;
|
|
11625
|
+
this.port.addEventListener("message", (event) => {
|
|
11626
|
+
this.waiting.get(event.data?.id)?.(event.data);
|
|
11627
|
+
});
|
|
11628
|
+
this.port.addEventListener("close", () => this.fail("the folder's port closed"));
|
|
11629
|
+
this.port.start();
|
|
11630
|
+
}
|
|
11631
|
+
get maxIo() {
|
|
11632
|
+
return this.capabilities.maxIo ?? HOSTFS_IO;
|
|
11633
|
+
}
|
|
11634
|
+
get gone() {
|
|
11635
|
+
return this.dead !== void 0;
|
|
11636
|
+
}
|
|
11637
|
+
fail(why) {
|
|
11638
|
+
if (this.dead === void 0) this.port.close();
|
|
11639
|
+
this.dead ??= why;
|
|
11640
|
+
for (const settle3 of [...this.waiting.values()])
|
|
11641
|
+
settle3({ id: 0, error: { code: "ENOTCONN", message: why } });
|
|
11642
|
+
}
|
|
11643
|
+
ask(message3, bytes = 0, transfer = []) {
|
|
11644
|
+
const id2 = ++this.next;
|
|
11645
|
+
if (this.dead) return Promise.reject(fsError2("ENOTCONN", this.dead));
|
|
11646
|
+
return new Promise((resolve, reject) => {
|
|
11647
|
+
const timer = setTimeout(
|
|
11648
|
+
() => {
|
|
11649
|
+
this.waiting.delete(id2);
|
|
11650
|
+
reject(fsError2("ETIMEDOUT", "the folder's port did not answer"));
|
|
11651
|
+
this.fail("the folder's port stopped answering");
|
|
11652
|
+
},
|
|
11653
|
+
this.requestMs + Math.ceil(bytes / 1048576) * PORT_MS_PER_MIB
|
|
11654
|
+
);
|
|
11655
|
+
this.waiting.set(id2, (reply) => {
|
|
11656
|
+
clearTimeout(timer);
|
|
11657
|
+
this.waiting.delete(id2);
|
|
11658
|
+
if (reply.error) reject(fsError2(reply.error.code ?? "EIO", reply.error.message ?? ""));
|
|
11659
|
+
else resolve(reply);
|
|
11660
|
+
});
|
|
11661
|
+
try {
|
|
11662
|
+
this.port.postMessage({ id: id2, ...message3 }, transfer);
|
|
11663
|
+
} catch (err) {
|
|
11664
|
+
this.fail(`the folder's port is closed: ${err.message}`);
|
|
11665
|
+
}
|
|
11666
|
+
});
|
|
11667
|
+
}
|
|
11668
|
+
async call(op, body = {}) {
|
|
11669
|
+
return (await this.ask({ op: "call", name: op, body })).result;
|
|
11670
|
+
}
|
|
11671
|
+
async read(fh, offset, size, ifMatch) {
|
|
11672
|
+
const reply = await this.ask(
|
|
11673
|
+
{ op: "read", fh, offset, size, ...ifMatch ? { ifMatch } : {} },
|
|
11674
|
+
size
|
|
11675
|
+
);
|
|
11676
|
+
return reply.bytes ?? new Uint8Array(0);
|
|
11677
|
+
}
|
|
11678
|
+
async write(fh, offset, bytes) {
|
|
11679
|
+
await this.ask({ op: "write", fh, offset, bytes }, bytes.length);
|
|
11680
|
+
}
|
|
11681
|
+
watch(signal, onEvent, onOpen = () => void 0) {
|
|
11682
|
+
const id2 = ++this.next;
|
|
11683
|
+
if (this.dead) return Promise.reject(fsError2("ENOTCONN", this.dead));
|
|
11684
|
+
if (signal.aborted) {
|
|
11685
|
+
this.fail("the folder's watch ended");
|
|
11686
|
+
return Promise.resolve();
|
|
11687
|
+
}
|
|
11688
|
+
return new Promise((resolve, reject) => {
|
|
11689
|
+
const finish = () => {
|
|
11690
|
+
this.waiting.delete(id2);
|
|
11691
|
+
signal.removeEventListener("abort", stop);
|
|
11692
|
+
};
|
|
11693
|
+
const stop = () => {
|
|
11694
|
+
finish();
|
|
11695
|
+
try {
|
|
11696
|
+
this.port.postMessage({ id: id2, op: "unwatch" });
|
|
11697
|
+
} catch {
|
|
11698
|
+
}
|
|
11699
|
+
resolve();
|
|
11700
|
+
};
|
|
11701
|
+
this.waiting.set(id2, (reply) => {
|
|
11702
|
+
if (reply.open) return onOpen();
|
|
11703
|
+
if (reply.event) return onEvent(reply.event);
|
|
11704
|
+
finish();
|
|
11705
|
+
if (reply.error) reject(fsError2(reply.error.code ?? "ENOTCONN", reply.error.message ?? ""));
|
|
11706
|
+
else resolve();
|
|
11707
|
+
});
|
|
11708
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
11709
|
+
try {
|
|
11710
|
+
this.port.postMessage({ id: id2, op: "watch" });
|
|
11711
|
+
} catch (err) {
|
|
11712
|
+
finish();
|
|
11713
|
+
reject(fsError2("ENOTCONN", `the folder's port is closed: ${err.message}`));
|
|
11714
|
+
}
|
|
11715
|
+
}).finally(() => this.fail("the folder's watch ended"));
|
|
11716
|
+
}
|
|
11717
|
+
};
|
|
11718
|
+
function grantConnect(hook, fetch2, requestMs) {
|
|
11608
11719
|
return async (source, options) => {
|
|
11609
|
-
const
|
|
11610
|
-
return new
|
|
11720
|
+
const first = await hook(source, options);
|
|
11721
|
+
if ("port" in first) return new PortTransport(first, requestMs);
|
|
11722
|
+
const grant = async () => {
|
|
11723
|
+
const again = await hook(source, options);
|
|
11724
|
+
if ("port" in again)
|
|
11725
|
+
throw fsError2("ESTALE", "the folder moved to a port, so its open files are gone");
|
|
11726
|
+
return again;
|
|
11727
|
+
};
|
|
11728
|
+
return new HostfsClient(first, grant, fetch2);
|
|
11611
11729
|
};
|
|
11612
11730
|
}
|
|
11613
11731
|
async function openHostfs(spec, connect, timing = {}) {
|
|
@@ -12653,7 +12771,11 @@ var Launcher = class {
|
|
|
12653
12771
|
throw fsError("ENODEV", "this kernel has no hostfs hook (createKernel({ hostfs }))");
|
|
12654
12772
|
return openHostfs(
|
|
12655
12773
|
spec,
|
|
12656
|
-
grantConnect(
|
|
12774
|
+
grantConnect(
|
|
12775
|
+
hostfs,
|
|
12776
|
+
hostfsFetch ?? ((url, init) => fetch(url, init)),
|
|
12777
|
+
hostfsTiming?.requestMs
|
|
12778
|
+
),
|
|
12657
12779
|
hostfsTiming
|
|
12658
12780
|
);
|
|
12659
12781
|
}
|