Skip to content

Commit

Permalink
std: Add an experimental connect_timeout function
Browse files Browse the repository at this point in the history
This adds a `TcpStream::connect_timeout` function in order to assist opening
connections with a timeout (cc rust-lang#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.
  • Loading branch information
alexcrichton committed Apr 19, 2014
1 parent 9d5082e commit 3915e17
Show file tree
Hide file tree
Showing 15 changed files with 490 additions and 145 deletions.
15 changes: 10 additions & 5 deletions src/liblibc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,14 @@ pub use types::common::c95::{FILE, c_void, fpos_t};
pub use types::common::c99::{int8_t, int16_t, int32_t, int64_t};
pub use types::common::c99::{uint8_t, uint16_t, uint32_t, uint64_t};
pub use types::common::posix88::{DIR, dirent_t};
pub use types::os::common::posix01::{timeval};
pub use types::os::common::bsd44::{addrinfo, in_addr, in6_addr, sockaddr_storage};
pub use types::os::common::bsd44::{ip_mreq, ip6_mreq, sockaddr, sockaddr_un};
pub use types::os::common::bsd44::{sa_family_t, sockaddr_in, sockaddr_in6, socklen_t};
pub use types::os::arch::c95::{c_char, c_double, c_float, c_int, c_uint};
pub use types::os::arch::c95::{c_long, c_short, c_uchar, c_ulong};
pub use types::os::arch::c95::{c_ushort, clock_t, ptrdiff_t};
pub use types::os::arch::c95::{size_t, time_t};
pub use types::os::arch::c95::{size_t, time_t, suseconds_t};
pub use types::os::arch::c99::{c_longlong, c_ulonglong};
pub use types::os::arch::c99::{intptr_t, uintptr_t};
pub use types::os::arch::posix88::{dev_t, ino_t, mode_t};
Expand All @@ -113,7 +114,7 @@ pub use consts::os::posix88::{STDERR_FILENO, STDIN_FILENO, S_IXUSR};
pub use consts::os::posix88::{STDOUT_FILENO, W_OK, X_OK};
pub use consts::os::bsd44::{AF_INET, AF_INET6, SOCK_STREAM, SOCK_DGRAM};
pub use consts::os::bsd44::{IPPROTO_IP, IPPROTO_IPV6, IPPROTO_TCP, TCP_NODELAY};
pub use consts::os::bsd44::{SOL_SOCKET, SO_KEEPALIVE};
pub use consts::os::bsd44::{SOL_SOCKET, SO_KEEPALIVE, SO_ERROR};
pub use consts::os::bsd44::{SO_REUSEADDR, SO_BROADCAST, SHUT_WR, IP_MULTICAST_LOOP};
pub use consts::os::bsd44::{IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP};
pub use consts::os::bsd44::{IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP};
Expand Down Expand Up @@ -170,14 +171,13 @@ pub use funcs::bsd43::{shutdown};
#[cfg(unix)] pub use consts::os::posix88::{ECONNREFUSED, ECONNRESET, EPERM, EPIPE};
#[cfg(unix)] pub use consts::os::posix88::{ENOTCONN, ECONNABORTED, EADDRNOTAVAIL, EINTR};
#[cfg(unix)] pub use consts::os::posix88::{EADDRINUSE, ENOENT, EISDIR, EAGAIN, EWOULDBLOCK};
#[cfg(unix)] pub use consts::os::posix88::{ECANCELED, SIGINT};
#[cfg(unix)] pub use consts::os::posix88::{ECANCELED, SIGINT, EINPROGRESS};
#[cfg(unix)] pub use consts::os::posix88::{SIGTERM, SIGKILL, SIGPIPE, PROT_NONE};
#[cfg(unix)] pub use consts::os::posix01::{SIG_IGN, WNOHANG};
#[cfg(unix)] pub use consts::os::bsd44::{AF_UNIX};

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

#[cfg(unix)] pub use types::os::arch::c95::{suseconds_t};
#[cfg(unix)] pub use types::os::arch::posix88::{uid_t, gid_t};
#[cfg(unix)] pub use types::os::arch::posix01::{pthread_attr_t};
#[cfg(unix)] pub use types::os::arch::posix01::{stat, utimbuf};
Expand All @@ -195,6 +195,7 @@ pub use funcs::bsd43::{shutdown};
#[cfg(windows)] pub use consts::os::c95::{WSAECONNREFUSED, WSAECONNRESET, WSAEACCES};
#[cfg(windows)] pub use consts::os::c95::{WSAEWOULDBLOCK, WSAENOTCONN, WSAECONNABORTED};
#[cfg(windows)] pub use consts::os::c95::{WSAEADDRNOTAVAIL, WSAEADDRINUSE, WSAEINTR};
#[cfg(windows)] pub use consts::os::c95::{WSAEINPROGRESS};
#[cfg(windows)] pub use consts::os::extra::{ERROR_INSUFFICIENT_BUFFER};
#[cfg(windows)] pub use consts::os::extra::{O_BINARY, O_NOINHERIT, PAGE_NOACCESS};
#[cfg(windows)] pub use consts::os::extra::{PAGE_READONLY, PAGE_READWRITE, PAGE_EXECUTE};
Expand Down Expand Up @@ -1708,6 +1709,7 @@ pub mod consts {
pub static SO_KEEPALIVE: c_int = 8;
pub static SO_BROADCAST: c_int = 32;
pub static SO_REUSEADDR: c_int = 4;
pub static SO_ERROR: c_int = 0x1007;

pub static SHUT_RD: c_int = 0;
pub static SHUT_WR: c_int = 1;
Expand Down Expand Up @@ -2496,6 +2498,7 @@ pub mod consts {
pub static SO_KEEPALIVE: c_int = 9;
pub static SO_BROADCAST: c_int = 6;
pub static SO_REUSEADDR: c_int = 2;
pub static SO_ERROR: c_int = 4;

pub static SHUT_RD: c_int = 0;
pub static SHUT_WR: c_int = 1;
Expand Down Expand Up @@ -2954,6 +2957,7 @@ pub mod consts {
pub static SO_KEEPALIVE: c_int = 0x0008;
pub static SO_BROADCAST: c_int = 0x0020;
pub static SO_REUSEADDR: c_int = 0x0004;
pub static SO_ERROR: c_int = 0x1007;

pub static SHUT_RD: c_int = 0;
pub static SHUT_WR: c_int = 1;
Expand Down Expand Up @@ -3340,6 +3344,7 @@ pub mod consts {
pub static SO_KEEPALIVE: c_int = 0x0008;
pub static SO_BROADCAST: c_int = 0x0020;
pub static SO_REUSEADDR: c_int = 0x0004;
pub static SO_ERROR: c_int = 0x1007;

pub static SHUT_RD: c_int = 0;
pub static SHUT_WR: c_int = 1;
Expand Down
76 changes: 76 additions & 0 deletions src/libnative/io/c_unix.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! C definitions used by libnative that don't belong in liblibc
pub use self::select::fd_set;

use libc;

#[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")]
pub static FIONBIO: libc::c_ulong = 0x8004667e;
#[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
pub static FIONBIO: libc::c_ulong = 0x5421;
#[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")]
pub static FIOCLEX: libc::c_ulong = 0x20006601;
#[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
pub static FIOCLEX: libc::c_ulong = 0x5451;

extern {
pub fn gettimeofday(timeval: *mut libc::timeval,
tzp: *libc::c_void) -> libc::c_int;
pub fn select(nfds: libc::c_int,
readfds: *fd_set,
writefds: *fd_set,
errorfds: *fd_set,
timeout: *libc::timeval) -> libc::c_int;
pub fn getsockopt(sockfd: libc::c_int,
level: libc::c_int,
optname: libc::c_int,
optval: *mut libc::c_void,
optlen: *mut libc::socklen_t) -> libc::c_int;
pub fn ioctl(fd: libc::c_int, req: libc::c_ulong, ...) -> libc::c_int;

}

#[cfg(target_os = "macos")]
mod select {
pub static FD_SETSIZE: uint = 1024;

pub struct fd_set {
fds_bits: [i32, ..(FD_SETSIZE / 32)]
}

pub fn fd_set(set: &mut fd_set, fd: i32) {
set.fds_bits[(fd / 32) as uint] |= 1 << (fd % 32);
}
}

#[cfg(target_os = "android")]
#[cfg(target_os = "freebsd")]
#[cfg(target_os = "linux")]
mod select {
use std::uint;

pub static FD_SETSIZE: uint = 1024;

pub struct fd_set {
fds_bits: [uint, ..(FD_SETSIZE / uint::BITS)]
}

pub fn fd_set(set: &mut fd_set, fd: i32) {
let fd = fd as uint;
set.fds_bits[fd / uint::BITS] |= 1 << (fd % uint::BITS);
}
}
62 changes: 62 additions & 0 deletions src/libnative/io/c_win32.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! C definitions used by libnative that don't belong in liblibc
#![allow(type_overflow)]

use libc;

pub static WSADESCRIPTION_LEN: uint = 256;
pub static WSASYS_STATUS_LEN: uint = 128;
pub static FIONBIO: libc::c_long = 0x8004667e;
static FD_SETSIZE: uint = 64;

pub struct WSADATA {
pub wVersion: libc::WORD,
pub wHighVersion: libc::WORD,
pub szDescription: [u8, ..WSADESCRIPTION_LEN + 1],
pub szSystemStatus: [u8, ..WSASYS_STATUS_LEN + 1],
pub iMaxSockets: u16,
pub iMaxUdpDg: u16,
pub lpVendorInfo: *u8,
}

pub type LPWSADATA = *mut WSADATA;

pub struct fd_set {
fd_count: libc::c_uint,
fd_array: [libc::SOCKET, ..FD_SETSIZE],
}

pub fn fd_set(set: &mut fd_set, s: libc::SOCKET) {
set.fd_array[set.fd_count as uint] = s;
set.fd_count += 1;
}

#[link(name = "ws2_32")]
extern "system" {
pub fn WSAStartup(wVersionRequested: libc::WORD,
lpWSAData: LPWSADATA) -> libc::c_int;
pub fn WSAGetLastError() -> libc::c_int;

pub fn ioctlsocket(s: libc::SOCKET, cmd: libc::c_long,
argp: *mut libc::c_ulong) -> libc::c_int;
pub fn select(nfds: libc::c_int,
readfds: *mut fd_set,
writefds: *mut fd_set,
exceptfds: *mut fd_set,
timeout: *libc::timeval) -> libc::c_int;
pub fn getsockopt(sockfd: libc::SOCKET,
level: libc::c_int,
optname: libc::c_int,
optval: *mut libc::c_char,
optlen: *mut libc::c_int) -> libc::c_int;
}
8 changes: 6 additions & 2 deletions src/libnative/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ pub mod pipe;
#[path = "pipe_win32.rs"]
pub mod pipe;

#[cfg(unix)] #[path = "c_unix.rs"] mod c;
#[cfg(windows)] #[path = "c_win32.rs"] mod c;

mod timer_helper;

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

impl rtio::IoFactory for IoFactory {
// networking
fn tcp_connect(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpStream:Send> {
net::TcpStream::connect(addr).map(|s| ~s as ~RtioTcpStream:Send)
fn tcp_connect(&mut self, addr: SocketAddr,
timeout: Option<u64>) -> IoResult<~RtioTcpStream:Send> {
net::TcpStream::connect(addr, timeout).map(|s| ~s as ~RtioTcpStream:Send)
}
fn tcp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpListener:Send> {
net::TcpListener::bind(addr).map(|s| ~s as ~RtioTcpListener:Send)
Expand Down
Loading

1 comment on commit 3915e17

@alexcrichton
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=brson

Please sign in to comment.