From efeb42be2837842d1beb47b51bb693c7474aba3d Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Sat, 4 Feb 2017 01:10:12 +0100 Subject: [PATCH] Use less syscalls in `FileDesc::set_{nonblocking,cloexec}` Only set the flags if they differ from what the OS reported, use `FIONBIO` to atomically set the non-blocking IO flag on Linux. --- src/libstd/sys/unix/fd.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index dcab30aad83..c690fd467ee 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -144,11 +144,24 @@ pub fn set_cloexec(&self) -> io::Result<()> { pub fn set_cloexec(&self) -> io::Result<()> { unsafe { let previous = cvt(libc::fcntl(self.fd, libc::F_GETFD))?; - cvt(libc::fcntl(self.fd, libc::F_SETFD, previous | libc::FD_CLOEXEC))?; + let new = previous | libc::FD_CLOEXEC; + if new != previous { + cvt(libc::fcntl(self.fd, libc::F_SETFD, new))?; + } + Ok(()) + } + } + + #[cfg(target_os = "linux")] + pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { + unsafe { + let v = nonblocking as c_int; + cvt(libc::ioctl(self.fd, libc::FIONBIO, &v))?; Ok(()) } } + #[cfg(not(target_os = "linux"))] pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { unsafe { let previous = cvt(libc::fcntl(self.fd, libc::F_GETFL))?; @@ -157,7 +170,9 @@ pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { } else { previous & !libc::O_NONBLOCK }; - cvt(libc::fcntl(self.fd, libc::F_SETFL, new))?; + if new != previous { + cvt(libc::fcntl(self.fd, libc::F_SETFL, new))?; + } Ok(()) } } -- 2.44.0