@ai-ecoverse/slicc-kernel 1.120.0 → 1.120.2

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.
@@ -874,6 +874,14 @@ var RemoteWatch = class {
874
874
  met;
875
875
  settled = false;
876
876
  quiet;
877
+ crowd;
878
+ told;
879
+ recount() {
880
+ const now = this.crowded();
881
+ if (now === this.told) return;
882
+ this.told = now;
883
+ this.crowd?.(now);
884
+ }
877
885
  constructor(name2, options = {}) {
878
886
  this.name = name2;
879
887
  this.locks = options.locks === void 0 ? lockManager() : options.locks ?? void 0;
@@ -890,6 +898,7 @@ var RemoteWatch = class {
890
898
  });
891
899
  this.joined = granted2.then(() => this.join()).then(() => {
892
900
  this.settled = true;
901
+ this.recount();
893
902
  });
894
903
  this.channel.postMessage({ hello: this.tab });
895
904
  }
@@ -922,6 +931,7 @@ var RemoteWatch = class {
922
931
  if (data.hello !== void 0) this.greeted(data.hello);
923
932
  if (data.here !== void 0 && data.to === this.tab) {
924
933
  this.peers.add(data.here);
934
+ this.recount();
925
935
  this.met?.();
926
936
  }
927
937
  if (data.tab !== void 0 && data.paths !== void 0) this.announced(data);
@@ -932,6 +942,7 @@ var RemoteWatch = class {
932
942
  }
933
943
  greeted(peer) {
934
944
  this.peers.add(peer);
945
+ this.recount();
935
946
  const answer = () => {
936
947
  this.channel.postMessage({ here: this.tab, to: peer });
937
948
  if (this.mine.length > 0) void this.announce(this.mine);
@@ -942,6 +953,7 @@ var RemoteWatch = class {
942
953
  announced({ tab, paths, seq: seq2 }) {
943
954
  const from = tab;
944
955
  this.peers.add(from);
956
+ this.recount();
945
957
  if (paths.length > 0) this.others.set(from, paths);
946
958
  else this.others.delete(from);
947
959
  this.rebuild();
@@ -967,6 +979,7 @@ var RemoteWatch = class {
967
979
  }
968
980
  }
969
981
  this.rebuild();
982
+ this.recount();
970
983
  }
971
984
  watched() {
972
985
  return this.union.size > 0;
@@ -1199,7 +1212,7 @@ var OpfsFs = class {
1199
1212
  this.rootName = channel;
1200
1213
  this.channel = channel === void 0 ? void 0 : new BroadcastChannel(channel);
1201
1214
  this.remote = channel === void 0 ? void 0 : new RemoteWatch(`${channel}:watch`);
1202
- if (this.remote) this.remote.quiet = () => this.quiet();
1215
+ if (this.remote) this.remote.quiet = () => this.quiet().then(() => this.settle?.());
1203
1216
  if (this.channel) {
1204
1217
  const remote = this.remote;
1205
1218
  meta.listen?.(
@@ -1354,6 +1367,22 @@ var OpfsFs = class {
1354
1367
  if (this.unlocked === 0) for (const done4 of this.idle.splice(0)) done4();
1355
1368
  }
1356
1369
  }
1370
+ settle;
1371
+ onPeer(settle3) {
1372
+ this.settle = settle3;
1373
+ }
1374
+ peers() {
1375
+ const remote = this.remote;
1376
+ if (!remote) return void 0;
1377
+ return {
1378
+ joined: () => remote.peered(),
1379
+ crowded: () => remote.crowded(),
1380
+ watch: (listener) => {
1381
+ remote.crowd = listener;
1382
+ listener(remote.crowded());
1383
+ }
1384
+ };
1385
+ }
1357
1386
  quiet() {
1358
1387
  if (this.unlocked === 0) return Promise.resolve();
1359
1388
  return new Promise((resolve2) => this.idle.push(resolve2));
@@ -6376,7 +6405,7 @@ function satisfies(version, range2) {
6376
6405
  }
6377
6406
 
6378
6407
  // src/version.ts
6379
- var KERNEL_VERSION = true ? "1.120.0" : "0.0.0-dev";
6408
+ var KERNEL_VERSION = true ? "1.120.2" : "0.0.0-dev";
6380
6409
  var OS_RELEASE = "6.0.0-slicc";
6381
6410
  function procVersion() {
6382
6411
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -8654,7 +8683,8 @@ var RING = 1;
8654
8683
  var RING_SIZE = 4096;
8655
8684
  var SLOT = 2;
8656
8685
  var DIRTY = RING + RING_SIZE * SLOT;
8657
- var CHANGES_BYTES = (DIRTY + 1) * 4;
8686
+ var FOREIGN = DIRTY + 1;
8687
+ var CHANGES_BYTES = (FOREIGN + 1) * 4;
8658
8688
  function changeHash(path) {
8659
8689
  let h = 2166136261;
8660
8690
  for (let i = 0; i < path.length; i++) {
@@ -8682,6 +8712,9 @@ var FileChanges = class {
8682
8712
  dirtied(delta) {
8683
8713
  Atomics.add(this.view, DIRTY, delta);
8684
8714
  }
8715
+ foreign(on) {
8716
+ Atomics.store(this.view, FOREIGN, on ? 1 : 0);
8717
+ }
8685
8718
  publish(...paths) {
8686
8719
  for (const path of paths) {
8687
8720
  const g = Atomics.add(this.view, GEN, 1) + 1 | 0;
@@ -13643,10 +13676,14 @@ async function flock(req, ctx) {
13643
13676
  if (!locks || !flockOf) throw new KernelError("ENOLCK");
13644
13677
  if (!FLOCK_KINDS.has(req.kind)) throw new KernelError("EINVAL");
13645
13678
  const { key, owner } = await flockOf(req.fd);
13679
+ const granted2 = req.kind !== "unlock";
13680
+ const shared = locks.shared?.() === true;
13681
+ if (shared && !granted2) await ctx.settle?.(req.fd, false);
13646
13682
  if (req.kind !== "unlock" && req.wait)
13647
13683
  await locks.flocks.wait(key, owner, req.kind, ctx.blocking);
13648
13684
  else if (!await locks.flocks.set(key, owner, req.kind)) throw new KernelError("EAGAIN");
13649
- return done2;
13685
+ if (shared && granted2) await ctx.settle?.(req.fd, true);
13686
+ return shared ? json3(true) : done2;
13650
13687
  }
13651
13688
  async function recordLock2(req, ctx) {
13652
13689
  const { locks, fileKey } = ctx;
@@ -13657,6 +13694,7 @@ async function recordLock2(req, ctx) {
13657
13694
  ...req.fd !== void 0 ? { fd: req.fd } : {}
13658
13695
  };
13659
13696
  if (req.op === "lk-close") {
13697
+ if (req.fd !== void 0 && locks.shared?.()) await ctx.settle?.(req.fd, false);
13660
13698
  locks.dropFile(await fileKey(target, "close"), owner);
13661
13699
  return done2;
13662
13700
  }
@@ -13668,13 +13706,16 @@ async function recordLock2(req, ctx) {
13668
13706
  const len = held.end === Number.POSITIVE_INFINITY ? 0 : held.end - held.start;
13669
13707
  return json3({ kind: held.kind, pid: held.owner, start: held.start, len });
13670
13708
  }
13671
- if (req.kind !== "unlock" && req.wait) {
13709
+ const granted2 = req.kind !== "unlock";
13710
+ const shared = locks.shared?.() === true;
13711
+ const fd = shared ? req.fd : void 0;
13712
+ if (!granted2 && fd !== void 0) await ctx.settle?.(fd, false);
13713
+ if (req.kind !== "unlock" && req.wait)
13672
13714
  await locks.wait(key, owner, req.kind, range2, ctx.blocking);
13673
- return done2;
13674
- }
13675
- if (!await locks.set(key, owner, req.kind, range2.start, range2.end))
13715
+ else if (!await locks.set(key, owner, req.kind, range2.start, range2.end))
13676
13716
  throw new KernelError("EAGAIN");
13677
- return done2;
13717
+ if (granted2 && fd !== void 0) await ctx.settle?.(fd, true);
13718
+ return shared ? json3(true) : done2;
13678
13719
  }
13679
13720
 
13680
13721
  // src/kernel/net/loopback-transport.ts
@@ -16984,6 +17025,11 @@ var VfsNode = class {
16984
17025
  holds() {
16985
17026
  return this.dirty;
16986
17027
  }
17028
+ reread() {
17029
+ if (this.dirty || this.orphaned || this.pin || this.revoked) return;
17030
+ this.data = void 0;
17031
+ this.ranged = void 0;
17032
+ }
16987
17033
  replace(contents2) {
16988
17034
  this.ranged = void 0;
16989
17035
  this.data = new Uint8Array(contents2);
@@ -17611,6 +17657,7 @@ function vfsFile(fs, opts, nodes) {
17611
17657
  })),
17612
17658
  known: () => node.known(),
17613
17659
  flush: () => serial(() => node.flush()),
17660
+ reread: () => serial(async () => node.reread()),
17614
17661
  close: () => node.serial(async () => {
17615
17662
  try {
17616
17663
  takeOpenError();
@@ -18093,6 +18140,7 @@ var WasmProcess = class {
18093
18140
  owner: () => this.lockOwner(),
18094
18141
  fileKey: (target, kind, setting) => this.lockKey(target, kind, setting),
18095
18142
  flockOf: (fd) => this.flockOf(fd),
18143
+ settle: (fd, granted2) => this.settle(fd, granted2),
18096
18144
  locks: this.options.locks,
18097
18145
  ops: this.asyncOps,
18098
18146
  blocking: () => this.blockingSignal(cancelled),
@@ -18176,6 +18224,11 @@ var WasmProcess = class {
18176
18224
  else if (this.pathKeys.size < 4096) this.pathKeys.set(path, key);
18177
18225
  return key;
18178
18226
  }
18227
+ async settle(fd, granted2) {
18228
+ const file = this.fds.has(fd) ? this.fds.get(fd).file : void 0;
18229
+ if (granted2) await file?.reread?.();
18230
+ else await file?.flush?.();
18231
+ }
18179
18232
  async flockOf(fd) {
18180
18233
  const open = this.fds.get(fd);
18181
18234
  const { locks } = this.options;
@@ -19861,13 +19914,20 @@ var LockService = class {
19861
19914
  };
19862
19915
  void this.locks.request(this.aliveOf(this.kernel), () => new Promise(() => {
19863
19916
  }));
19864
- this.role = this.elect();
19917
+ const peers = options.peers;
19918
+ this.role = peers ? Promise.all([this.elect(), peers.joined()]).then(() => void 0) : this.elect();
19919
+ this.peers = options.peers;
19865
19920
  this.flocks = {
19866
19921
  set: (key, owner, kind) => this.flockSet(key, owner, kind),
19867
19922
  wait: (key, owner, kind, blocking) => this.flockWait(key, owner, kind, blocking),
19868
19923
  drop: (owner) => this.flockDrop(owner)
19869
19924
  };
19870
19925
  }
19926
+ peers;
19927
+ shared() {
19928
+ if (!this.leader || this.ownerOf.size > 0 || this.tokens.size > 0) return true;
19929
+ return this.peers?.crowded() === true;
19930
+ }
19871
19931
  aliveOf(kernel) {
19872
19932
  return `slicc-locks-alive:${LOCKS_PROTOCOL}:${this.root}:${kernel}`;
19873
19933
  }
@@ -20128,11 +20188,11 @@ var LockService = class {
20128
20188
  this.table.closed(pid, fd);
20129
20189
  }
20130
20190
  };
20131
- function kernelLocks(root) {
20191
+ function kernelLocks(root, peers) {
20132
20192
  const locks = globalThis.navigator?.locks;
20133
20193
  if (root === void 0 || !locks || typeof BroadcastChannel !== "function")
20134
20194
  return new LockTable();
20135
- return new LockService({ root, locks });
20195
+ return new LockService({ root, locks, ...peers ? { peers } : {} });
20136
20196
  }
20137
20197
  var ASK_OPS = /* @__PURE__ */ new Set([
20138
20198
  "set",
@@ -23520,7 +23580,9 @@ var Launcher = class {
23520
23580
  constructor(options) {
23521
23581
  this.usersMode = usersMode(options.users);
23522
23582
  this.rootFs = options.fs;
23523
- this.locks = kernelLocks(options.fs.rootName);
23583
+ const peers = options.fs.peers?.();
23584
+ this.locks = kernelLocks(options.fs.rootName, peers);
23585
+ peers?.watch((crowded) => this.changes.foreign(crowded));
23524
23586
  this.dac = this.usersMode === "off" ? void 0 : new Dac(this.usersMode, options.onDenial);
23525
23587
  if (this.dac) this.dac.tagOf = (pid) => this.tagOf(pid);
23526
23588
  this.clipboard = new ClipboardBroker(
@@ -23601,6 +23663,7 @@ var Launcher = class {
23601
23663
  this.nodes = new VfsNodes(fs, (path) => this.released(path));
23602
23664
  this.nodes.keepsOnDisk = true;
23603
23665
  this.openFiles.add(this.nodes);
23666
+ options.fs.onPeer?.(() => this.flushOpen());
23604
23667
  const holders = [this.held, this.openFiles];
23605
23668
  this.unlinked = new UnlinkedKeeper(
23606
23669
  fs,
@@ -25261,6 +25324,9 @@ var Launcher = class {
25261
25324
  this.writers ??= this.writerStack();
25262
25325
  return this.writers;
25263
25326
  }
25327
+ async flushOpen() {
25328
+ for (const nodes of this.openFiles) await nodes.flush("/").catch(() => void 0);
25329
+ }
25264
25330
  writerStack() {
25265
25331
  const mounted = this.mounts.wrap(this.unguardedRoot);
25266
25332
  const fs = this.commandFs(this.rooted(mounted));