@ai-ecoverse/slicc-kernel 1.98.3 → 1.99.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 +56 -1
- package/dist/kernel-worker.js +240 -15
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +89 -18
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +240 -15
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +89 -18
- package/dist/process-worker.js.map +4 -4
- package/package.json +2 -2
package/dist/node.js
CHANGED
|
@@ -1038,6 +1038,7 @@ function kernelFdKind(file) {
|
|
|
1038
1038
|
}
|
|
1039
1039
|
var FdTable = class _FdTable {
|
|
1040
1040
|
static MAX_FDS = 1024;
|
|
1041
|
+
handles;
|
|
1041
1042
|
fds = /* @__PURE__ */ new Map();
|
|
1042
1043
|
cloexec = /* @__PURE__ */ new Set();
|
|
1043
1044
|
status = /* @__PURE__ */ new Map();
|
|
@@ -1134,6 +1135,7 @@ var FdTable = class _FdTable {
|
|
|
1134
1135
|
for (const [fd, file] of this.fds) child.fds.set(fd, file.retain());
|
|
1135
1136
|
for (const fd of this.cloexec) child.cloexec.add(fd);
|
|
1136
1137
|
for (const [fd, flags2] of this.status) child.status.set(fd, flags2);
|
|
1138
|
+
child.handles = this.handles?.fork();
|
|
1137
1139
|
return child;
|
|
1138
1140
|
}
|
|
1139
1141
|
async closeAll() {
|
|
@@ -1141,6 +1143,7 @@ var FdTable = class _FdTable {
|
|
|
1141
1143
|
this.fds.clear();
|
|
1142
1144
|
this.cloexec.clear();
|
|
1143
1145
|
this.status.clear();
|
|
1146
|
+
this.handles?.clear();
|
|
1144
1147
|
await Promise.allSettled(files.map((file) => Promise.resolve().then(() => file.release())));
|
|
1145
1148
|
}
|
|
1146
1149
|
};
|
|
@@ -11075,7 +11078,7 @@ var PATH_OPS = new Set(SYNC_FS_OPS);
|
|
|
11075
11078
|
var EARLY_WHOLE_FILE = 64 * 1024;
|
|
11076
11079
|
|
|
11077
11080
|
// src/version.ts
|
|
11078
|
-
var KERNEL_VERSION = true ? "1.
|
|
11081
|
+
var KERNEL_VERSION = true ? "1.99.0" : "0.0.0-dev";
|
|
11079
11082
|
var OS_RELEASE = "6.0.0-slicc";
|
|
11080
11083
|
function procVersion() {
|
|
11081
11084
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -14173,6 +14176,206 @@ async function waitReady(fds, read, write, deadline, interrupted3) {
|
|
|
14173
14176
|
}
|
|
14174
14177
|
}
|
|
14175
14178
|
|
|
14179
|
+
// src/kernel/sem.ts
|
|
14180
|
+
var SEM_VALUE_MAX = 2147483647;
|
|
14181
|
+
var SEM_NAMES_MAX = 4096;
|
|
14182
|
+
var SEM_HANDLES_MAX = 256;
|
|
14183
|
+
var NAME_MAX = 251;
|
|
14184
|
+
var TIMER_MAX_MS = 2147483647;
|
|
14185
|
+
var SEM_OPS = [
|
|
14186
|
+
"sem-open",
|
|
14187
|
+
"sem-close",
|
|
14188
|
+
"sem-unlink",
|
|
14189
|
+
"sem-post",
|
|
14190
|
+
"sem-wait",
|
|
14191
|
+
"sem-getvalue"
|
|
14192
|
+
];
|
|
14193
|
+
var Semaphore = class {
|
|
14194
|
+
value;
|
|
14195
|
+
uid;
|
|
14196
|
+
gid;
|
|
14197
|
+
mode;
|
|
14198
|
+
waiters = [];
|
|
14199
|
+
constructor(value, uid, gid, mode) {
|
|
14200
|
+
this.value = value;
|
|
14201
|
+
this.uid = uid;
|
|
14202
|
+
this.gid = gid;
|
|
14203
|
+
this.mode = mode;
|
|
14204
|
+
}
|
|
14205
|
+
post() {
|
|
14206
|
+
const next2 = this.waiters.shift();
|
|
14207
|
+
if (next2) next2.grant();
|
|
14208
|
+
else if (this.value >= SEM_VALUE_MAX) throw new KernelError("EOVERFLOW");
|
|
14209
|
+
else this.value++;
|
|
14210
|
+
}
|
|
14211
|
+
take() {
|
|
14212
|
+
if (this.value === 0) return false;
|
|
14213
|
+
this.value--;
|
|
14214
|
+
return true;
|
|
14215
|
+
}
|
|
14216
|
+
wait(signal, timeoutMs) {
|
|
14217
|
+
if (this.take()) return Promise.resolve(true);
|
|
14218
|
+
if (signal.aborted) return Promise.reject(new KernelError("EINTR"));
|
|
14219
|
+
return new Promise((resolve2, reject) => {
|
|
14220
|
+
const deadline = timeoutMs < 0 ? Number.POSITIVE_INFINITY : performance.now() + timeoutMs;
|
|
14221
|
+
let timer;
|
|
14222
|
+
const leave = () => {
|
|
14223
|
+
const at = this.waiters.indexOf(waiter);
|
|
14224
|
+
if (at >= 0) this.waiters.splice(at, 1);
|
|
14225
|
+
clearTimeout(timer);
|
|
14226
|
+
signal.removeEventListener("abort", abort);
|
|
14227
|
+
};
|
|
14228
|
+
const waiter = {
|
|
14229
|
+
grant: () => {
|
|
14230
|
+
leave();
|
|
14231
|
+
resolve2(true);
|
|
14232
|
+
}
|
|
14233
|
+
};
|
|
14234
|
+
const abort = () => {
|
|
14235
|
+
leave();
|
|
14236
|
+
reject(new KernelError("EINTR"));
|
|
14237
|
+
};
|
|
14238
|
+
const expire = () => {
|
|
14239
|
+
const left = deadline - performance.now();
|
|
14240
|
+
if (left > 0) {
|
|
14241
|
+
timer = setTimeout(expire, Math.min(left, TIMER_MAX_MS));
|
|
14242
|
+
return;
|
|
14243
|
+
}
|
|
14244
|
+
leave();
|
|
14245
|
+
resolve2(false);
|
|
14246
|
+
};
|
|
14247
|
+
this.waiters.push(waiter);
|
|
14248
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
14249
|
+
if (deadline !== Number.POSITIVE_INFINITY) {
|
|
14250
|
+
timer = setTimeout(expire, Math.min(timeoutMs, TIMER_MAX_MS));
|
|
14251
|
+
}
|
|
14252
|
+
});
|
|
14253
|
+
}
|
|
14254
|
+
};
|
|
14255
|
+
var SemTable = class {
|
|
14256
|
+
names = /* @__PURE__ */ new Map();
|
|
14257
|
+
limit;
|
|
14258
|
+
constructor(limit = SEM_NAMES_MAX) {
|
|
14259
|
+
this.limit = limit;
|
|
14260
|
+
}
|
|
14261
|
+
open(name2, create, exclusive, make, check, adopt) {
|
|
14262
|
+
const found = this.names.get(name2);
|
|
14263
|
+
if (found) {
|
|
14264
|
+
if (create && exclusive) throw new KernelError("EEXIST");
|
|
14265
|
+
check(found);
|
|
14266
|
+
return adopt(found);
|
|
14267
|
+
}
|
|
14268
|
+
if (!create) throw new KernelError("ENOENT");
|
|
14269
|
+
if (this.names.size >= this.limit) throw new KernelError("ENOSPC");
|
|
14270
|
+
const sem = make();
|
|
14271
|
+
const handle = adopt(sem);
|
|
14272
|
+
this.names.set(name2, sem);
|
|
14273
|
+
return handle;
|
|
14274
|
+
}
|
|
14275
|
+
unlink(name2, check) {
|
|
14276
|
+
const found = this.names.get(name2);
|
|
14277
|
+
if (!found) throw new KernelError("ENOENT");
|
|
14278
|
+
check(found);
|
|
14279
|
+
this.names.delete(name2);
|
|
14280
|
+
}
|
|
14281
|
+
};
|
|
14282
|
+
var SemHandles = class _SemHandles {
|
|
14283
|
+
byHandle = /* @__PURE__ */ new Map();
|
|
14284
|
+
next = 1;
|
|
14285
|
+
add(sem) {
|
|
14286
|
+
for (const [handle2, entry] of this.byHandle) {
|
|
14287
|
+
if (entry.sem === sem) {
|
|
14288
|
+
entry.opens++;
|
|
14289
|
+
return handle2;
|
|
14290
|
+
}
|
|
14291
|
+
}
|
|
14292
|
+
if (this.byHandle.size >= SEM_HANDLES_MAX) throw new KernelError("EMFILE");
|
|
14293
|
+
const handle = this.next++;
|
|
14294
|
+
this.byHandle.set(handle, { sem, opens: 1 });
|
|
14295
|
+
return handle;
|
|
14296
|
+
}
|
|
14297
|
+
get(handle) {
|
|
14298
|
+
const entry = this.byHandle.get(handle);
|
|
14299
|
+
if (!entry) throw new KernelError("EINVAL");
|
|
14300
|
+
return entry.sem;
|
|
14301
|
+
}
|
|
14302
|
+
close(handle) {
|
|
14303
|
+
const entry = this.byHandle.get(handle);
|
|
14304
|
+
if (!entry) throw new KernelError("EINVAL");
|
|
14305
|
+
if (--entry.opens === 0) this.byHandle.delete(handle);
|
|
14306
|
+
}
|
|
14307
|
+
fork() {
|
|
14308
|
+
const child = new _SemHandles();
|
|
14309
|
+
child.next = this.next;
|
|
14310
|
+
for (const [handle, entry] of this.byHandle) child.byHandle.set(handle, { ...entry });
|
|
14311
|
+
return child;
|
|
14312
|
+
}
|
|
14313
|
+
clear() {
|
|
14314
|
+
this.byHandle.clear();
|
|
14315
|
+
}
|
|
14316
|
+
};
|
|
14317
|
+
function semName(raw) {
|
|
14318
|
+
const name2 = raw.replace(/^\/+/, "");
|
|
14319
|
+
if (name2 === "" || name2.includes("/") || name2 === "." || name2 === "..") {
|
|
14320
|
+
throw new KernelError("EINVAL");
|
|
14321
|
+
}
|
|
14322
|
+
if (new TextEncoder().encode(name2).length > NAME_MAX) throw new KernelError("ENAMETOOLONG");
|
|
14323
|
+
return name2;
|
|
14324
|
+
}
|
|
14325
|
+
var ok2 = (json5) => json5 === void 0 ? { ok: true, kind: "void" } : { ok: true, kind: "json", json: json5 };
|
|
14326
|
+
async function semSyscall(req, proc) {
|
|
14327
|
+
const { table, handles, cred } = proc;
|
|
14328
|
+
if (!table) throw new KernelError("ENOSYS");
|
|
14329
|
+
const { denied: denied2 } = proc;
|
|
14330
|
+
const shown = (name2) => `/dev/shm/sem.${name2}`;
|
|
14331
|
+
const opens = (name2) => (sem) => {
|
|
14332
|
+
const perm = { uid: sem.uid, gid: sem.gid, mode: sem.mode };
|
|
14333
|
+
if (denied2 && !permits(cred, perm, R_OK | W_OK, false)) denied2("sem_open", shown(name2));
|
|
14334
|
+
};
|
|
14335
|
+
const unlinks = (name2) => (sem) => {
|
|
14336
|
+
if (denied2 && cred.euid !== 0 && cred.euid !== sem.uid) denied2("sem_unlink", shown(name2));
|
|
14337
|
+
};
|
|
14338
|
+
switch (req.op) {
|
|
14339
|
+
case "sem-open": {
|
|
14340
|
+
if (req.value < 0 || req.value > SEM_VALUE_MAX) throw new KernelError("EINVAL");
|
|
14341
|
+
const name2 = semName(req.name);
|
|
14342
|
+
const mode = req.mode & 511 & ~proc.umask;
|
|
14343
|
+
return ok2(
|
|
14344
|
+
table.open(
|
|
14345
|
+
name2,
|
|
14346
|
+
req.create,
|
|
14347
|
+
req.exclusive,
|
|
14348
|
+
() => new Semaphore(req.value, cred.euid, cred.egid, mode),
|
|
14349
|
+
opens(name2),
|
|
14350
|
+
(sem) => handles.add(sem)
|
|
14351
|
+
)
|
|
14352
|
+
);
|
|
14353
|
+
}
|
|
14354
|
+
case "sem-close":
|
|
14355
|
+
handles.close(req.handle);
|
|
14356
|
+
return ok2();
|
|
14357
|
+
case "sem-unlink": {
|
|
14358
|
+
const name2 = semName(req.name);
|
|
14359
|
+
table.unlink(name2, unlinks(name2));
|
|
14360
|
+
return ok2();
|
|
14361
|
+
}
|
|
14362
|
+
case "sem-post":
|
|
14363
|
+
handles.get(req.handle).post();
|
|
14364
|
+
return ok2();
|
|
14365
|
+
case "sem-getvalue":
|
|
14366
|
+
return ok2(handles.get(req.handle).value);
|
|
14367
|
+
case "sem-wait": {
|
|
14368
|
+
const sem = handles.get(req.handle);
|
|
14369
|
+
if (sem.take()) return ok2();
|
|
14370
|
+
if (req.how === "try") throw new KernelError("EAGAIN");
|
|
14371
|
+
if (req.how === "timed" && req.timeoutMs === 0) throw new KernelError("ETIMEDOUT");
|
|
14372
|
+
const got = await sem.wait(proc.blocking(), req.how === "block" ? -1 : req.timeoutMs);
|
|
14373
|
+
if (!got) throw new KernelError("ETIMEDOUT");
|
|
14374
|
+
return ok2();
|
|
14375
|
+
}
|
|
14376
|
+
}
|
|
14377
|
+
}
|
|
14378
|
+
|
|
14176
14379
|
// src/kernel/net/datagram-wire.ts
|
|
14177
14380
|
function encodeReceived(got) {
|
|
14178
14381
|
const host = new TextEncoder().encode(got.host);
|
|
@@ -14219,20 +14422,20 @@ function dgramAt(fds, fd) {
|
|
|
14219
14422
|
if (!(file instanceof KernelDgram)) throw new KernelError("EOPNOTSUPP");
|
|
14220
14423
|
return file;
|
|
14221
14424
|
}
|
|
14222
|
-
var
|
|
14425
|
+
var ok3 = (json5) => json5 === void 0 ? { ok: true, kind: "void" } : { ok: true, kind: "json", json: json5 };
|
|
14223
14426
|
async function socketSyscall(req, proc) {
|
|
14224
14427
|
const { fds, net } = proc;
|
|
14225
14428
|
switch (req.op) {
|
|
14226
14429
|
case "sock-open": {
|
|
14227
14430
|
if (req.type === "dgram" && req.domain !== "inet") throw new KernelError("EPROTONOSUPPORT");
|
|
14228
14431
|
const file = req.type === "dgram" ? new KernelDgram(net) : net.socket(req.domain);
|
|
14229
|
-
return
|
|
14432
|
+
return ok3(fds.install(new OpenFile(file), 3));
|
|
14230
14433
|
}
|
|
14231
14434
|
case "sock-pair": {
|
|
14232
14435
|
const [a, b] = KernelSocket.pair(net, req.domain, proc.cred?.());
|
|
14233
14436
|
const first = fds.install(new OpenFile(a), 3);
|
|
14234
14437
|
try {
|
|
14235
|
-
return
|
|
14438
|
+
return ok3([first, fds.install(new OpenFile(b), 3)]);
|
|
14236
14439
|
} catch (e) {
|
|
14237
14440
|
await Promise.resolve(fds.close(first));
|
|
14238
14441
|
throw e;
|
|
@@ -14240,32 +14443,32 @@ async function socketSyscall(req, proc) {
|
|
|
14240
14443
|
}
|
|
14241
14444
|
case "sock-bind":
|
|
14242
14445
|
anySocketAt(fds, req.fd).bind(req.addr);
|
|
14243
|
-
return
|
|
14446
|
+
return ok3();
|
|
14244
14447
|
case "sock-listen":
|
|
14245
14448
|
socketAt(fds, req.fd).listen(req.backlog, proc.cred?.());
|
|
14246
|
-
return
|
|
14449
|
+
return ok3();
|
|
14247
14450
|
case "sock-accept":
|
|
14248
|
-
return
|
|
14451
|
+
return ok3(await accept(proc, req.fd, req.nonblock));
|
|
14249
14452
|
case "sock-connect":
|
|
14250
14453
|
return connect(req, proc);
|
|
14251
14454
|
case "sock-shutdown":
|
|
14252
14455
|
anySocketAt(fds, req.fd).shutdown(req.how);
|
|
14253
|
-
return
|
|
14456
|
+
return ok3();
|
|
14254
14457
|
case "sock-name": {
|
|
14255
14458
|
const socket = anySocketAt(fds, req.fd);
|
|
14256
14459
|
const addr = req.peer ? socket.peer : socket.local;
|
|
14257
14460
|
if (req.peer && !addr) throw new KernelError("ENOTCONN");
|
|
14258
|
-
return
|
|
14461
|
+
return ok3(addr ?? unnamed(socket instanceof KernelDgram ? "inet" : socket.domain));
|
|
14259
14462
|
}
|
|
14260
14463
|
case "sock-getopt":
|
|
14261
|
-
return
|
|
14464
|
+
return ok3(anySocketAt(fds, req.fd).getOption(req.level, req.name));
|
|
14262
14465
|
case "sock-setopt":
|
|
14263
14466
|
anySocketAt(fds, req.fd).setOption(req.level, req.name, req.value);
|
|
14264
|
-
return
|
|
14467
|
+
return ok3();
|
|
14265
14468
|
case "sock-resolve": {
|
|
14266
14469
|
const addresses = await proc.resolve(req.name, req.family, () => proc.blocking());
|
|
14267
14470
|
if (addresses.length === 0) throw new KernelError("ENOENT");
|
|
14268
|
-
return
|
|
14471
|
+
return ok3(addresses);
|
|
14269
14472
|
}
|
|
14270
14473
|
default:
|
|
14271
14474
|
return datagram(req, proc);
|
|
@@ -14275,7 +14478,7 @@ async function connect(req, proc) {
|
|
|
14275
14478
|
const target = anySocketAt(proc.fds, req.fd);
|
|
14276
14479
|
if (target instanceof KernelDgram) {
|
|
14277
14480
|
target.connectTo(req.addr);
|
|
14278
|
-
return
|
|
14481
|
+
return ok3();
|
|
14279
14482
|
}
|
|
14280
14483
|
const stamp = proc.net.facadeAt(req.addr) && await proc.stamp?.();
|
|
14281
14484
|
const dialing = target.connect(req.addr, true, proc.cred?.(), stamp || void 0);
|
|
@@ -14284,13 +14487,13 @@ async function connect(req, proc) {
|
|
|
14284
14487
|
throw new KernelError("EINPROGRESS");
|
|
14285
14488
|
}
|
|
14286
14489
|
if (dialing !== void 0) await interruptible2(dialing, proc.blocking());
|
|
14287
|
-
return
|
|
14490
|
+
return ok3();
|
|
14288
14491
|
}
|
|
14289
14492
|
async function datagram(req, proc) {
|
|
14290
14493
|
const dgram = dgramAt(proc.fds, req.fd);
|
|
14291
14494
|
if (req.op === "sock-sendto") {
|
|
14292
14495
|
if (req.nonblock && !pollFile(dgram).writable) throw new KernelError("EAGAIN");
|
|
14293
|
-
return
|
|
14496
|
+
return ok3(await dgram.send(req.body, req.addr));
|
|
14294
14497
|
}
|
|
14295
14498
|
const ready2 = pollFile(dgram).readable;
|
|
14296
14499
|
if (req.nonblock && !ready2) throw new KernelError("EAGAIN");
|
|
@@ -15056,6 +15259,9 @@ function isHttpSyscall(req) {
|
|
|
15056
15259
|
function isSocketSyscall(req) {
|
|
15057
15260
|
return req.op.startsWith("sock-");
|
|
15058
15261
|
}
|
|
15262
|
+
function isSemSyscall(req) {
|
|
15263
|
+
return req.op.startsWith("sem-");
|
|
15264
|
+
}
|
|
15059
15265
|
function isEpollSyscall(req) {
|
|
15060
15266
|
return EPOLL_OPS.includes(req.op);
|
|
15061
15267
|
}
|
|
@@ -15150,6 +15356,7 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
|
|
|
15150
15356
|
"sig-pause",
|
|
15151
15357
|
...SOCKET_OPS,
|
|
15152
15358
|
...EPOLL_OPS,
|
|
15359
|
+
...SEM_OPS,
|
|
15153
15360
|
...HTTP_OPS,
|
|
15154
15361
|
...PTY_OPS,
|
|
15155
15362
|
...HOST_OPS
|
|
@@ -15382,6 +15589,7 @@ var WasmProcess = class {
|
|
|
15382
15589
|
if (isTtySyscall(req)) return this.ttySyscall(req);
|
|
15383
15590
|
if (isJobSyscall(req)) return this.jobSyscall(req);
|
|
15384
15591
|
if (isSocketSyscall(req)) return await this.socketSyscall(req, cancelled);
|
|
15592
|
+
if (isSemSyscall(req)) return await this.semSyscall(req, cancelled);
|
|
15385
15593
|
if (isEpollSyscall(req)) {
|
|
15386
15594
|
return await epollSyscall(req, {
|
|
15387
15595
|
fds: this.fds,
|
|
@@ -16101,6 +16309,20 @@ var WasmProcess = class {
|
|
|
16101
16309
|
if (!http) return Promise.resolve({ ok: false, errno: "ENETUNREACH", message: NO_TRANSPORT });
|
|
16102
16310
|
return http.syscall(req);
|
|
16103
16311
|
}
|
|
16312
|
+
semSyscall(req, cancelled) {
|
|
16313
|
+
const g = this.guarded();
|
|
16314
|
+
const known = this.fds.handles;
|
|
16315
|
+
const handles = known instanceof SemHandles ? known : new SemHandles();
|
|
16316
|
+
this.fds.handles = handles;
|
|
16317
|
+
return semSyscall(req, {
|
|
16318
|
+
table: this.options.sems,
|
|
16319
|
+
handles,
|
|
16320
|
+
cred: this.cred,
|
|
16321
|
+
denied: g ? (op, path) => deny(g, op, path) : void 0,
|
|
16322
|
+
umask: this.umask,
|
|
16323
|
+
blocking: () => this.blockingSignal(cancelled)
|
|
16324
|
+
});
|
|
16325
|
+
}
|
|
16104
16326
|
socketSyscall(req, cancelled) {
|
|
16105
16327
|
this.net ??= this.options.net ?? new LoopbackNet();
|
|
16106
16328
|
const resolver = this.options.resolver ?? HOSTS_ONLY;
|
|
@@ -16611,6 +16833,7 @@ function processOptions(opts, header4, hooks, created3) {
|
|
|
16611
16833
|
net: opts.net,
|
|
16612
16834
|
http: opts.http,
|
|
16613
16835
|
locks: opts.locks,
|
|
16836
|
+
...opts.sems ? { sems: opts.sems } : {},
|
|
16614
16837
|
onReap: opts.onReap,
|
|
16615
16838
|
resolver: opts.resolver,
|
|
16616
16839
|
...notifiers(header4),
|
|
@@ -20272,6 +20495,7 @@ var Launcher = class {
|
|
|
20272
20495
|
sudoer;
|
|
20273
20496
|
jobs = new JobTable();
|
|
20274
20497
|
locks = new LockTable();
|
|
20498
|
+
sems = new SemTable();
|
|
20275
20499
|
settling = new SettlingChildren((pid) => this.jobs.pgidOf(pid));
|
|
20276
20500
|
ptys = new PtyTable(
|
|
20277
20501
|
(tty, sig) => this.keySignal(tty, 0, sig, () => this.jobs.signalOwnedForeground(tty, sig)),
|
|
@@ -21130,6 +21354,7 @@ var Launcher = class {
|
|
|
21130
21354
|
net: this.net,
|
|
21131
21355
|
http: new HttpHandles(this.transport, pid, this.loopbackFor(pid)),
|
|
21132
21356
|
locks: this.locks,
|
|
21357
|
+
sems: this.sems,
|
|
21133
21358
|
resolver: this.resolver,
|
|
21134
21359
|
onReap: (child) => this.reaped(child, pid),
|
|
21135
21360
|
...req.fork ? { fork: req.fork } : {},
|