libuv: timer start

This commit is contained in:
Mitchell Hashimoto
2022-04-21 19:43:20 -07:00
parent 10440d6783
commit 2496ffafec
2 changed files with 49 additions and 8 deletions

View File

@ -25,13 +25,55 @@ pub fn deinit(self: *Timer, alloc: Allocator) void {
self.* = undefined;
}
/// Start the timer. timeout and repeat are in milliseconds.
///
/// If timeout is zero, the callback fires on the next event loop iteration.
/// If repeat is non-zero, the callback fires first after timeout milliseconds
/// and then repeatedly after repeat milliseconds.
pub fn start(
self: Timer,
comptime cb: fn (Timer) void,
timeout: u64,
repeat: u64,
) !void {
const Wrapper = struct {
pub fn callback(handle: [*c]c.uv_timer_t) callconv(.C) void {
const newSelf: Timer = .{ .handle = handle };
@call(.{ .modifier = .always_inline }, cb, .{newSelf});
}
};
try errors.convertError(c.uv_timer_start(
self.handle,
Wrapper.callback,
timeout,
repeat,
));
}
/// Stop the timer, the callback will not be called anymore.
pub fn stop(self: Timer) !void {
try errors.convertError(c.uv_timer_stop(self.handle));
}
test "Timer" {
var loop = try Loop.init(testing.allocator);
defer loop.deinit(testing.allocator);
var timer = try init(testing.allocator, loop);
defer timer.deinit(testing.allocator);
timer.close(null);
var called: bool = false;
timer.setData(&called);
try timer.start((struct {
fn callback(t: Timer) void {
t.getData(bool).?.* = true;
t.close(null);
}
}).callback, 10, 1000);
_ = try loop.run(.default);
try testing.expect(called);
}
test "Timer: close callback" {
@ -43,7 +85,7 @@ test "Timer: close callback" {
var data: u8 = 42;
timer.setData(&data);
timer.close((struct {
fn callback(v: *Timer) void {
fn callback(v: Timer) void {
var dataPtr = v.getData(u8).?;
dataPtr.* = 24;
}

View File

@ -23,16 +23,15 @@ pub fn Handle(comptime T: type) type {
//
// In-progress requests, like uv_connect_t or uv_write_t, are cancelled
// and have their callbacks called asynchronously with status=UV_ECANCELED.
pub fn close(self: *T, comptime cb: ?fn (*T) void) void {
pub fn close(self: T, comptime cb: ?fn (T) void) void {
const cbParam = if (cb) |f|
(struct {
pub fn callback(handle: [*c]c.uv_handle_t) callconv(.C) void {
// We get the raw handle, so we need to reconstruct
// the T. This is mutable because a lot of the libuv APIs
// are non-const but modifying it makes no sense.
var param: T = .{ .handle = @ptrCast(HandleType, handle) };
@call(.{ .modifier = .always_inline }, f, .{&param});
const param: T = .{ .handle = @ptrCast(HandleType, handle) };
@call(.{ .modifier = .always_inline }, f, .{param});
}
}).callback
else
@ -42,7 +41,7 @@ pub fn Handle(comptime T: type) type {
}
/// Sets handle->data to data.
pub fn setData(self: *T, pointer: ?*anyopaque) void {
pub fn setData(self: T, pointer: ?*anyopaque) void {
c.uv_handle_set_data(
@ptrCast(*c.uv_handle_t, self.handle),
pointer,
@ -50,7 +49,7 @@ pub fn Handle(comptime T: type) type {
}
/// Returns handle->data.
pub fn getData(self: *T, comptime DT: type) ?*DT {
pub fn getData(self: T, comptime DT: type) ?*DT {
return if (c.uv_handle_get_data(@ptrCast(*c.uv_handle_t, self.handle))) |ptr|
@ptrCast(?*DT, @alignCast(@alignOf(DT), ptr))
else