| ... | ... | @@ -1871,6 +1871,7 @@ pub const StreamServer = struct { |
| 1871 | 1871 | kernel_backlog: u31, |
| 1872 | 1872 | reuse_address: bool, |
| 1873 | 1873 | reuse_port: bool, |
| 1874 | force_nonblocking: bool, |
| 1874 | 1875 | |
| 1875 | 1876 | /// `undefined` until `listen` returns successfully. |
| 1876 | 1877 | listen_address: Address, |
| ... | ... | @@ -1888,6 +1889,9 @@ pub const StreamServer = struct { |
| 1888 | 1889 | |
| 1889 | 1890 | /// Enable SO.REUSEPORT on the socket. |
| 1890 | 1891 | reuse_port: bool = false, |
| 1892 | |
| 1893 | /// Force non-blocking mode. |
| 1894 | force_nonblocking: bool = false, |
| 1891 | 1895 | }; |
| 1892 | 1896 | |
| 1893 | 1897 | /// After this call succeeds, resources have been acquired and must |
| ... | ... | @@ -1898,6 +1902,7 @@ pub const StreamServer = struct { |
| 1898 | 1902 | .kernel_backlog = options.kernel_backlog, |
| 1899 | 1903 | .reuse_address = options.reuse_address, |
| 1900 | 1904 | .reuse_port = options.reuse_port, |
| 1905 | .force_nonblocking = options.force_nonblocking, |
| 1901 | 1906 | .listen_address = undefined, |
| 1902 | 1907 | }; |
| 1903 | 1908 | } |
| ... | ... | @@ -1911,9 +1916,11 @@ pub const StreamServer = struct { |
| 1911 | 1916 | pub fn listen(self: *StreamServer, address: Address) !void { |
| 1912 | 1917 | const nonblock = if (std.io.is_async) os.SOCK.NONBLOCK else 0; |
| 1913 | 1918 | const sock_flags = os.SOCK.STREAM | os.SOCK.CLOEXEC | nonblock; |
| 1919 | var use_sock_flags: u32 = sock_flags; |
| 1920 | if (self.force_nonblocking) use_sock_flags |= os.SOCK.NONBLOCK; |
| 1914 | 1921 | const proto = if (address.any.family == os.AF.UNIX) @as(u32, 0) else os.IPPROTO.TCP; |
| 1915 | 1922 | |
| 1916 | | const sockfd = try os.socket(address.any.family, sock_flags, proto); |
| 1923 | const sockfd = try os.socket(address.any.family, use_sock_flags, proto); |
| 1917 | 1924 | self.sockfd = sockfd; |
| 1918 | 1925 | errdefer { |
| 1919 | 1926 | os.closeSocket(sockfd); |
| ... | ... | @@ -1963,8 +1970,8 @@ pub const StreamServer = struct { |
| 1963 | 1970 | /// The system-wide limit on the total number of open files has been reached. |
| 1964 | 1971 | SystemFdQuotaExceeded, |
| 1965 | 1972 | |
| 1966 | | /// Not enough free memory. This often means that the memory allocation is limited |
| 1967 | | /// by the socket buffer limits, not by the system memory. |
| 1973 | /// Not enough free memory. This often means that the memory allocation |
| 1974 | /// is limited by the socket buffer limits, not by the system memory. |
| 1968 | 1975 | SystemResources, |
| 1969 | 1976 | |
| 1970 | 1977 | /// Socket is not listening for new connections. |
| ... | ... | @@ -1972,6 +1979,9 @@ pub const StreamServer = struct { |
| 1972 | 1979 | |
| 1973 | 1980 | ProtocolFailure, |
| 1974 | 1981 | |
| 1982 | /// Socket is in non-blocking mode and there is no connection to accept. |
| 1983 | WouldBlock, |
| 1984 | |
| 1975 | 1985 | /// Firewall rules forbid connection. |
| 1976 | 1986 | BlockedByFirewall, |
| 1977 | 1987 | |
| ... | ... | @@ -2007,9 +2017,8 @@ pub const StreamServer = struct { |
| 2007 | 2017 | .stream = Stream{ .handle = fd }, |
| 2008 | 2018 | .address = accepted_addr, |
| 2009 | 2019 | }; |
| 2010 | | } else |err| switch (err) { |
| 2011 | | error.WouldBlock => unreachable, |
| 2012 | | else => |e| return e, |
| 2020 | } else |err| { |
| 2021 | return err; |
| 2013 | 2022 | } |
| 2014 | 2023 | } |
| 2015 | 2024 | }; |