Skip to content

Commit f2a6e94

Browse files
Merge pull request #229 from lightpanda-io/cancellation
Cancellation
2 parents ade128f + 054e20c commit f2a6e94

File tree

3 files changed

+61
-5
lines changed

3 files changed

+61
-5
lines changed

src/loop.zig

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ pub const IO = @import("tigerbeetle-io").IO;
2020
const public = @import("api.zig");
2121
const JSCallback = public.Callback;
2222

23+
const log = std.log.scoped(.loop);
24+
2325
fn report(comptime fmt: []const u8, args: anytype) void {
2426
const max_len = 200;
2527
var buf: [max_len]u8 = undefined;
@@ -113,7 +115,13 @@ pub const SingleThreaded = struct {
113115
defer ctx.loop.freeCbk(completion, ctx);
114116

115117
// TODO: return the error to the callback
116-
result catch |err| @panic(@errorName(err));
118+
result catch |err| {
119+
switch (err) {
120+
error.Canceled => {},
121+
else => log.err("timeout callback: {any}", .{err}),
122+
}
123+
return;
124+
};
117125

118126
const old_events_nb = ctx.loop.removeEvent();
119127
if (builtin.is_test) {
@@ -129,7 +137,7 @@ pub const SingleThreaded = struct {
129137
}
130138
}
131139

132-
pub fn timeout(self: *Self, nanoseconds: u63, js_cbk: ?JSCallback) void {
140+
pub fn timeout(self: *Self, nanoseconds: u63, js_cbk: ?JSCallback) usize {
133141
const completion = self.alloc.create(IO.Completion) catch unreachable;
134142
completion.* = undefined;
135143
const ctx = self.alloc.create(ContextTimeout) catch unreachable;
@@ -142,6 +150,54 @@ pub const SingleThreaded = struct {
142150
if (builtin.is_test) {
143151
report("start timeout {d} for {d} nanoseconds", .{ old_events_nb + 1, nanoseconds });
144152
}
153+
154+
return @intFromPtr(completion);
155+
}
156+
157+
const ContextCancel = struct {
158+
loop: *Self,
159+
js_cbk: ?JSCallback,
160+
};
161+
162+
fn cancelCallback(
163+
ctx: *ContextCancel,
164+
completion: *IO.Completion,
165+
result: IO.CancelError!void,
166+
) void {
167+
defer ctx.loop.freeCbk(completion, ctx);
168+
169+
// TODO: return the error to the callback
170+
result catch |err| {
171+
log.err("cancel callback: {any}", .{err});
172+
return;
173+
};
174+
175+
const old_events_nb = ctx.loop.removeEvent();
176+
if (builtin.is_test) {
177+
report("timeout done, remaining events: {d}", .{old_events_nb - 1});
178+
}
179+
180+
// js callback
181+
if (ctx.js_cbk) |js_cbk| {
182+
defer js_cbk.deinit(ctx.loop.alloc);
183+
js_cbk.call(null) catch {
184+
ctx.loop.cbk_error = true;
185+
};
186+
}
187+
}
188+
189+
pub fn cancel(self: *Self, id: usize, js_cbk: ?JSCallback) void {
190+
const comp_cancel: *IO.Completion = @ptrFromInt(id);
191+
192+
const completion = self.alloc.create(IO.Completion) catch unreachable;
193+
completion.* = undefined;
194+
const ctx = self.alloc.create(ContextCancel) catch unreachable;
195+
ctx.* = ContextCancel{
196+
.loop = self,
197+
.js_cbk = js_cbk,
198+
};
199+
200+
self.io.cancel(*ContextCancel, ctx, cancelCallback, completion, comp_cancel);
145201
}
146202

147203
// Yield

src/tests/cbk_test.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub const Window = struct {
5252
) void {
5353
const n: u63 = @intCast(milliseconds);
5454
// TODO: check this value can be holded in u63
55-
loop.timeout(n * std.time.ns_per_ms, callback);
55+
_ = loop.timeout(n * std.time.ns_per_ms, callback);
5656
}
5757

5858
pub fn _cbkAsyncWithJSArg(
@@ -64,7 +64,7 @@ pub const Window = struct {
6464
) void {
6565
const n: u63 = @intCast(milliseconds);
6666
// TODO: check this value can be holded in u63
67-
loop.timeout(n * std.time.ns_per_ms, callback);
67+
_ = loop.timeout(n * std.time.ns_per_ms, callback);
6868
}
6969

7070
pub fn _cbkAsyncWithNatArg(_: Window, callback: Callback) !void {

vendor/tigerbeetle-io

0 commit comments

Comments
 (0)