Skip to content

Commit c8677b5

Browse files
committed
Make sure ownership is transferred in into_raw_fd
Previously all of the into_raw_fd implementations only returns a copy of the inner RawFd, while still holding the ownership of the file descriptor when returning for into_raw_fd. Since `self` is dropped at the end of into_raw_fd, the returned file descriptor will actually be closed, render the function unuseable. The patch makes sure that into_raw_fd actually takes the ownership of the file descriptor all the way from the inner IoHandle. To achieve this, I have to use an Option in IoHandle to store the I/O source. It's not pretty, but I cannot come up with a better way.
1 parent 2ca9c46 commit c8677b5

File tree

7 files changed

+36
-55
lines changed

7 files changed

+36
-55
lines changed

src/net/driver/mod.rs

+24-12
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ pub struct IoHandle<T: Evented> {
183183
entry: Arc<Entry>,
184184

185185
/// The I/O event source.
186-
source: T,
186+
source: Option<T>,
187187
}
188188

189189
impl<T: Evented> IoHandle<T> {
@@ -196,13 +196,13 @@ impl<T: Evented> IoHandle<T> {
196196
entry: REACTOR
197197
.register(&source)
198198
.expect("cannot register an I/O event source"),
199-
source,
199+
source: Some(source),
200200
}
201201
}
202202

203203
/// Returns a reference to the inner I/O event source.
204204
pub fn get_ref(&self) -> &T {
205-
&self.source
205+
self.source.as_ref().unwrap()
206206
}
207207

208208
/// Polls the I/O handle for reading.
@@ -278,13 +278,25 @@ impl<T: Evented> IoHandle<T> {
278278

279279
Ok(())
280280
}
281+
282+
/// Deregister and return the I/O source
283+
///
284+
/// This method is to support IntoRawFd in struct that uses IoHandle
285+
pub fn into_inner(mut self) -> T {
286+
let source = self.source.take().unwrap();
287+
REACTOR.deregister(&source, &self.entry)
288+
.expect("cannot deregister I/O event source");
289+
source
290+
}
281291
}
282292

283293
impl<T: Evented> Drop for IoHandle<T> {
284294
fn drop(&mut self) {
285-
REACTOR
286-
.deregister(&self.source, &self.entry)
287-
.expect("cannot deregister I/O event source");
295+
if let Some(ref source) = self.source {
296+
REACTOR
297+
.deregister(source, &self.entry)
298+
.expect("cannot deregister I/O event source");
299+
}
288300
}
289301
}
290302

@@ -305,7 +317,7 @@ impl<T: Evented + std::io::Read + Unpin> AsyncRead for IoHandle<T> {
305317
) -> Poll<io::Result<usize>> {
306318
futures_core::ready!(Pin::new(&mut *self).poll_readable(cx)?);
307319

308-
match self.source.read(buf) {
320+
match self.source.as_mut().unwrap().read(buf) {
309321
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => {
310322
self.clear_readable(cx)?;
311323
Poll::Pending
@@ -326,7 +338,7 @@ where
326338
) -> Poll<io::Result<usize>> {
327339
futures_core::ready!(Pin::new(&mut *self).poll_readable(cx)?);
328340

329-
match (&self.source).read(buf) {
341+
match self.source.as_ref().unwrap().read(buf) {
330342
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => {
331343
self.clear_readable(cx)?;
332344
Poll::Pending
@@ -344,7 +356,7 @@ impl<T: Evented + std::io::Write + Unpin> AsyncWrite for IoHandle<T> {
344356
) -> Poll<io::Result<usize>> {
345357
futures_core::ready!(self.poll_writable(cx)?);
346358

347-
match self.source.write(buf) {
359+
match self.source.as_mut().unwrap().write(buf) {
348360
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => {
349361
self.clear_writable(cx)?;
350362
Poll::Pending
@@ -356,7 +368,7 @@ impl<T: Evented + std::io::Write + Unpin> AsyncWrite for IoHandle<T> {
356368
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
357369
futures_core::ready!(self.poll_writable(cx)?);
358370

359-
match self.source.flush() {
371+
match self.source.as_mut().unwrap().flush() {
360372
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => {
361373
self.clear_writable(cx)?;
362374
Poll::Pending
@@ -381,7 +393,7 @@ where
381393
) -> Poll<io::Result<usize>> {
382394
futures_core::ready!(self.poll_writable(cx)?);
383395

384-
match (&self.source).write(buf) {
396+
match self.get_ref().write(buf) {
385397
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => {
386398
self.clear_writable(cx)?;
387399
Poll::Pending
@@ -393,7 +405,7 @@ where
393405
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
394406
futures_core::ready!(self.poll_writable(cx)?);
395407

396-
match (&self.source).flush() {
408+
match self.get_ref().flush() {
397409
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => {
398410
self.clear_writable(cx)?;
399411
Poll::Pending

src/net/tcp/listener.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ use crate::task::{Context, Poll};
5050
#[derive(Debug)]
5151
pub struct TcpListener {
5252
io_handle: IoHandle<mio::net::TcpListener>,
53-
54-
#[cfg(unix)]
55-
raw_fd: std::os::unix::io::RawFd,
5653
// #[cfg(windows)]
5754
// raw_socket: std::os::windows::io::RawSocket,
5855
}
@@ -87,7 +84,6 @@ impl TcpListener {
8784
Ok(mio_listener) => {
8885
#[cfg(unix)]
8986
let listener = TcpListener {
90-
raw_fd: mio_listener.as_raw_fd(),
9187
io_handle: IoHandle::new(mio_listener),
9288
};
9389

@@ -136,7 +132,6 @@ impl TcpListener {
136132

137133
#[cfg(unix)]
138134
let stream = TcpStream {
139-
raw_fd: mio_stream.as_raw_fd(),
140135
io_handle: IoHandle::new(mio_stream),
141136
};
142137

@@ -243,7 +238,6 @@ impl From<std::net::TcpListener> for TcpListener {
243238

244239
#[cfg(unix)]
245240
let listener = TcpListener {
246-
raw_fd: mio_listener.as_raw_fd(),
247241
io_handle: IoHandle::new(mio_listener),
248242
};
249243

@@ -273,7 +267,7 @@ cfg_if! {
273267
if #[cfg(any(unix, feature = "docs"))] {
274268
impl AsRawFd for TcpListener {
275269
fn as_raw_fd(&self) -> RawFd {
276-
self.raw_fd
270+
self.io_handle.get_ref().as_raw_fd()
277271
}
278272
}
279273

@@ -285,7 +279,7 @@ cfg_if! {
285279

286280
impl IntoRawFd for TcpListener {
287281
fn into_raw_fd(self) -> RawFd {
288-
self.raw_fd
282+
self.io_handle.into_inner().into_raw_fd()
289283
}
290284
}
291285
}

src/net/tcp/stream.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ use crate::task::{Context, Poll};
5151
#[derive(Debug)]
5252
pub struct TcpStream {
5353
pub(super) io_handle: IoHandle<mio::net::TcpStream>,
54-
55-
#[cfg(unix)]
56-
pub(super) raw_fd: std::os::unix::io::RawFd,
5754
// #[cfg(windows)]
5855
// pub(super) raw_socket: std::os::windows::io::RawSocket,
5956
}
@@ -103,7 +100,6 @@ impl TcpStream {
103100
let stream = mio::net::TcpStream::connect(&addr).map(|mio_stream| {
104101
#[cfg(unix)]
105102
let stream = TcpStream {
106-
raw_fd: mio_stream.as_raw_fd(),
107103
io_handle: IoHandle::new(mio_stream),
108104
};
109105

@@ -445,7 +441,6 @@ impl From<std::net::TcpStream> for TcpStream {
445441

446442
#[cfg(unix)]
447443
let stream = TcpStream {
448-
raw_fd: mio_stream.as_raw_fd(),
449444
io_handle: IoHandle::new(mio_stream),
450445
};
451446

@@ -475,7 +470,7 @@ cfg_if! {
475470
if #[cfg(any(unix, feature = "docs"))] {
476471
impl AsRawFd for TcpStream {
477472
fn as_raw_fd(&self) -> RawFd {
478-
self.raw_fd
473+
self.io_handle.get_ref().as_raw_fd()
479474
}
480475
}
481476

@@ -487,7 +482,7 @@ cfg_if! {
487482

488483
impl IntoRawFd for TcpStream {
489484
fn into_raw_fd(self) -> RawFd {
490-
self.raw_fd
485+
self.io_handle.into_inner().into_raw_fd()
491486
}
492487
}
493488
}

src/net/udp/mod.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,6 @@ use crate::task::Poll;
4848
#[derive(Debug)]
4949
pub struct UdpSocket {
5050
io_handle: IoHandle<mio::net::UdpSocket>,
51-
52-
#[cfg(unix)]
53-
raw_fd: std::os::unix::io::RawFd,
5451
// #[cfg(windows)]
5552
// raw_socket: std::os::windows::io::RawSocket,
5653
}
@@ -82,7 +79,6 @@ impl UdpSocket {
8279
Ok(mio_socket) => {
8380
#[cfg(unix)]
8481
let socket = UdpSocket {
85-
raw_fd: mio_socket.as_raw_fd(),
8682
io_handle: IoHandle::new(mio_socket),
8783
};
8884

@@ -515,7 +511,6 @@ impl From<std::net::UdpSocket> for UdpSocket {
515511

516512
#[cfg(unix)]
517513
let socket = UdpSocket {
518-
raw_fd: mio_socket.as_raw_fd(),
519514
io_handle: IoHandle::new(mio_socket),
520515
};
521516

@@ -545,7 +540,7 @@ cfg_if! {
545540
if #[cfg(any(unix, feature = "docs"))] {
546541
impl AsRawFd for UdpSocket {
547542
fn as_raw_fd(&self) -> RawFd {
548-
self.raw_fd
543+
self.io_handle.get_ref().as_raw_fd()
549544
}
550545
}
551546

@@ -557,7 +552,7 @@ cfg_if! {
557552

558553
impl IntoRawFd for UdpSocket {
559554
fn into_raw_fd(self) -> RawFd {
560-
self.raw_fd
555+
self.io_handle.into_inner().into_raw_fd()
561556
}
562557
}
563558
}

src/os/unix/net/datagram.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,12 @@ use crate::task::{blocking, Poll};
4444
pub struct UnixDatagram {
4545
#[cfg(not(feature = "docs"))]
4646
io_handle: IoHandle<mio_uds::UnixDatagram>,
47-
48-
raw_fd: RawFd,
4947
}
5048

5149
impl UnixDatagram {
5250
#[cfg(not(feature = "docs"))]
5351
fn new(socket: mio_uds::UnixDatagram) -> UnixDatagram {
5452
UnixDatagram {
55-
raw_fd: socket.as_raw_fd(),
5653
io_handle: IoHandle::new(socket),
5754
}
5855
}
@@ -362,15 +359,14 @@ impl From<std::os::unix::net::UnixDatagram> for UnixDatagram {
362359
fn from(datagram: std::os::unix::net::UnixDatagram) -> UnixDatagram {
363360
let mio_datagram = mio_uds::UnixDatagram::from_datagram(datagram).unwrap();
364361
UnixDatagram {
365-
raw_fd: mio_datagram.as_raw_fd(),
366362
io_handle: IoHandle::new(mio_datagram),
367363
}
368364
}
369365
}
370366

371367
impl AsRawFd for UnixDatagram {
372368
fn as_raw_fd(&self) -> RawFd {
373-
self.raw_fd
369+
self.io_handle.get_ref().as_raw_fd()
374370
}
375371
}
376372

@@ -383,6 +379,6 @@ impl FromRawFd for UnixDatagram {
383379

384380
impl IntoRawFd for UnixDatagram {
385381
fn into_raw_fd(self) -> RawFd {
386-
self.raw_fd
382+
self.io_handle.into_inner().into_raw_fd()
387383
}
388384
}

src/os/unix/net/listener.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ use crate::task::{blocking, Context, Poll};
5050
pub struct UnixListener {
5151
#[cfg(not(feature = "docs"))]
5252
io_handle: IoHandle<mio_uds::UnixListener>,
53-
54-
raw_fd: RawFd,
5553
}
5654

5755
impl UnixListener {
@@ -73,7 +71,6 @@ impl UnixListener {
7371
let listener = blocking::spawn(async move { mio_uds::UnixListener::bind(path) }).await?;
7472

7573
Ok(UnixListener {
76-
raw_fd: listener.as_raw_fd(),
7774
io_handle: IoHandle::new(listener),
7875
})
7976
}
@@ -102,7 +99,6 @@ impl UnixListener {
10299
Ok(Some((io, addr))) => {
103100
let mio_stream = mio_uds::UnixStream::from_stream(io)?;
104101
let stream = UnixStream {
105-
raw_fd: mio_stream.as_raw_fd(),
106102
io_handle: IoHandle::new(mio_stream),
107103
};
108104
Poll::Ready(Ok((stream, addr)))
@@ -214,15 +210,14 @@ impl From<std::os::unix::net::UnixListener> for UnixListener {
214210
fn from(listener: std::os::unix::net::UnixListener) -> UnixListener {
215211
let mio_listener = mio_uds::UnixListener::from_listener(listener).unwrap();
216212
UnixListener {
217-
raw_fd: mio_listener.as_raw_fd(),
218213
io_handle: IoHandle::new(mio_listener),
219214
}
220215
}
221216
}
222217

223218
impl AsRawFd for UnixListener {
224219
fn as_raw_fd(&self) -> RawFd {
225-
self.raw_fd
220+
self.io_handle.get_ref().as_raw_fd()
226221
}
227222
}
228223

@@ -235,6 +230,6 @@ impl FromRawFd for UnixListener {
235230

236231
impl IntoRawFd for UnixListener {
237232
fn into_raw_fd(self) -> RawFd {
238-
self.raw_fd
233+
self.io_handle.into_inner().into_raw_fd()
239234
}
240235
}

src/os/unix/net/stream.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ use crate::task::{blocking, Context, Poll};
4242
pub struct UnixStream {
4343
#[cfg(not(feature = "docs"))]
4444
pub(super) io_handle: IoHandle<mio_uds::UnixStream>,
45-
46-
pub(super) raw_fd: RawFd,
4745
}
4846

4947
impl UnixStream {
@@ -71,7 +69,6 @@ impl UnixStream {
7169
let mut state = {
7270
match blocking::spawn(async move { mio_uds::UnixStream::connect(path) }).await {
7371
Ok(mio_stream) => State::Waiting(UnixStream {
74-
raw_fd: mio_stream.as_raw_fd(),
7572
io_handle: IoHandle::new(mio_stream),
7673
}),
7774
Err(err) => State::Error(err),
@@ -124,11 +121,9 @@ impl UnixStream {
124121
pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
125122
let (a, b) = mio_uds::UnixStream::pair()?;
126123
let a = UnixStream {
127-
raw_fd: a.as_raw_fd(),
128124
io_handle: IoHandle::new(a),
129125
};
130126
let b = UnixStream {
131-
raw_fd: b.as_raw_fd(),
132127
io_handle: IoHandle::new(b),
133128
};
134129
Ok((a, b))
@@ -271,15 +266,14 @@ impl From<std::os::unix::net::UnixStream> for UnixStream {
271266
fn from(stream: std::os::unix::net::UnixStream) -> UnixStream {
272267
let mio_stream = mio_uds::UnixStream::from_stream(stream).unwrap();
273268
UnixStream {
274-
raw_fd: mio_stream.as_raw_fd(),
275269
io_handle: IoHandle::new(mio_stream),
276270
}
277271
}
278272
}
279273

280274
impl AsRawFd for UnixStream {
281275
fn as_raw_fd(&self) -> RawFd {
282-
self.raw_fd
276+
self.io_handle.get_ref().as_raw_fd()
283277
}
284278
}
285279

@@ -292,6 +286,6 @@ impl FromRawFd for UnixStream {
292286

293287
impl IntoRawFd for UnixStream {
294288
fn into_raw_fd(self) -> RawFd {
295-
self.raw_fd
289+
self.io_handle.into_inner().into_raw_fd()
296290
}
297291
}

0 commit comments

Comments
 (0)