@ai-ecoverse/slicc-kernel 1.124.4 → 1.124.5

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.
@@ -1253,9 +1253,13 @@ var OpfsFs = class {
1253
1253
  if (this.remote) this.remote.quiet = () => this.quiet().then(() => this.settle?.());
1254
1254
  if (this.channel) {
1255
1255
  const remote = this.remote;
1256
- meta.listen?.(
1257
- (c) => remote?.emit({ paths: c.paths ?? [], trees: c.trees ?? [] })
1258
- );
1256
+ meta.listen?.((c) => {
1257
+ for (const path of [...c.paths ?? [], ...c.trees ?? []]) this.forget(path);
1258
+ remote?.emit({ paths: c.paths ?? [], trees: c.trees ?? [] });
1259
+ });
1260
+ remote?.listen((c) => {
1261
+ for (const path of [...c.paths, ...c.trees]) this.forget(path);
1262
+ });
1259
1263
  this.channel.onmessage = ({ data }) => {
1260
1264
  for (const path of data) this.forget(path);
1261
1265
  remote?.emit({ paths: data, trees: [] });
@@ -1416,9 +1420,13 @@ var OpfsFs = class {
1416
1420
  joined: () => remote.peered(),
1417
1421
  crowded: () => remote.crowded(),
1418
1422
  watch: (listener) => {
1419
- remote.crowd = listener;
1423
+ remote.crowd = (crowded) => {
1424
+ this.fresh();
1425
+ listener(crowded);
1426
+ };
1420
1427
  listener(remote.crowded());
1421
- }
1428
+ },
1429
+ fresh: () => this.fresh()
1422
1430
  };
1423
1431
  }
1424
1432
  quiet() {
@@ -1471,6 +1479,7 @@ var OpfsFs = class {
1471
1479
  async walk(parts2, from, start2) {
1472
1480
  let dir = start2;
1473
1481
  for (let at = from; at < parts2.length; at++) {
1482
+ this.calls++;
1474
1483
  dir = await dir.getDirectoryHandle(parts2[at]);
1475
1484
  this.dirs.set(`/${parts2.slice(0, at + 1).join("/")}`, dir);
1476
1485
  this.checked.set(dir, performance.now());
@@ -1499,11 +1508,29 @@ var OpfsFs = class {
1499
1508
  async current(path, dir) {
1500
1509
  if (dir === this.root) return path === "/";
1501
1510
  if (performance.now() - (this.checked.get(dir) ?? -CHECK_MS) < CHECK_MS) return true;
1511
+ this.calls++;
1502
1512
  const where = await this.root.resolve(dir).catch(() => null);
1503
1513
  if (where === null || `/${where.join("/")}` !== path) return false;
1504
1514
  this.checked.set(dir, performance.now());
1505
1515
  return true;
1506
1516
  }
1517
+ exact = 0;
1518
+ calls = 0;
1519
+ opfsCalls() {
1520
+ return this.calls;
1521
+ }
1522
+ fresh() {
1523
+ this.changes++;
1524
+ this.absent.clear();
1525
+ }
1526
+ async exactly(op) {
1527
+ this.exact++;
1528
+ try {
1529
+ return await op();
1530
+ } finally {
1531
+ this.exact--;
1532
+ }
1533
+ }
1507
1534
  forget(path) {
1508
1535
  this.changes++;
1509
1536
  this.dirs.deleteTree(path);
@@ -1538,6 +1565,7 @@ var OpfsFs = class {
1538
1565
  }
1539
1566
  }
1540
1567
  async child(parent, name2, kind) {
1568
+ this.calls++;
1541
1569
  return kind === "file" ? parent.getFileHandle(name2) : parent.getDirectoryHandle(name2);
1542
1570
  }
1543
1571
  async parent(path) {
@@ -1566,7 +1594,7 @@ var OpfsFs = class {
1566
1594
  const kept = this.dirs.get(path);
1567
1595
  if (kept && await this.current(path, kept)) return kept;
1568
1596
  const gone = this.absent.get(path);
1569
- if (gone !== void 0 && !this.shared() && performance.now() - gone < ABSENT_MS) {
1597
+ if (gone !== void 0 && this.exact === 0 && performance.now() - gone < ABSENT_MS) {
1570
1598
  throw translate({ name: "NotFoundError" }, path);
1571
1599
  }
1572
1600
  const seen = this.changes;
@@ -1727,6 +1755,7 @@ var OpfsFs = class {
1727
1755
  flushing = {};
1728
1756
  touch(now, ...dirs) {
1729
1757
  this.changes++;
1758
+ if (this.shared()) this.channel?.postMessage(dirs);
1730
1759
  for (const dir of dirs) {
1731
1760
  this.absent.deleteTree(dir);
1732
1761
  this.dirTimes.set(dir, now);
@@ -1758,7 +1787,7 @@ var OpfsFs = class {
1758
1787
  return this.remote?.crowded() === true;
1759
1788
  }
1760
1789
  glanced(handle) {
1761
- if (this.shared()) return void 0;
1790
+ if (this.exact > 0) return void 0;
1762
1791
  const seen = this.glances.get(handle);
1763
1792
  const fresh2 = seen && seen.changes === this.changes && performance.now() - seen.at < GLANCE_MS;
1764
1793
  return fresh2 ? seen.file : void 0;
@@ -1766,6 +1795,7 @@ var OpfsFs = class {
1766
1795
  async glance(handle) {
1767
1796
  const at = performance.now();
1768
1797
  const before = this.changes;
1798
+ this.calls++;
1769
1799
  const file = await handle.getFile();
1770
1800
  if (before === this.changes) this.glances.set(handle, { at, file, changes: before });
1771
1801
  else this.glances.delete(handle);
@@ -2051,7 +2081,7 @@ var OpfsFs = class {
2051
2081
  if (!options.recursive) return this.mkdirExcl(path, options.owner);
2052
2082
  let found;
2053
2083
  try {
2054
- found = await this.locate(path, true);
2084
+ found = await this.exactly(() => this.locate(path, true));
2055
2085
  } catch (err) {
2056
2086
  if (!missing2(err)) throw err;
2057
2087
  }
@@ -2124,6 +2154,7 @@ var OpfsFs = class {
2124
2154
  });
2125
2155
  }
2126
2156
  async handleExists(dir, name2) {
2157
+ this.calls++;
2127
2158
  try {
2128
2159
  await dir.getDirectoryHandle(name2);
2129
2160
  return true;
@@ -2178,7 +2209,7 @@ var OpfsFs = class {
2178
2209
  async link(from, to, follow2) {
2179
2210
  await (follow2 ? this.stat(from) : this.lstat(from));
2180
2211
  if (!(await this.stat(parentOf3(to))).isDirectory) throw fsError("ENOTDIR", to);
2181
- const taken = await this.lstat(to).then(
2212
+ const taken = await this.exactly(() => this.lstat(to)).then(
2182
2213
  () => true,
2183
2214
  (err) => {
2184
2215
  if (missing2(err)) return false;
@@ -2201,7 +2232,7 @@ var OpfsFs = class {
2201
2232
  async moveTo(source, parent, destination, to) {
2202
2233
  const sourceStat = await this.describe(source);
2203
2234
  if (sourceStat.isDirectory && within2(destination, source.path)) throw fsError("EINVAL", to);
2204
- const target = await this.locate(destination, false).catch((err) => {
2235
+ const target = await this.exactly(() => this.locate(destination, false)).catch((err) => {
2205
2236
  if (missing2(err)) return null;
2206
2237
  throw err;
2207
2238
  });
@@ -2320,7 +2351,7 @@ var OpfsFs = class {
2320
2351
  if (parent.handle?.kind !== "directory") throw fsError("ENOTDIR", path);
2321
2352
  const at = resolvePath(parent.path, baseOf(path));
2322
2353
  this.refuse(at);
2323
- if (await this.locate(at, false).then(
2354
+ if (await this.exactly(() => this.locate(at, false)).then(
2324
2355
  () => true,
2325
2356
  (err) => !missing2(err)
2326
2357
  )) {
@@ -6594,7 +6625,7 @@ function satisfies(version, range2) {
6594
6625
  }
6595
6626
 
6596
6627
  // src/version.ts
6597
- var KERNEL_VERSION = true ? "1.124.4" : "0.0.0-dev";
6628
+ var KERNEL_VERSION = true ? "1.124.5" : "0.0.0-dev";
6598
6629
  var OS_RELEASE = "6.0.0-slicc";
6599
6630
  function procVersion() {
6600
6631
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -12781,6 +12812,8 @@ var SYS_TREE = {
12781
12812
  slicc_shared_root: (listing) => `${listing.peers ?? 0}
12782
12813
  `,
12783
12814
  slicc_fs_calls: (listing) => `${listing.fsCalls ?? 0}
12815
+ `,
12816
+ slicc_opfs_calls: (listing) => `${listing.opfsCalls ?? 0}
12784
12817
  `
12785
12818
  }
12786
12819
  };
@@ -13952,9 +13985,13 @@ async function flock(req, ctx) {
13952
13985
  if (req.kind !== "unlock" && req.wait)
13953
13986
  await locks.flocks.wait(key, owner, req.kind, ctx.blocking);
13954
13987
  else if (!await locks.flocks.set(key, owner, req.kind)) throw new KernelError("EAGAIN");
13955
- if (shared && granted2) await ctx.settle?.(req.fd, true);
13988
+ if (shared && granted2) await grantedAcross(ctx, req.fd);
13956
13989
  return shared ? json3(true) : done2;
13957
13990
  }
13991
+ async function grantedAcross(ctx, fd) {
13992
+ ctx.locks?.fresh?.();
13993
+ if (fd !== void 0) await ctx.settle?.(fd, true);
13994
+ }
13958
13995
  async function recordLock2(req, ctx) {
13959
13996
  const { locks, fileKey } = ctx;
13960
13997
  if (!locks || !fileKey) throw new KernelError("ENOLCK");
@@ -13984,7 +14021,7 @@ async function recordLock2(req, ctx) {
13984
14021
  await locks.wait(key, owner, req.kind, range2, ctx.blocking);
13985
14022
  else if (!await locks.set(key, owner, req.kind, range2.start, range2.end))
13986
14023
  throw new KernelError("EAGAIN");
13987
- if (granted2 && fd !== void 0) await ctx.settle?.(fd, true);
14024
+ if (granted2 && shared) await grantedAcross(ctx, fd);
13988
14025
  return shared ? json3(true) : done2;
13989
14026
  }
13990
14027
 
@@ -20643,6 +20680,9 @@ var LockService = class {
20643
20680
  };
20644
20681
  }
20645
20682
  peers;
20683
+ fresh() {
20684
+ this.peers?.fresh?.();
20685
+ }
20646
20686
  shared() {
20647
20687
  if (!this.leader || this.ownerOf.size > 0 || this.tokens.size > 0) return true;
20648
20688
  return this.peers?.crowded() === true;
@@ -25375,7 +25415,8 @@ var Launcher = class {
25375
25415
  cpu: this.cpuTotal(),
25376
25416
  wasm: this.memories.count(),
25377
25417
  peers: Number(this.locks.shared?.() === true),
25378
- fsCalls: servedFsCalls()
25418
+ fsCalls: servedFsCalls(),
25419
+ opfsCalls: this.rootFs.opfsCalls?.() ?? 0
25379
25420
  }),
25380
25421
  sudo: (call, signal) => this.sudo(pid, call, signal),
25381
25422
  crontab: (call) => this.crontab(pid, call),