summaryrefslogtreecommitdiff
path: root/src/fs.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-27 20:20:27 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commit7dc3891ed574d6e96548f592b09b0f8abc87ae2a (patch)
tree70cddb9ce4a7e9039f8167e806b7e996f94eefb0 /src/fs.zig
parentacd9e032a147f4aa7ad49110dc2f4fb945e7a9bb (diff)
downloadpardes-7dc3891ed574d6e96548f592b09b0f8abc87ae2a.tar.gz
pardes-7dc3891ed574d6e96548f592b09b0f8abc87ae2a.zip
Keep what each open holds in one table of open records
Snapshots (and /log's cursor), runs, and the reader_handle constants for event and pty/data each reused the open handle and each validated handle and node on its own. Now p.fs.opens is one table of 64 records, each the node it was opened on and a tagged union of what it holds, like lib9p's per-fid aux and acme's Fid (editors/acme/dat.h:373-385): one lookup (openOf), one release, ENFILE when full. A held read lives in its open's record, so it goes with the release. Opens that hold nothing answer handle 0 and take no record. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/fs.zig')
-rw-r--r--src/fs.zig17
1 files changed, 5 insertions, 12 deletions
diff --git a/src/fs.zig b/src/fs.zig
index c2e88b10..4f395b1c 100644
--- a/src/fs.zig
+++ b/src/fs.zig
@@ -321,7 +321,7 @@ test "virtual writes enforce permissions even when contents are empty" {
try std.testing.expectError(error.IsDirectory, write(p, "/virtual/src", bytes));
} else try std.testing.expectError(error.FileNotFound, write(p, "/virtual/src/fs.zig", bytes));
}
- for (p.fs.snapshots) |snapshot| try std.testing.expect(snapshot.node == 0);
+ for (p.fs.opens) |o| try std.testing.expect(o.node == 0);
}
test "direct self reads and writes use the same dot paths as Look" {
@@ -480,10 +480,7 @@ test "bounded reads release terminal snapshots after success and size refusal" {
defer gpa.free(bytes);
try std.testing.expectEqualStrings(expected, bytes);
try std.testing.expectError(error.FileTooLarge, readLimit(p, path, expected.len - 1));
- for (p.fs.snapshots) |snapshot| {
- try std.testing.expectEqual(@as(u64, 0), snapshot.node);
- try std.testing.expect(snapshot.bytes == null);
- }
+ for (p.fs.opens) |o| try std.testing.expectEqual(@as(u64, 0), o.node);
}
test "bounded reads probe size-unknown proc files at the exact limit" {
@@ -1237,14 +1234,11 @@ pub const Namespace = struct {
mounts: std.ArrayList(Mount) = .empty,
node_name: [16]u8 = undefined,
os_paths: std.ArrayList(OsPath) = .empty,
- snapshots: [tree.screen.snapshot_slots]tree.screen.Snapshot = @splat(.{}),
- runs: [tree.pty.run_slots]tree.pty.Run = @splat(.{}),
+ /// What each open holds between its open and its release.
+ opens: [tree.open_slots]tree.Open = @splat(.{}),
out: std.ArrayList(u8) = .empty,
listeners: u16 = 0,
origin: u8 = 'K',
- /// Reads that found nothing yet, one per open that can wait: the log's
- /// and a run's opens, and one event and one pty/data reader a pane.
- held: [tree.screen.snapshot_slots + tree.pty.run_slots + 2 * MAX_PANES]?tree.Held = @splat(null),
/// Something a held read may be waiting on changed since they were last
/// answered: a record queued, a run answered, a pane gone.
news: bool = false,
@@ -1266,8 +1260,7 @@ pub const Namespace = struct {
st.mounts.deinit(gpa);
for (st.os_paths.items) |entry| gpa.free(entry.path);
st.os_paths.deinit(gpa);
- for (st.snapshots) |snapshot| if (snapshot.bytes) |bytes| gpa.free(bytes);
- for (&st.runs) |*slot| slot.reset(gpa, 0);
+ for (&st.opens) |*o| o.deinit(gpa);
st.log.deinit(gpa);
st.out.deinit(gpa);
}