| ... | ... | @@ -423,17 +423,35 @@ fn idle(k: *Kqueue, thread: *Thread) void { |
| 423 | 423 | return; |
| 424 | 424 | }, |
| 425 | 425 | _ => { |
| 426 | | const fiber: *Fiber = @ptrFromInt(event.udata); |
| 427 | | assert(fiber.queue_next == null); |
| 428 | | fiber.resultPointer(Completion).* = .{ |
| 426 | const event_head_fiber: *Fiber = @ptrFromInt(event.udata); |
| 427 | const event_tail_fiber = thread.wait_queues.fetchSwapRemove(.{ |
| 428 | .ident = event.ident, |
| 429 | .filter = event.filter, |
| 430 | }).?.value; |
| 431 | assert(event_tail_fiber.queue_next == null); |
| 432 | |
| 433 | // TODO reevaluate this logic |
| 434 | event_head_fiber.resultPointer(Completion).* = .{ |
| 429 | 435 | .flags = event.flags, |
| 430 | 436 | .fflags = event.fflags, |
| 431 | 437 | .data = event.data, |
| 432 | 438 | }; |
| 433 | | if (maybe_ready_fiber == null) maybe_ready_fiber = fiber else if (maybe_ready_queue) |*ready_queue| { |
| 434 | | ready_queue.tail.queue_next = fiber; |
| 435 | | ready_queue.tail = fiber; |
| 436 | | } else maybe_ready_queue = .{ .head = fiber, .tail = fiber }; |
| 439 | |
| 440 | queue_ready: { |
| 441 | const head: *Fiber = if (maybe_ready_fiber == null) f: { |
| 442 | maybe_ready_fiber = event_head_fiber; |
| 443 | const next = event_head_fiber.queue_next orelse break :queue_ready; |
| 444 | event_head_fiber.queue_next = null; |
| 445 | break :f next; |
| 446 | } else event_head_fiber; |
| 447 | |
| 448 | if (maybe_ready_queue) |*ready_queue| { |
| 449 | ready_queue.tail.queue_next = head; |
| 450 | ready_queue.tail = event_tail_fiber; |
| 451 | } else { |
| 452 | maybe_ready_queue = .{ .head = head, .tail = event_tail_fiber }; |
| 453 | } |
| 454 | } |
| 437 | 455 | }, |
| 438 | 456 | }; |
| 439 | 457 | if (maybe_ready_queue) |ready_queue| k.schedule(thread, ready_queue); |
| ... | ... | @@ -1477,7 +1495,6 @@ fn netRead(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Strea |
| 1477 | 1495 | |
| 1478 | 1496 | while (true) { |
| 1479 | 1497 | try k.checkCancel(); |
| 1480 | | std.debug.print("calling readv\n", .{}); |
| 1481 | 1498 | const rc = posix.system.readv(fd, dest.ptr, @intCast(dest.len)); |
| 1482 | 1499 | switch (posix.errno(rc)) { |
| 1483 | 1500 | .SUCCESS => return @intCast(rc), |
| ... | ... | @@ -1486,19 +1503,33 @@ fn netRead(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Strea |
| 1486 | 1503 | .AGAIN => { |
| 1487 | 1504 | const thread: *Thread = .current(); |
| 1488 | 1505 | const fiber = thread.currentFiber(); |
| 1489 | | const changes = [_]posix.Kevent{ |
| 1490 | | .{ |
| 1491 | | .ident = @as(u32, @bitCast(fd)), |
| 1492 | | .filter = std.c.EVFILT.READ, |
| 1493 | | .flags = std.c.EV.ADD | std.c.EV.ONESHOT, |
| 1494 | | .fflags = 0, |
| 1495 | | .data = 0, |
| 1496 | | .udata = @intFromPtr(fiber), |
| 1497 | | }, |
| 1498 | | }; |
| 1499 | | assert(0 == (posix.kevent(thread.kq_fd, &changes, &.{}, null) catch |err| { |
| 1500 | | @panic(@errorName(err)); // TODO |
| 1501 | | })); |
| 1506 | const ident: u32 = @bitCast(fd); |
| 1507 | const filter = std.c.EVFILT.READ; |
| 1508 | const gop = thread.wait_queues.getOrPut(k.gpa, .{ |
| 1509 | .ident = ident, |
| 1510 | .filter = filter, |
| 1511 | }) catch return error.SystemResources; |
| 1512 | if (gop.found_existing) { |
| 1513 | const tail_fiber = gop.value_ptr.*; |
| 1514 | assert(tail_fiber.queue_next == null); |
| 1515 | tail_fiber.queue_next = fiber; |
| 1516 | gop.value_ptr.* = fiber; |
| 1517 | } else { |
| 1518 | gop.value_ptr.* = fiber; |
| 1519 | const changes = [_]posix.Kevent{ |
| 1520 | .{ |
| 1521 | .ident = ident, |
| 1522 | .filter = filter, |
| 1523 | .flags = std.c.EV.ADD | std.c.EV.ONESHOT, |
| 1524 | .fflags = 0, |
| 1525 | .data = 0, |
| 1526 | .udata = @intFromPtr(fiber), |
| 1527 | }, |
| 1528 | }; |
| 1529 | assert(0 == (posix.kevent(thread.kq_fd, &changes, &.{}, null) catch |err| { |
| 1530 | @panic(@errorName(err)); // TODO |
| 1531 | })); |
| 1532 | } |
| 1502 | 1533 | yield(k, null, .nothing); |
| 1503 | 1534 | continue; |
| 1504 | 1535 | }, |