summaryrefslogtreecommitdiff
path: root/src/selection_pipe.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/selection_pipe.zig')
-rw-r--r--src/selection_pipe.zig49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/selection_pipe.zig b/src/selection_pipe.zig
index 65c4c7fd..c1104010 100644
--- a/src/selection_pipe.zig
+++ b/src/selection_pipe.zig
@@ -78,6 +78,55 @@ pub const Response = struct {
}
};
+/// The in-flight set a host keeps while pipes run off its loop.
+///
+/// tty.zig and gui.zig each had this verbatim — same `finish` walk, same
+/// `cancelAll`, same 16 — differing only in whether `add` asserted or returned
+/// a bool. It lives here beside the Job it tracks so a third host (the AppKit
+/// shell, which had no pipe support at all) does not have to grow a fourth.
+///
+/// Bounded on purpose: a filter is a user gesture, and sixteen concurrent ones
+/// is already more than anybody means. `add` returning false is the host's cue
+/// to answer the request as failed rather than to queue it.
+pub const Tasks = struct {
+ pub const capacity = 16;
+
+ pub const Task = struct {
+ id: u32,
+ future: std.Io.Future(anyerror!void),
+ };
+
+ items: [capacity]Task = undefined,
+ len: usize = 0,
+
+ pub fn full(tasks: *const Tasks) bool {
+ return tasks.len == tasks.items.len;
+ }
+
+ pub fn add(tasks: *Tasks, task: Task) bool {
+ if (tasks.full()) return false;
+ tasks.items[tasks.len] = task;
+ tasks.len += 1;
+ return true;
+ }
+
+ /// Join the one that answered and drop it, preserving order so `cancelAll`
+ /// stays deterministic.
+ pub fn finish(tasks: *Tasks, io: std.Io, id: u32) void {
+ for (tasks.items[0..tasks.len], 0..) |*task, i| if (task.id == id) {
+ task.future.await(io) catch {};
+ tasks.len -= 1;
+ std.mem.copyForwards(Task, tasks.items[i..tasks.len], tasks.items[i + 1 .. tasks.len + 1]);
+ return;
+ };
+ }
+
+ pub fn cancelAll(tasks: *Tasks, io: std.Io) void {
+ for (tasks.items[0..tasks.len]) |*task| task.future.cancel(io) catch {};
+ tasks.len = 0;
+ }
+};
+
const WriterContext = struct {
io: std.Io,
file: std.Io.File,