Skip to content

std: Close TcpListener with closesocket() #19334

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 5, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/libstd/sys/windows/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@ impl AsRawSocket for io::net::tcp::TcpStream {

impl AsRawSocket for io::net::tcp::TcpListener {
fn as_raw_socket(&self) -> Socket {
self.as_inner().fd()
self.as_inner().socket()
}
}

impl AsRawSocket for io::net::tcp::TcpAcceptor {
fn as_raw_socket(&self) -> Socket {
self.as_inner().fd()
self.as_inner().socket()
}
}

Expand Down
40 changes: 22 additions & 18 deletions src/libstd/sys/windows/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,37 +48,35 @@ impl Drop for Event {
// TCP listeners
////////////////////////////////////////////////////////////////////////////////

pub struct TcpListener {
inner: FileDesc,
}
pub struct TcpListener { sock: sock_t }

impl TcpListener {
pub fn bind(addr: ip::SocketAddr) -> IoResult<TcpListener> {
sys::init_net();

let fd = try!(socket(addr, libc::SOCK_STREAM));
let ret = TcpListener { inner: FileDesc::new(fd as libc::c_int, true) };
let sock = try!(socket(addr, libc::SOCK_STREAM));
let ret = TcpListener { sock: sock };

let mut storage = unsafe { mem::zeroed() };
let len = addr_to_sockaddr(addr, &mut storage);
let addrp = &storage as *const _ as *const libc::sockaddr;

match unsafe { libc::bind(fd, addrp, len) } {
match unsafe { libc::bind(sock, addrp, len) } {
-1 => Err(last_net_error()),
_ => Ok(ret),
}
}

pub fn fd(&self) -> sock_t { self.inner.fd as sock_t }
pub fn socket(&self) -> sock_t { self.sock }

pub fn listen(self, backlog: int) -> IoResult<TcpAcceptor> {
match unsafe { libc::listen(self.fd(), backlog as libc::c_int) } {
match unsafe { libc::listen(self.socket(), backlog as libc::c_int) } {
-1 => Err(last_net_error()),

_ => {
let accept = try!(Event::new());
let ret = unsafe {
c::WSAEventSelect(self.fd(), accept.handle(), c::FD_ACCEPT)
c::WSAEventSelect(self.socket(), accept.handle(), c::FD_ACCEPT)
};
if ret != 0 {
return Err(last_net_error())
Expand All @@ -97,7 +95,13 @@ impl TcpListener {
}

pub fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
sockname(self.fd(), libc::getsockname)
sockname(self.socket(), libc::getsockname)
}
}

impl Drop for TcpListener {
fn drop(&mut self) {
unsafe { super::close_sock(self.sock); }
}
}

Expand All @@ -114,7 +118,7 @@ struct AcceptorInner {
}

impl TcpAcceptor {
pub fn fd(&self) -> sock_t { self.inner.listener.fd() }
pub fn socket(&self) -> sock_t { self.inner.listener.socket() }

pub fn accept(&mut self) -> IoResult<TcpStream> {
// Unlink unix, windows cannot invoke `select` on arbitrary file
Expand Down Expand Up @@ -161,27 +165,27 @@ impl TcpAcceptor {

let mut wsaevents: c::WSANETWORKEVENTS = unsafe { mem::zeroed() };
let ret = unsafe {
c::WSAEnumNetworkEvents(self.fd(), events[1], &mut wsaevents)
c::WSAEnumNetworkEvents(self.socket(), events[1], &mut wsaevents)
};
if ret != 0 { return Err(last_net_error()) }

if wsaevents.lNetworkEvents & c::FD_ACCEPT == 0 { continue }
match unsafe {
libc::accept(self.fd(), ptr::null_mut(), ptr::null_mut())
libc::accept(self.socket(), ptr::null_mut(), ptr::null_mut())
} {
-1 if wouldblock() => {}
-1 => return Err(last_net_error()),

// Accepted sockets inherit the same properties as the caller,
// so we need to deregister our event and switch the socket back
// to blocking mode
fd => {
let stream = TcpStream::new(fd);
socket => {
let stream = TcpStream::new(socket);
let ret = unsafe {
c::WSAEventSelect(fd, events[1], 0)
c::WSAEventSelect(socket, events[1], 0)
};
if ret != 0 { return Err(last_net_error()) }
try!(set_nonblocking(fd, false));
try!(set_nonblocking(socket, false));
return Ok(stream)
}
}
Expand All @@ -191,7 +195,7 @@ impl TcpAcceptor {
}

pub fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
sockname(self.fd(), libc::getsockname)
sockname(self.socket(), libc::getsockname)
}

pub fn set_timeout(&mut self, timeout: Option<u64>) {
Expand Down