@ai-ecoverse/slicc-kernel 1.116.2 → 1.117.1

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/dist/node.js CHANGED
@@ -931,7 +931,8 @@ function openPipe(capacity) {
931
931
  },
932
932
  close: () => pipe.closeRead(),
933
933
  poll: () => ({ readable: pipe.readReady, writable: false, hangup: pipe.writersGone }),
934
- changed: (signal) => pipe.changed(signal)
934
+ changed: (signal) => pipe.changed(signal),
935
+ identity: pipe
935
936
  }),
936
937
  write: new OpenFile({
937
938
  write: async (bytes, signal) => {
@@ -943,7 +944,8 @@ function openPipe(capacity) {
943
944
  },
944
945
  close: () => pipe.closeWrite(),
945
946
  poll: () => ({ readable: false, writable: pipe.writeReady, hangup: pipe.readersGone }),
946
- changed: (signal) => pipe.changed(signal)
947
+ changed: (signal) => pipe.changed(signal),
948
+ identity: pipe
947
949
  })
948
950
  };
949
951
  }
@@ -6576,7 +6578,7 @@ function satisfies(version, range2) {
6576
6578
  }
6577
6579
 
6578
6580
  // src/version.ts
6579
- var KERNEL_VERSION = true ? "1.116.2" : "0.0.0-dev";
6581
+ var KERNEL_VERSION = true ? "1.117.1" : "0.0.0-dev";
6580
6582
  var OS_RELEASE = "6.0.0-slicc";
6581
6583
  function procVersion() {
6582
6584
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -9720,6 +9722,7 @@ var FifoTable = class {
9720
9722
  let open = true;
9721
9723
  return new OpenFile({
9722
9724
  fifo: path,
9725
+ identity: fifo,
9723
9726
  ...reads ? {
9724
9727
  read: async (max, signal) => {
9725
9728
  try {
@@ -13153,7 +13156,71 @@ function lockRange(start2, len) {
13153
13156
  if (from < 0) throw new KernelError("EINVAL");
13154
13157
  return { start: from, end };
13155
13158
  }
13159
+ function changedAt(wakers, key, signal) {
13160
+ return new Promise((resolve2, reject) => {
13161
+ const set3 = wakers.get(key) ?? /* @__PURE__ */ new Set();
13162
+ wakers.set(key, set3);
13163
+ const done4 = () => {
13164
+ set3.delete(wake);
13165
+ if (set3.size === 0 && wakers.get(key) === set3) wakers.delete(key);
13166
+ signal.removeEventListener("abort", abort);
13167
+ };
13168
+ const wake = () => {
13169
+ done4();
13170
+ resolve2();
13171
+ };
13172
+ const abort = () => {
13173
+ done4();
13174
+ reject(new KernelError("EINTR"));
13175
+ };
13176
+ set3.add(wake);
13177
+ signal.addEventListener("abort", abort, { once: true });
13178
+ });
13179
+ }
13180
+ function wakeAt(wakers, key) {
13181
+ for (const wake of [...wakers.get(key) ?? []]) wake();
13182
+ }
13183
+ var FlockTable = class {
13184
+ held = /* @__PURE__ */ new Map();
13185
+ keys = /* @__PURE__ */ new WeakMap();
13186
+ wakers = /* @__PURE__ */ new Map();
13187
+ free(key, owner, kind) {
13188
+ for (const [other, has] of this.held.get(key) ?? [])
13189
+ if (other !== owner && (kind === "exclusive" || has === "exclusive")) return false;
13190
+ return true;
13191
+ }
13192
+ set(key, owner, kind) {
13193
+ const has = this.held.get(key)?.get(owner);
13194
+ if (has === kind) return true;
13195
+ if (has !== void 0) this.drop(owner);
13196
+ if (kind === "unlock") return true;
13197
+ if (!this.free(key, owner, kind)) return false;
13198
+ const holders = this.held.get(key) ?? /* @__PURE__ */ new Map();
13199
+ holders.set(owner, kind);
13200
+ this.held.set(key, holders);
13201
+ this.keys.set(owner, key);
13202
+ return true;
13203
+ }
13204
+ async wait(key, owner, kind, blocking) {
13205
+ if (this.set(key, owner, kind)) return;
13206
+ const signal = blocking();
13207
+ while (!this.set(key, owner, kind)) {
13208
+ if (signal.aborted) throw new KernelError("EINTR");
13209
+ await changedAt(this.wakers, key, signal);
13210
+ }
13211
+ }
13212
+ drop(owner) {
13213
+ const key = this.keys.get(owner);
13214
+ if (key === void 0) return;
13215
+ this.keys.delete(owner);
13216
+ const holders = this.held.get(key);
13217
+ holders?.delete(owner);
13218
+ if (holders?.size === 0) this.held.delete(key);
13219
+ wakeAt(this.wakers, key);
13220
+ }
13221
+ };
13156
13222
  var LockTable = class {
13223
+ flocks = new FlockTable();
13157
13224
  records = /* @__PURE__ */ new Map();
13158
13225
  blocked = /* @__PURE__ */ new Map();
13159
13226
  wakers = /* @__PURE__ */ new Map();
@@ -13211,28 +13278,10 @@ var LockTable = class {
13211
13278
  return false;
13212
13279
  }
13213
13280
  changed(key, signal) {
13214
- return new Promise((resolve2, reject) => {
13215
- const set3 = this.wakers.get(key) ?? /* @__PURE__ */ new Set();
13216
- this.wakers.set(key, set3);
13217
- const done4 = () => {
13218
- set3.delete(wake);
13219
- if (set3.size === 0 && this.wakers.get(key) === set3) this.wakers.delete(key);
13220
- signal.removeEventListener("abort", abort);
13221
- };
13222
- const wake = () => {
13223
- done4();
13224
- resolve2();
13225
- };
13226
- const abort = () => {
13227
- done4();
13228
- reject(new KernelError("EINTR"));
13229
- };
13230
- set3.add(wake);
13231
- signal.addEventListener("abort", abort, { once: true });
13232
- });
13281
+ return changedAt(this.wakers, key, signal);
13233
13282
  }
13234
13283
  wake(key) {
13235
- for (const wake of [...this.wakers.get(key) ?? []]) wake();
13284
+ wakeAt(this.wakers, key);
13236
13285
  }
13237
13286
  store(key, locks) {
13238
13287
  if (locks.length === 0) this.records.delete(key);
@@ -13297,6 +13346,7 @@ var HOST_OPS = [
13297
13346
  "lk-set",
13298
13347
  "lk-get",
13299
13348
  "lk-close",
13349
+ "flock",
13300
13350
  "async-submit",
13301
13351
  "async-wait",
13302
13352
  "async-take",
@@ -13449,6 +13499,8 @@ async function hostSyscall(req, ctx) {
13449
13499
  case "lk-get":
13450
13500
  case "lk-close":
13451
13501
  return recordLock2(req, ctx);
13502
+ case "flock":
13503
+ return flock(req, ctx);
13452
13504
  case "async-submit":
13453
13505
  if (!ctx.valid(req.req)) throw new KernelError("EINVAL");
13454
13506
  if (req.ack) ctx.ops.ack(req.ack);
@@ -13471,6 +13523,17 @@ async function hostSyscall(req, ctx) {
13471
13523
  return done2;
13472
13524
  }
13473
13525
  }
13526
+ var FLOCK_KINDS = /* @__PURE__ */ new Set(["shared", "exclusive", "unlock"]);
13527
+ async function flock(req, ctx) {
13528
+ const { locks, flockOf } = ctx;
13529
+ if (!locks || !flockOf) throw new KernelError("ENOLCK");
13530
+ if (!FLOCK_KINDS.has(req.kind)) throw new KernelError("EINVAL");
13531
+ const { key, owner } = await flockOf(req.fd);
13532
+ if (req.kind !== "unlock" && req.wait)
13533
+ await locks.flocks.wait(key, owner, req.kind, ctx.blocking);
13534
+ else if (!locks.flocks.set(key, owner, req.kind)) throw new KernelError("EAGAIN");
13535
+ return done2;
13536
+ }
13474
13537
  async function recordLock2(req, ctx) {
13475
13538
  const { locks, fileKey } = ctx;
13476
13539
  if (!locks || !fileKey) throw new KernelError("ENOLCK");
@@ -17441,6 +17504,18 @@ var fileKeys = /* @__PURE__ */ new WeakMap();
17441
17504
  function identityKey(st, path) {
17442
17505
  return st.ino === void 0 ? path : `${st.dev ?? 0}:${st.ino}`;
17443
17506
  }
17507
+ var objectIds = /* @__PURE__ */ new WeakMap();
17508
+ var nextObjectId = 1;
17509
+ function objectKey(file) {
17510
+ const at = file.tty ?? file.identity ?? file.pty ?? file;
17511
+ let id2 = objectIds.get(at);
17512
+ if (id2 === void 0) {
17513
+ id2 = nextObjectId++;
17514
+ objectIds.set(at, id2);
17515
+ }
17516
+ return `object:${id2}`;
17517
+ }
17518
+ var flockHooked = /* @__PURE__ */ new WeakSet();
17444
17519
  var DYING = { ok: false, errno: "EINTR", message: "the process is being killed" };
17445
17520
  var HOSTS_ONLY = new Resolver({ routes: new Routes() });
17446
17521
  function timeLeft(req, started) {
@@ -17741,6 +17816,7 @@ var WasmProcess = class {
17741
17816
  pid: this.pid,
17742
17817
  owner: () => this.lockOwner(),
17743
17818
  fileKey: (target, kind, setting) => this.lockKey(target, kind, setting),
17819
+ flockOf: (fd) => this.flockOf(fd),
17744
17820
  locks: this.options.locks,
17745
17821
  ops: this.asyncOps,
17746
17822
  blocking: () => this.blockingSignal(cancelled),
@@ -17809,6 +17885,7 @@ var WasmProcess = class {
17809
17885
  throw new KernelError("EBADF");
17810
17886
  const known = file ? fileKeys.get(file) : this.pathKeys.get(target.path ?? "");
17811
17887
  if (kind === "close" && !file && target.path !== void 0) this.pathKeys.delete(target.path);
17888
+ if (access2 && !access2.stat) return objectKey(access2);
17812
17889
  const want = kind === "read" ? R_OK : kind === "write" ? W_OK : 0;
17813
17890
  const path = await this.lockPath(target, want);
17814
17891
  if (known !== void 0) return known;
@@ -17823,6 +17900,33 @@ var WasmProcess = class {
17823
17900
  else if (this.pathKeys.size < 4096) this.pathKeys.set(path, key);
17824
17901
  return key;
17825
17902
  }
17903
+ async flockOf(fd) {
17904
+ const open = this.fds.get(fd);
17905
+ const { locks } = this.options;
17906
+ if (locks && !flockHooked.has(open)) {
17907
+ flockHooked.add(open);
17908
+ open.onClose(() => locks.flocks.drop(open));
17909
+ }
17910
+ return { key: await this.objectKeyOf(open), owner: open };
17911
+ }
17912
+ async objectKeyOf(open) {
17913
+ const { file } = open;
17914
+ const meta = file.heldMeta;
17915
+ if (meta && "device" in meta) return `device:${meta.device}`;
17916
+ if (meta && "dir" in meta) {
17917
+ const st2 = await this.options.fs.stat?.(meta.dir).catch(() => void 0);
17918
+ return st2 ? identityKey(st2, meta.dir) : objectKey(file);
17919
+ }
17920
+ const known = fileKeys.get(open);
17921
+ if (known !== void 0) return known;
17922
+ const vfs = await file.stat?.().catch(() => void 0);
17923
+ if (!vfs || vfs.orphan) return objectKey(file);
17924
+ const st = await this.options.fs.stat?.(vfs.path).catch(() => void 0);
17925
+ if (!st) return objectKey(file);
17926
+ const key = identityKey(st, vfs.path);
17927
+ fileKeys.set(open, key);
17928
+ return key;
17929
+ }
17826
17930
  async dropRecordLocks(fd) {
17827
17931
  const { locks } = this.options;
17828
17932
  const owner = this.options.jobs?.shown(this.pid) ?? this.pid;
@@ -20103,6 +20207,7 @@ function scrubbed(inner, scrubber, idleMs = SCRUB_IDLE_MS) {
20103
20207
  },
20104
20208
  changed,
20105
20209
  ...file.tty ? { tty: file.tty } : {},
20210
+ identity: file.identity ?? file,
20106
20211
  ...file.clipboard ? { clipboard: file.clipboard } : {},
20107
20212
  ...file.write ? {
20108
20213
  write: async (bytes, signal) => {