| ... | ... | @@ -2277,81 +2277,84 @@ fn operate(userdata: ?*anyopaque, operations: []Io.Operation) void { |
| 2277 | 2277 | |
| 2278 | 2278 | var poll_buffer: [poll_buffer_len]posix.pollfd = undefined; |
| 2279 | 2279 | var map_buffer: [poll_buffer_len]u8 = undefined; // poll_buffer index to operations index |
| 2280 | | var poll_i: usize = 0; |
| 2281 | | |
| 2282 | | // Put all the file reads with nonblocking enabled into the poll set. |
| 2283 | | if (operations.len > poll_buffer.len) @panic("TODO"); |
| 2284 | | |
| 2285 | | for (operations, 0..) |*operation, operation_index| switch (operation.*) { |
| 2286 | | .noop => continue, |
| 2287 | | .file_read_streaming => |*o| { |
| 2288 | | if (o.nonblocking) { |
| 2289 | | o.result = error.WouldBlock; |
| 2290 | | poll_buffer[poll_i] = .{ |
| 2291 | | .fd = o.file.handle, |
| 2292 | | .events = posix.POLL.IN, |
| 2293 | | .revents = undefined, |
| 2294 | | }; |
| 2295 | | map_buffer[poll_i] = @intCast(operation_index); |
| 2296 | | poll_i += 1; |
| 2297 | | } else { |
| 2298 | | o.result = fileReadStreaming(o.file, o.data) catch |err| switch (err) { |
| 2299 | | error.Canceled => { |
| 2300 | | setOperationsCanceled(operations[operation_index..]); |
| 2301 | | return; |
| 2302 | | }, |
| 2303 | | else => err, |
| 2304 | | }; |
| 2280 | var operation_index: usize = 0; |
| 2281 | |
| 2282 | while (operation_index < operations.len) { |
| 2283 | var poll_i: usize = 0; |
| 2284 | while (operation_index < operations.len) : (operation_index += 1) { |
| 2285 | switch (operations[operation_index]) { |
| 2286 | .noop => continue, |
| 2287 | .file_read_streaming => |*o| { |
| 2288 | if (o.nonblocking) { |
| 2289 | o.result = error.WouldBlock; |
| 2290 | poll_buffer[poll_i] = .{ |
| 2291 | .fd = o.file.handle, |
| 2292 | .events = posix.POLL.IN, |
| 2293 | .revents = 0, |
| 2294 | }; |
| 2295 | if (map_buffer.len - poll_i == 0) break; |
| 2296 | map_buffer[poll_i] = @intCast(operation_index); |
| 2297 | poll_i += 1; |
| 2298 | } else { |
| 2299 | o.result = fileReadStreaming(o.file, o.data) catch |err| switch (err) { |
| 2300 | error.Canceled => { |
| 2301 | setOperationsError(operations[operation_index..], error.Canceled); |
| 2302 | return; |
| 2303 | }, |
| 2304 | else => err, |
| 2305 | }; |
| 2306 | } |
| 2307 | }, |
| 2305 | 2308 | } |
| 2306 | | }, |
| 2307 | | }; |
| 2308 | | |
| 2309 | | if (poll_i == 0) { |
| 2310 | | @branchHint(.likely); |
| 2311 | | return; |
| 2312 | | } |
| 2309 | } |
| 2313 | 2310 | |
| 2314 | | while (true) { |
| 2315 | | const syscall = Syscall.start() catch |err| switch (err) { |
| 2316 | | error.Canceled => { |
| 2317 | | setAllOperationsError(operations, map_buffer[0..poll_i], error.Canceled); |
| 2318 | | return; |
| 2319 | | }, |
| 2320 | | }; |
| 2321 | | const poll_rc = posix.system.poll(&poll_buffer, poll_i, -1); |
| 2322 | | syscall.finish(); |
| 2323 | | switch (posix.errno(poll_rc)) { |
| 2324 | | .SUCCESS => { |
| 2325 | | if (poll_rc == 0) { |
| 2326 | | // Spurious timeout; handle same as INTR. |
| 2327 | | continue; |
| 2328 | | } |
| 2329 | | break; |
| 2330 | | }, |
| 2331 | | .INTR => continue, |
| 2332 | | .NOMEM => { |
| 2333 | | setAllOperationsError(operations, map_buffer[0..poll_i], error.SystemResources); |
| 2334 | | return; |
| 2335 | | }, |
| 2336 | | else => { |
| 2337 | | setAllOperationsError(operations, map_buffer[0..poll_i], error.Unexpected); |
| 2338 | | return; |
| 2339 | | }, |
| 2311 | if (poll_i == 0) { |
| 2312 | @branchHint(.likely); |
| 2313 | return; |
| 2340 | 2314 | } |
| 2341 | | } |
| 2342 | 2315 | |
| 2343 | | for (poll_buffer[0..poll_i], map_buffer[0..poll_i]) |*poll_fd, operation_index| { |
| 2344 | | if (poll_fd.revents == 0) continue; |
| 2345 | | switch (operations[operation_index]) { |
| 2346 | | .noop => unreachable, |
| 2347 | | .file_read_streaming => |*o| { |
| 2348 | | o.result = fileReadStreaming(o.file, o.data); |
| 2349 | | }, |
| 2316 | while (true) { |
| 2317 | const syscall = Syscall.start() catch |err| switch (err) { |
| 2318 | error.Canceled => { |
| 2319 | setPollOperationsError(operations, map_buffer[0..poll_i], error.Canceled); |
| 2320 | setOperationsError(operations[operation_index..], error.Canceled); |
| 2321 | return; |
| 2322 | }, |
| 2323 | }; |
| 2324 | const poll_rc = posix.system.poll(&poll_buffer, poll_i, -1); |
| 2325 | syscall.finish(); |
| 2326 | switch (posix.errno(poll_rc)) { |
| 2327 | .SUCCESS => { |
| 2328 | if (poll_rc == 0) { |
| 2329 | // Spurious timeout; handle same as INTR. |
| 2330 | continue; |
| 2331 | } |
| 2332 | for (poll_buffer[0..poll_i], map_buffer[0..poll_i]) |*poll_fd, i| { |
| 2333 | if (poll_fd.revents == 0) continue; |
| 2334 | switch (operations[i]) { |
| 2335 | .noop => unreachable, |
| 2336 | .file_read_streaming => |*o| { |
| 2337 | o.result = fileReadStreaming(o.file, o.data); |
| 2338 | }, |
| 2339 | } |
| 2340 | } |
| 2341 | break; |
| 2342 | }, |
| 2343 | .INTR => continue, |
| 2344 | .NOMEM => { |
| 2345 | setPollOperationsError(operations, map_buffer[0..poll_i], error.SystemResources); |
| 2346 | break; |
| 2347 | }, |
| 2348 | else => { |
| 2349 | setPollOperationsError(operations, map_buffer[0..poll_i], error.Unexpected); |
| 2350 | break; |
| 2351 | }, |
| 2352 | } |
| 2350 | 2353 | } |
| 2351 | 2354 | } |
| 2352 | 2355 | } |
| 2353 | 2356 | |
| 2354 | | fn setAllOperationsError( |
| 2357 | fn setPollOperationsError( |
| 2355 | 2358 | operations: []Io.Operation, |
| 2356 | 2359 | map: []const u8, |
| 2357 | 2360 | err: error{ Canceled, SystemResources, Unexpected }, |
| ... | ... | @@ -2362,10 +2365,10 @@ fn setAllOperationsError( |
| 2362 | 2365 | }; |
| 2363 | 2366 | } |
| 2364 | 2367 | |
| 2365 | | fn setOperationsCanceled(operations: []Io.Operation) void { |
| 2368 | fn setOperationsError(operations: []Io.Operation, err: error{ Canceled, SystemResources, Unexpected }) void { |
| 2366 | 2369 | for (operations) |*op| switch (op.*) { |
| 2367 | 2370 | .noop => unreachable, |
| 2368 | | inline else => |*o| o.result = error.Canceled, |
| 2371 | inline else => |*o| o.result = err, |
| 2369 | 2372 | }; |
| 2370 | 2373 | } |
| 2371 | 2374 | |