Skip to content

Commit 3915e17

Browse files
committed
std: Add an experimental connect_timeout function
This adds a `TcpStream::connect_timeout` function in order to assist opening connections with a timeout (cc #13523). There isn't really much design space for this specific operation (unlike timing out normal blocking reads/writes), so I am fairly confident that this is the correct interface for this function. The function is marked #[experimental] because it takes a u64 timeout argument, and the u64 type is likely to change in the future.
1 parent 9d5082e commit 3915e17

File tree

15 files changed

+490
-145
lines changed

15 files changed

+490
-145
lines changed

src/liblibc/lib.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,14 @@ pub use types::common::c95::{FILE, c_void, fpos_t};
8787
pub use types::common::c99::{int8_t, int16_t, int32_t, int64_t};
8888
pub use types::common::c99::{uint8_t, uint16_t, uint32_t, uint64_t};
8989
pub use types::common::posix88::{DIR, dirent_t};
90+
pub use types::os::common::posix01::{timeval};
9091
pub use types::os::common::bsd44::{addrinfo, in_addr, in6_addr, sockaddr_storage};
9192
pub use types::os::common::bsd44::{ip_mreq, ip6_mreq, sockaddr, sockaddr_un};
9293
pub use types::os::common::bsd44::{sa_family_t, sockaddr_in, sockaddr_in6, socklen_t};
9394
pub use types::os::arch::c95::{c_char, c_double, c_float, c_int, c_uint};
9495
pub use types::os::arch::c95::{c_long, c_short, c_uchar, c_ulong};
9596
pub use types::os::arch::c95::{c_ushort, clock_t, ptrdiff_t};
96-
pub use types::os::arch::c95::{size_t, time_t};
97+
pub use types::os::arch::c95::{size_t, time_t, suseconds_t};
9798
pub use types::os::arch::c99::{c_longlong, c_ulonglong};
9899
pub use types::os::arch::c99::{intptr_t, uintptr_t};
99100
pub use types::os::arch::posix88::{dev_t, ino_t, mode_t};
@@ -113,7 +114,7 @@ pub use consts::os::posix88::{STDERR_FILENO, STDIN_FILENO, S_IXUSR};
113114
pub use consts::os::posix88::{STDOUT_FILENO, W_OK, X_OK};
114115
pub use consts::os::bsd44::{AF_INET, AF_INET6, SOCK_STREAM, SOCK_DGRAM};
115116
pub use consts::os::bsd44::{IPPROTO_IP, IPPROTO_IPV6, IPPROTO_TCP, TCP_NODELAY};
116-
pub use consts::os::bsd44::{SOL_SOCKET, SO_KEEPALIVE};
117+
pub use consts::os::bsd44::{SOL_SOCKET, SO_KEEPALIVE, SO_ERROR};
117118
pub use consts::os::bsd44::{SO_REUSEADDR, SO_BROADCAST, SHUT_WR, IP_MULTICAST_LOOP};
118119
pub use consts::os::bsd44::{IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP};
119120
pub use consts::os::bsd44::{IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP};
@@ -170,14 +171,13 @@ pub use funcs::bsd43::{shutdown};
170171
#[cfg(unix)] pub use consts::os::posix88::{ECONNREFUSED, ECONNRESET, EPERM, EPIPE};
171172
#[cfg(unix)] pub use consts::os::posix88::{ENOTCONN, ECONNABORTED, EADDRNOTAVAIL, EINTR};
172173
#[cfg(unix)] pub use consts::os::posix88::{EADDRINUSE, ENOENT, EISDIR, EAGAIN, EWOULDBLOCK};
173-
#[cfg(unix)] pub use consts::os::posix88::{ECANCELED, SIGINT};
174+
#[cfg(unix)] pub use consts::os::posix88::{ECANCELED, SIGINT, EINPROGRESS};
174175
#[cfg(unix)] pub use consts::os::posix88::{SIGTERM, SIGKILL, SIGPIPE, PROT_NONE};
175176
#[cfg(unix)] pub use consts::os::posix01::{SIG_IGN, WNOHANG};
176177
#[cfg(unix)] pub use consts::os::bsd44::{AF_UNIX};
177178

178-
#[cfg(unix)] pub use types::os::common::posix01::{pthread_t, timespec, timezone, timeval};
179+
#[cfg(unix)] pub use types::os::common::posix01::{pthread_t, timespec, timezone};
179180

180-
#[cfg(unix)] pub use types::os::arch::c95::{suseconds_t};
181181
#[cfg(unix)] pub use types::os::arch::posix88::{uid_t, gid_t};
182182
#[cfg(unix)] pub use types::os::arch::posix01::{pthread_attr_t};
183183
#[cfg(unix)] pub use types::os::arch::posix01::{stat, utimbuf};
@@ -195,6 +195,7 @@ pub use funcs::bsd43::{shutdown};
195195
#[cfg(windows)] pub use consts::os::c95::{WSAECONNREFUSED, WSAECONNRESET, WSAEACCES};
196196
#[cfg(windows)] pub use consts::os::c95::{WSAEWOULDBLOCK, WSAENOTCONN, WSAECONNABORTED};
197197
#[cfg(windows)] pub use consts::os::c95::{WSAEADDRNOTAVAIL, WSAEADDRINUSE, WSAEINTR};
198+
#[cfg(windows)] pub use consts::os::c95::{WSAEINPROGRESS};
198199
#[cfg(windows)] pub use consts::os::extra::{ERROR_INSUFFICIENT_BUFFER};
199200
#[cfg(windows)] pub use consts::os::extra::{O_BINARY, O_NOINHERIT, PAGE_NOACCESS};
200201
#[cfg(windows)] pub use consts::os::extra::{PAGE_READONLY, PAGE_READWRITE, PAGE_EXECUTE};
@@ -1708,6 +1709,7 @@ pub mod consts {
17081709
pub static SO_KEEPALIVE: c_int = 8;
17091710
pub static SO_BROADCAST: c_int = 32;
17101711
pub static SO_REUSEADDR: c_int = 4;
1712+
pub static SO_ERROR: c_int = 0x1007;
17111713

17121714
pub static SHUT_RD: c_int = 0;
17131715
pub static SHUT_WR: c_int = 1;
@@ -2496,6 +2498,7 @@ pub mod consts {
24962498
pub static SO_KEEPALIVE: c_int = 9;
24972499
pub static SO_BROADCAST: c_int = 6;
24982500
pub static SO_REUSEADDR: c_int = 2;
2501+
pub static SO_ERROR: c_int = 4;
24992502

25002503
pub static SHUT_RD: c_int = 0;
25012504
pub static SHUT_WR: c_int = 1;
@@ -2954,6 +2957,7 @@ pub mod consts {
29542957
pub static SO_KEEPALIVE: c_int = 0x0008;
29552958
pub static SO_BROADCAST: c_int = 0x0020;
29562959
pub static SO_REUSEADDR: c_int = 0x0004;
2960+
pub static SO_ERROR: c_int = 0x1007;
29572961

29582962
pub static SHUT_RD: c_int = 0;
29592963
pub static SHUT_WR: c_int = 1;
@@ -3340,6 +3344,7 @@ pub mod consts {
33403344
pub static SO_KEEPALIVE: c_int = 0x0008;
33413345
pub static SO_BROADCAST: c_int = 0x0020;
33423346
pub static SO_REUSEADDR: c_int = 0x0004;
3347+
pub static SO_ERROR: c_int = 0x1007;
33433348

33443349
pub static SHUT_RD: c_int = 0;
33453350
pub static SHUT_WR: c_int = 1;

src/libnative/io/c_unix.rs

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! C definitions used by libnative that don't belong in liblibc
12+
13+
pub use self::select::fd_set;
14+
15+
use libc;
16+
17+
#[cfg(target_os = "macos")]
18+
#[cfg(target_os = "freebsd")]
19+
pub static FIONBIO: libc::c_ulong = 0x8004667e;
20+
#[cfg(target_os = "linux")]
21+
#[cfg(target_os = "android")]
22+
pub static FIONBIO: libc::c_ulong = 0x5421;
23+
#[cfg(target_os = "macos")]
24+
#[cfg(target_os = "freebsd")]
25+
pub static FIOCLEX: libc::c_ulong = 0x20006601;
26+
#[cfg(target_os = "linux")]
27+
#[cfg(target_os = "android")]
28+
pub static FIOCLEX: libc::c_ulong = 0x5451;
29+
30+
extern {
31+
pub fn gettimeofday(timeval: *mut libc::timeval,
32+
tzp: *libc::c_void) -> libc::c_int;
33+
pub fn select(nfds: libc::c_int,
34+
readfds: *fd_set,
35+
writefds: *fd_set,
36+
errorfds: *fd_set,
37+
timeout: *libc::timeval) -> libc::c_int;
38+
pub fn getsockopt(sockfd: libc::c_int,
39+
level: libc::c_int,
40+
optname: libc::c_int,
41+
optval: *mut libc::c_void,
42+
optlen: *mut libc::socklen_t) -> libc::c_int;
43+
pub fn ioctl(fd: libc::c_int, req: libc::c_ulong, ...) -> libc::c_int;
44+
45+
}
46+
47+
#[cfg(target_os = "macos")]
48+
mod select {
49+
pub static FD_SETSIZE: uint = 1024;
50+
51+
pub struct fd_set {
52+
fds_bits: [i32, ..(FD_SETSIZE / 32)]
53+
}
54+
55+
pub fn fd_set(set: &mut fd_set, fd: i32) {
56+
set.fds_bits[(fd / 32) as uint] |= 1 << (fd % 32);
57+
}
58+
}
59+
60+
#[cfg(target_os = "android")]
61+
#[cfg(target_os = "freebsd")]
62+
#[cfg(target_os = "linux")]
63+
mod select {
64+
use std::uint;
65+
66+
pub static FD_SETSIZE: uint = 1024;
67+
68+
pub struct fd_set {
69+
fds_bits: [uint, ..(FD_SETSIZE / uint::BITS)]
70+
}
71+
72+
pub fn fd_set(set: &mut fd_set, fd: i32) {
73+
let fd = fd as uint;
74+
set.fds_bits[fd / uint::BITS] |= 1 << (fd % uint::BITS);
75+
}
76+
}

src/libnative/io/c_win32.rs

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! C definitions used by libnative that don't belong in liblibc
12+
13+
#![allow(type_overflow)]
14+
15+
use libc;
16+
17+
pub static WSADESCRIPTION_LEN: uint = 256;
18+
pub static WSASYS_STATUS_LEN: uint = 128;
19+
pub static FIONBIO: libc::c_long = 0x8004667e;
20+
static FD_SETSIZE: uint = 64;
21+
22+
pub struct WSADATA {
23+
pub wVersion: libc::WORD,
24+
pub wHighVersion: libc::WORD,
25+
pub szDescription: [u8, ..WSADESCRIPTION_LEN + 1],
26+
pub szSystemStatus: [u8, ..WSASYS_STATUS_LEN + 1],
27+
pub iMaxSockets: u16,
28+
pub iMaxUdpDg: u16,
29+
pub lpVendorInfo: *u8,
30+
}
31+
32+
pub type LPWSADATA = *mut WSADATA;
33+
34+
pub struct fd_set {
35+
fd_count: libc::c_uint,
36+
fd_array: [libc::SOCKET, ..FD_SETSIZE],
37+
}
38+
39+
pub fn fd_set(set: &mut fd_set, s: libc::SOCKET) {
40+
set.fd_array[set.fd_count as uint] = s;
41+
set.fd_count += 1;
42+
}
43+
44+
#[link(name = "ws2_32")]
45+
extern "system" {
46+
pub fn WSAStartup(wVersionRequested: libc::WORD,
47+
lpWSAData: LPWSADATA) -> libc::c_int;
48+
pub fn WSAGetLastError() -> libc::c_int;
49+
50+
pub fn ioctlsocket(s: libc::SOCKET, cmd: libc::c_long,
51+
argp: *mut libc::c_ulong) -> libc::c_int;
52+
pub fn select(nfds: libc::c_int,
53+
readfds: *mut fd_set,
54+
writefds: *mut fd_set,
55+
exceptfds: *mut fd_set,
56+
timeout: *libc::timeval) -> libc::c_int;
57+
pub fn getsockopt(sockfd: libc::SOCKET,
58+
level: libc::c_int,
59+
optname: libc::c_int,
60+
optval: *mut libc::c_char,
61+
optlen: *mut libc::c_int) -> libc::c_int;
62+
}

src/libnative/io/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ pub mod pipe;
7171
#[path = "pipe_win32.rs"]
7272
pub mod pipe;
7373

74+
#[cfg(unix)] #[path = "c_unix.rs"] mod c;
75+
#[cfg(windows)] #[path = "c_win32.rs"] mod c;
76+
7477
mod timer_helper;
7578

7679
pub type IoResult<T> = Result<T, IoError>;
@@ -161,8 +164,9 @@ impl IoFactory {
161164

162165
impl rtio::IoFactory for IoFactory {
163166
// networking
164-
fn tcp_connect(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpStream:Send> {
165-
net::TcpStream::connect(addr).map(|s| ~s as ~RtioTcpStream:Send)
167+
fn tcp_connect(&mut self, addr: SocketAddr,
168+
timeout: Option<u64>) -> IoResult<~RtioTcpStream:Send> {
169+
net::TcpStream::connect(addr, timeout).map(|s| ~s as ~RtioTcpStream:Send)
166170
}
167171
fn tcp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpListener:Send> {
168172
net::TcpListener::bind(addr).map(|s| ~s as ~RtioTcpListener:Send)

0 commit comments

Comments
 (0)