Skip to content

Commit 4f98f5c

Browse files
committed
backend/kqueue: use xev.Async for mach port to fix leak
1 parent 1dd3c90 commit 4f98f5c

File tree

1 file changed

+6
-43
lines changed

1 file changed

+6
-43
lines changed

src/backend/kqueue.zig

Lines changed: 6 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub const Loop = struct {
2424
/// an empty message to this port can be used to wake up the loop
2525
/// at any time. Waking up the loop via this port won't trigger any
2626
/// particular completion, it just forces tick to cycle.
27-
mach_port: posix.system.mach_port_name_t,
27+
mach_port: xev.Async,
2828
mach_port_buffer: [32]u8 = undefined,
2929

3030
/// The number of active completions. This DOES NOT include completions that
@@ -80,18 +80,8 @@ pub const Loop = struct {
8080
const fd = try posix.kqueue();
8181
errdefer posix.close(fd);
8282

83-
// Create our mach port that we use for wakeups.
84-
const mach_self = posix.system.mach_task_self();
85-
var mach_port: posix.system.mach_port_name_t = undefined;
86-
switch (posix.system.getKernError(posix.system.mach_port_allocate(
87-
mach_self,
88-
@intFromEnum(posix.system.MACH_PORT_RIGHT.RECEIVE),
89-
&mach_port,
90-
))) {
91-
.SUCCESS => {}, // Success
92-
else => return error.MachPortAllocFailed,
93-
}
94-
errdefer _ = posix.system.mach_port_deallocate(mach_self, mach_port);
83+
var mach_port = try xev.Async.init();
84+
errdefer mach_port.deinit();
9585

9686
var res: Loop = .{
9787
.kqueue_fd = fd,
@@ -108,10 +98,7 @@ pub const Loop = struct {
10898
/// were unprocessed are lost -- their callbacks will never be called.
10999
pub fn deinit(self: *Loop) void {
110100
posix.close(self.kqueue_fd);
111-
_ = posix.system.mach_port_deallocate(
112-
posix.system.mach_task_self(),
113-
self.mach_port,
114-
);
101+
self.mach_port.deinit();
115102
}
116103

117104
/// Stop the loop. This can only be called from the main thread.
@@ -300,7 +287,7 @@ pub const Loop = struct {
300287
// Add our event so that we wake up when our mach port receives an
301288
// event. We have to add here because we need a stable self pointer.
302289
const events = [_]Kevent{.{
303-
.ident = @as(usize, @intCast(self.mach_port)),
290+
.ident = @as(usize, @intCast(self.mach_port.port)),
304291
.filter = posix.system.EVFILT_MACHPORT,
305292
.flags = posix.system.EV_ADD | posix.system.EV_ENABLE,
306293
.fflags = posix.system.MACH_RCV_MSG,
@@ -948,31 +935,7 @@ pub const Loop = struct {
948935
/// Sends an empty message to this loop's mach port so that it wakes
949936
/// up if it is blocking on kevent().
950937
fn wakeup(self: *Loop) !void {
951-
// This constructs an empty mach message. It has no data.
952-
var msg: posix.system.mach_msg_header_t = .{
953-
.msgh_bits = @intFromEnum(posix.system.MACH_MSG_TYPE.MAKE_SEND_ONCE),
954-
.msgh_size = @sizeOf(posix.system.mach_msg_header_t),
955-
.msgh_remote_port = self.mach_port,
956-
.msgh_local_port = posix.system.MACH_PORT_NULL,
957-
.msgh_voucher_port = undefined,
958-
.msgh_id = undefined,
959-
};
960-
961-
return switch (posix.system.getMachMsgError(
962-
posix.system.mach_msg(
963-
&msg,
964-
posix.system.MACH_SEND_MSG,
965-
msg.msgh_size,
966-
0,
967-
posix.system.MACH_PORT_NULL,
968-
posix.system.MACH_MSG_TIMEOUT_NONE,
969-
posix.system.MACH_PORT_NULL,
970-
),
971-
)) {
972-
.SUCCESS => {},
973-
.SEND_NO_BUFFER => {}, // Buffer full, will wake up
974-
else => error.MachMsgFailed,
975-
};
938+
try self.mach_port.notify();
976939
}
977940
};
978941

0 commit comments

Comments
 (0)