authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2020-06-16 22:38:51+02:00
committergravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2020-09-24 21:56:27+02:00
loge85c89630e78ccc0e4bab44064779a07a029cecd
treead8818dd35b5a9a0f781a69bb2c2a3fe6a681cb9
parentbd89bd6fdbcc0ce5ea7763a8043fd46099022b19

accept

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 {
720720 }
721721 }
722722
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
723757 /// Performs an async `os.open` using a separate thread.
724758 pub fn openZ(self: *Loop, file_path: [*:0]const u8, flags: u32, mode: os.mode_t) os.OpenError!os.fd_t {
725759 var req_node = Request.Node{
lib/std/net.zig+10-5
......@@ -1661,18 +1661,23 @@ pub const StreamServer = struct {
16611661
16621662 /// If this function succeeds, the returned `Connection` is a caller-managed resource.
16631663 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;
16661664 var accepted_addr: Address = undefined;
16671665 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| {
16691676 return Connection{
16701677 .file = fs.File{ .handle = fd },
16711678 .address = accepted_addr,
16721679 };
16731680 } 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.
16761681 error.WouldBlock => unreachable,
16771682 else => |e| return e,
16781683 }
lib/std/os.zig+1-6
......@@ -2890,12 +2890,7 @@ pub fn accept(
28902890 return fd;
28912891 },
28922892 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,
28992894 EBADF => unreachable, // always a race condition
29002895 ECONNABORTED => return error.ConnectionAborted,
29012896 EFAULT => unreachable,