Skip to content

Commit b50290d

Browse files
committed
AioCb::Drop will now panic for in-progress AioCb
Printing a warning message to stderr isn't really appropriate, because there's no way to guarantee that stderr is even valid. Nor is aio_suspend necessarily an appropriate action to take.
1 parent 13019c0 commit b50290d

File tree

5 files changed

+34
-48
lines changed

5 files changed

+34
-48
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
5151
([#744](https://github.com/nix-rust/nix/pull/744))
5252
- Moved constants ptrace request, event and options to enums and updated ptrace functions and argument types accordingly.
5353
([#749](https://github.com/nix-rust/nix/pull/749))
54+
- `AioCb::Drop` will now panic if the `AioCb` is still in-progress ([#715](https://github.com/nix-rust/nix/pull/715))
5455

5556
# Fixed
5657
- Fix compilation and tests for OpenBSD targets

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ nix-test = { path = "nix-test", version = "0.0.1" }
3131
name = "test"
3232
path = "test/test.rs"
3333

34+
[[test]]
35+
name = "test-aio-drop"
36+
path = "test/sys/test_aio_drop.rs"
37+
3438
[[test]]
3539
name = "test-mount"
3640
path = "test/test_mount.rs"

src/sys/aio.rs

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ use libc::{c_void, off_t, size_t};
44
use libc;
55
use std::fmt;
66
use std::fmt::Debug;
7-
use std::io::Write;
8-
use std::io::stderr;
97
use std::marker::PhantomData;
108
use std::mem;
119
use std::rc::Rc;
@@ -332,24 +330,8 @@ impl<'a> Debug for AioCb<'a> {
332330

333331
impl<'a> Drop for AioCb<'a> {
334332
/// If the `AioCb` has no remaining state in the kernel, just drop it.
335-
/// Otherwise, collect its error and return values, so as not to leak
336-
/// resources.
333+
/// Otherwise, dropping constitutes a resource leak, which is an error
337334
fn drop(&mut self) {
338-
if self.in_progress {
339-
// Well-written programs should never get here. They should always
340-
// wait for an AioCb to complete before dropping it
341-
let _ = write!(stderr(), "WARNING: dropped an in-progress AioCb");
342-
loop {
343-
let ret = aio_suspend(&[&self], None);
344-
match ret {
345-
Ok(()) => break,
346-
Err(Error::Sys(Errno::EINVAL)) => panic!(
347-
"Inconsistent AioCb.in_progress value"),
348-
Err(Error::Sys(Errno::EINTR)) => (), // Retry interrupted syscall
349-
_ => panic!("Unexpected aio_suspend return value {:?}", ret)
350-
};
351-
}
352-
let _ = self.aio_return();
353-
}
335+
assert!(!self.in_progress, "Dropped an in-progress AioCb");
354336
}
355337
}

test/sys/test_aio.rs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -442,31 +442,3 @@ fn test_lio_listio_read_immutable() {
442442
LioOpcode::LIO_READ);
443443
let _ = lio_listio(LioMode::LIO_NOWAIT, &[&mut rcb], SigevNotify::SigevNone);
444444
}
445-
446-
// Test dropping an AioCb that hasn't yet finished. Behind the scenes, the
447-
// library should wait for the AioCb's completion.
448-
#[test]
449-
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
450-
fn test_drop() {
451-
const INITIAL: &'static [u8] = b"abcdef123456";
452-
const WBUF: &'static [u8] = b"CDEF"; //"CDEF".to_string().into_bytes();
453-
let mut rbuf = Vec::new();
454-
const EXPECT: &'static [u8] = b"abCDEF123456";
455-
456-
let mut f = tempfile().unwrap();
457-
f.write(INITIAL).unwrap();
458-
{
459-
let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
460-
2, //offset
461-
&WBUF,
462-
0, //priority
463-
SigevNotify::SigevNone,
464-
LioOpcode::LIO_NOP);
465-
aiocb.write().unwrap();
466-
}
467-
468-
f.seek(SeekFrom::Start(0)).unwrap();
469-
let len = f.read_to_end(&mut rbuf).unwrap();
470-
assert!(len == EXPECT.len());
471-
assert!(rbuf == EXPECT);
472-
}

test/sys/test_aio_drop.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
extern crate nix;
2+
extern crate tempfile;
3+
4+
use nix::sys::aio::*;
5+
use nix::sys::signal::*;
6+
use std::os::unix::io::AsRawFd;
7+
use tempfile::tempfile;
8+
9+
// Test dropping an AioCb that hasn't yet finished.
10+
// This must happen in its own process, because on OSX this test seems to hose
11+
// the AIO subsystem and causes subsequent tests to fail
12+
#[test]
13+
#[should_panic(expected = "Dropped an in-progress AioCb")]
14+
#[cfg(not(target_env = "musl"))]
15+
fn test_drop() {
16+
const WBUF: &'static [u8] = b"CDEF";
17+
18+
let f = tempfile().unwrap();
19+
f.set_len(6).unwrap();
20+
let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
21+
2, //offset
22+
&WBUF,
23+
0, //priority
24+
SigevNotify::SigevNone,
25+
LioOpcode::LIO_NOP);
26+
aiocb.write().unwrap();
27+
}

0 commit comments

Comments
 (0)