An asynchronous IO runtime

mock: track open file descriptors

rockorager.dev 658cb01c e00f6a02

verified
+24
+24
src/ourio/Mock.zig
··· 10 const posix = std.posix; 11 12 completions: Queue(io.Task, .complete) = .{}, 13 14 accept_cb: ?*const fn (*io.Task) io.Result = null, 15 cancel_cb: ?*const fn (*io.Task) io.Result = null, ··· 39 } 40 41 pub fn deinit(self: *Mock, _: Allocator) void { 42 self.* = undefined; 43 } 44 ··· 79 .socket => if (self.socket_cb) |cb| cb(task) else return error.NoMockCallback, 80 .statx => if (self.statx_cb) |cb| cb(task) else return error.NoMockCallback, 81 .timer => if (self.timer_cb) |cb| cb(task) else return error.NoMockCallback, 82 .userfd => if (self.userfd_cb) |cb| cb(task) else return error.NoMockCallback, 83 .usermsg => if (self.usermsg_cb) |cb| cb(task) else return error.NoMockCallback, 84 .userptr => if (self.userptr_cb) |cb| cb(task) else return error.NoMockCallback, 85 .write => if (self.write_cb) |cb| cb(task) else return error.NoMockCallback, 86 .writev => if (self.writev_cb) |cb| cb(task) else return error.NoMockCallback, 87 }; 88 self.completions.push(task); 89 } 90 }
··· 10 const posix = std.posix; 11 12 completions: Queue(io.Task, .complete) = .{}, 13 + open_fds: i64 = 0, 14 15 accept_cb: ?*const fn (*io.Task) io.Result = null, 16 cancel_cb: ?*const fn (*io.Task) io.Result = null, ··· 40 } 41 42 pub fn deinit(self: *Mock, _: Allocator) void { 43 + if (self.open_fds > 0) { 44 + @panic("file descriptor leak"); 45 + } 46 + if (self.open_fds < 0) { 47 + @panic("unbalanced file descriptor close"); 48 + } 49 self.* = undefined; 50 } 51 ··· 86 .socket => if (self.socket_cb) |cb| cb(task) else return error.NoMockCallback, 87 .statx => if (self.statx_cb) |cb| cb(task) else return error.NoMockCallback, 88 .timer => if (self.timer_cb) |cb| cb(task) else return error.NoMockCallback, 89 + .userbytes => if (self.userbytes_cb) |cb| cb(task) else return error.NoMockCallback, 90 .userfd => if (self.userfd_cb) |cb| cb(task) else return error.NoMockCallback, 91 .usermsg => if (self.usermsg_cb) |cb| cb(task) else return error.NoMockCallback, 92 .userptr => if (self.userptr_cb) |cb| cb(task) else return error.NoMockCallback, 93 .write => if (self.write_cb) |cb| cb(task) else return error.NoMockCallback, 94 .writev => if (self.writev_cb) |cb| cb(task) else return error.NoMockCallback, 95 }; 96 + 97 + switch (task.result.?) { 98 + .accept => |accept| { 99 + if (accept) |_| self.open_fds += 1 else |_| {} 100 + }, 101 + .open => |open| { 102 + if (open) |_| self.open_fds += 1 else |_| {} 103 + }, 104 + .socket => |socket| { 105 + if (socket) |_| self.open_fds += 1 else |_| {} 106 + }, 107 + .close => |close| { 108 + if (close) |_| self.open_fds -= 1 else |_| {} 109 + }, 110 + else => {}, 111 + } 112 self.completions.push(task); 113 } 114 }