| author | |
| committer | |
| log | e85c89630e78ccc0e4bab44064779a07a029cecd |
| tree | ad8818dd35b5a9a0f781a69bb2c2a3fe6a681cb9 |
| parent | bd89bd6fdbcc0ce5ea7763a8043fd46099022b19 |
Signed-off-by: Loris Cro <kappaloris@gmail.com>3 files changed, 45 insertions(+), 11 deletions(-)
lib/std/event/loop.zig+34| ... | ... | @@ -720,6 +720,40 @@ pub const Loop = struct { |
| 720 | 720 | } |
| 721 | 721 | } |
| 722 | 722 | |
| 723 | /// ------- I/0 APIs ------- | |
| 724 | pub fn accept( | |
| 725 | self: *Loop, | |
| 726 | /// This argument is a socket that has been created with `socket`, bound to a local address | |
| 727 | /// with `bind`, and is listening for connections after a `listen`. | |
| 728 | sockfd: os.fd_t, | |
| 729 | /// This argument is a pointer to a sockaddr structure. This structure is filled in with the | |
| 730 | /// address of the peer socket, as known to the communications layer. The exact format of the | |
| 731 | /// address returned addr is determined by the socket's address family (see `socket` and the | |
| 732 | /// respective protocol man pages). | |
| 733 | addr: *os.sockaddr, | |
| 734 | /// This argument is a value-result argument: the caller must initialize it to contain the | |
| 735 | /// size (in bytes) of the structure pointed to by addr; on return it will contain the actual size | |
| 736 | /// of the peer address. | |
| 737 | /// | |
| 738 | /// The returned address is truncated if the buffer provided is too small; in this case, `addr_size` | |
| 739 | /// will return a value greater than was supplied to the call. | |
| 740 | addr_size: *os.socklen_t, | |
| 741 | /// The following values can be bitwise ORed in flags to obtain different behavior: | |
| 742 | /// * `SOCK_CLOEXEC` - Set the close-on-exec (`FD_CLOEXEC`) flag on the new file descriptor. See the | |
| 743 | /// description of the `O_CLOEXEC` flag in `open` for reasons why this may be useful. | |
| 744 | flags: u32, | |
| 745 | ) os.AcceptError!os.fd_t { | |
| 746 | while (true) { | |
| 747 | return os.accept(sockfd, addr, addr_size, flags | os.SOCK_NONBLOCK) catch |err| switch (err) { | |
| 748 | error.WouldBlock => { | |
| 749 | self.waitUntilFdReadable(sockfd); | |
| 750 | continue; | |
| 751 | }, | |
| 752 | else => return err, | |
| 753 | }; | |
| 754 | } | |
| 755 | } | |
| 756 | ||
| 723 | 757 | /// Performs an async `os.open` using a separate thread. |
| 724 | 758 | pub fn openZ(self: *Loop, file_path: [*:0]const u8, flags: u32, mode: os.mode_t) os.OpenError!os.fd_t { |
| 725 | 759 | var req_node = Request.Node{ |
lib/std/net.zig+10-5| ... | ... | @@ -1661,18 +1661,23 @@ pub const StreamServer = struct { |
| 1661 | 1661 | |
| 1662 | 1662 | /// If this function succeeds, the returned `Connection` is a caller-managed resource. |
| 1663 | 1663 | pub fn accept(self: *StreamServer) AcceptError!Connection { |
| 1664 | const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0; | |
| 1665 | const accept_flags = nonblock | os.SOCK_CLOEXEC; | |
| 1666 | 1664 | var accepted_addr: Address = undefined; |
| 1667 | 1665 | var adr_len: os.socklen_t = @sizeOf(Address); |
| 1668 | if (os.accept(self.sockfd.?, &accepted_addr.any, &adr_len, accept_flags)) |fd| { | |
| 1666 | const accept_result = blk: { | |
| 1667 | if (std.io.is_async) { | |
| 1668 | const loop = std.event.Loop.instance orelse return error.UnexpectedError; | |
| 1669 | break :blk loop.accept(self.sockfd.?, &accepted_addr.any, &adr_len, os.SOCK_CLOEXEC); | |
| 1670 | } else { | |
| 1671 | break :blk os.accept(self.sockfd.?, &accepted_addr.any, &adr_len, os.SOCK_CLOEXEC); | |
| 1672 | } | |
| 1673 | }; | |
| 1674 | ||
| 1675 | if (accept_result) |fd| { | |
| 1669 | 1676 | return Connection{ |
| 1670 | 1677 | .file = fs.File{ .handle = fd }, |
| 1671 | 1678 | .address = accepted_addr, |
| 1672 | 1679 | }; |
| 1673 | 1680 | } else |err| switch (err) { |
| 1674 | // We only give SOCK_NONBLOCK when I/O mode is async, in which case this error | |
| 1675 | // is handled by os.accept4. | |
| 1676 | 1681 | error.WouldBlock => unreachable, |
| 1677 | 1682 | else => |e| return e, |
| 1678 | 1683 | } |
lib/std/os.zig+1-6| ... | ... | @@ -2890,12 +2890,7 @@ pub fn accept( |
| 2890 | 2890 | return fd; |
| 2891 | 2891 | }, |
| 2892 | 2892 | EINTR => continue, |
| 2893 | EAGAIN => if (std.event.Loop.instance) |loop| { | |
| 2894 | loop.waitUntilFdReadable(sockfd); | |
| 2895 | continue; | |
| 2896 | } else { | |
| 2897 | return error.WouldBlock; | |
| 2898 | }, | |
| 2893 | EAGAIN => return error.WouldBlock, | |
| 2899 | 2894 | EBADF => unreachable, // always a race condition |
| 2900 | 2895 | ECONNABORTED => return error.ConnectionAborted, |
| 2901 | 2896 | EFAULT => unreachable, |