summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sys/aio.rs22
-rw-r--r--test/sys/test_aio.rs157
2 files changed, 90 insertions, 89 deletions
diff --git a/src/sys/aio.rs b/src/sys/aio.rs
index 429deea3..f0fce435 100644
--- a/src/sys/aio.rs
+++ b/src/sys/aio.rs
@@ -2,6 +2,7 @@ use {Error, Errno, Result};
use std::os::unix::io::RawFd;
use libc::{c_void, off_t, size_t};
use libc;
+use std::marker::PhantomData;
use std::mem;
use std::ptr::{null, null_mut};
use sys::signal::*;
@@ -59,11 +60,12 @@ pub enum AioCancelStat {
/// The basic structure used by all aio functions. Each `aiocb` represents one
/// I/O request.
#[repr(C)]
-pub struct AioCb {
- aiocb: libc::aiocb
+pub struct AioCb<'a> {
+ aiocb: libc::aiocb,
+ phantom: PhantomData<&'a mut [u8]>
}
-impl AioCb {
+impl<'a> AioCb<'a> {
/// Constructs a new `AioCb` with no associated buffer.
///
/// The resulting `AioCb` structure is suitable for use with `aio_fsync`.
@@ -73,13 +75,13 @@ impl AioCb {
/// * `sigev_notify` Determines how you will be notified of event
/// completion.
pub fn from_fd(fd: RawFd, prio: ::c_int,
- sigev_notify: SigevNotify) -> AioCb {
+ sigev_notify: SigevNotify) -> AioCb<'a> {
let mut a = AioCb::common_init(fd, prio, sigev_notify);
a.aio_offset = 0;
a.aio_nbytes = 0;
a.aio_buf = null_mut();
- let aiocb = AioCb { aiocb: a};
+ let aiocb = AioCb { aiocb: a, phantom: PhantomData};
aiocb
}
@@ -94,7 +96,7 @@ impl AioCb {
/// completion.
/// * `opcode` This field is only used for `lio_listio`. It determines
/// which operation to use for this individual aiocb
- pub fn from_mut_slice(fd: RawFd, offs: off_t, buf: &mut [u8],
+ pub fn from_mut_slice(fd: RawFd, offs: off_t, buf: &'a mut [u8],
prio: ::c_int, sigev_notify: SigevNotify,
opcode: LioOpcode) -> AioCb {
let mut a = AioCb::common_init(fd, prio, sigev_notify);
@@ -103,7 +105,7 @@ impl AioCb {
a.aio_buf = buf.as_ptr() as *mut c_void;
a.aio_lio_opcode = opcode as ::c_int;
- let aiocb = AioCb { aiocb: a};
+ let aiocb = AioCb { aiocb: a, phantom: PhantomData};
aiocb
}
@@ -121,7 +123,7 @@ impl AioCb {
// lio_listio wouldn't work, because that function needs a slice of AioCb,
// and they must all be the same type. We're basically stuck with using an
// unsafe function, since aio (as designed in C) is an unsafe API.
- pub unsafe fn from_slice(fd: RawFd, offs: off_t, buf: &[u8],
+ pub unsafe fn from_slice(fd: RawFd, offs: off_t, buf: &'a [u8],
prio: ::c_int, sigev_notify: SigevNotify,
opcode: LioOpcode) -> AioCb {
let mut a = AioCb::common_init(fd, prio, sigev_notify);
@@ -130,7 +132,7 @@ impl AioCb {
a.aio_buf = buf.as_ptr() as *mut c_void;
a.aio_lio_opcode = opcode as ::c_int;
- let aiocb = AioCb { aiocb: a};
+ let aiocb = AioCb { aiocb: a, phantom: PhantomData};
aiocb
}
@@ -189,7 +191,7 @@ pub fn aio_fsync(mode: AioFsyncMode, aiocb: &mut AioCb) -> Result<()> {
Errno::result(unsafe { libc::aio_fsync(mode as ::c_int, p) }).map(drop)
}
-/// Asynchously reads from a file descriptor into a buffer
+/// Asynchronously reads from a file descriptor into a buffer
pub fn aio_read(aiocb: &mut AioCb) -> Result<()> {
let p: *mut libc::aiocb = &mut aiocb.aiocb;
Errno::result(unsafe { libc::aio_read(p) }).map(drop)
diff --git a/test/sys/test_aio.rs b/test/sys/test_aio.rs
index 4659fd50..825282f1 100644
--- a/test/sys/test_aio.rs
+++ b/test/sys/test_aio.rs
@@ -121,7 +121,7 @@ fn test_aio_suspend() {
}
assert!(aio_return(&mut wcb).unwrap() as usize == WBUF.len());
- assert!(aio_return(&mut rcb).unwrap() as usize == rbuf.len());
+ assert!(aio_return(&mut rcb).unwrap() as usize == WBUF.len());
}
// Test a simple aio operation with no completion notification. We must poll
@@ -133,17 +133,19 @@ fn test_aio_read() {
const EXPECT: &'static [u8] = b"cdef";
let mut f = tempfile().unwrap();
f.write(INITIAL).unwrap();
- let mut aiocb = AioCb::from_mut_slice( f.as_raw_fd(),
- 2, //offset
- &mut rbuf,
- 0, //priority
- SigevNotify::SigevNone,
- LioOpcode::LIO_NOP);
- aio_read(&mut aiocb).unwrap();
-
- let err = poll_aio(&mut aiocb);
- assert!(err == Ok(()));
- assert!(aio_return(&mut aiocb).unwrap() as usize == rbuf.len());
+ {
+ let mut aiocb = AioCb::from_mut_slice( f.as_raw_fd(),
+ 2, //offset
+ &mut rbuf,
+ 0, //priority
+ SigevNotify::SigevNone,
+ LioOpcode::LIO_NOP);
+ aio_read(&mut aiocb).unwrap();
+
+ let err = poll_aio(&mut aiocb);
+ assert!(err == Ok(()));
+ assert!(aio_return(&mut aiocb).unwrap() as usize == EXPECT.len());
+ }
assert!(rbuf == EXPECT);
}
@@ -241,29 +243,28 @@ fn test_lio_listio_wait() {
f.write(INITIAL).unwrap();
- let mut wcb = unsafe {
- AioCb::from_slice( f.as_raw_fd(),
- 2, //offset
- &WBUF,
- 0, //priority
- SigevNotify::SigevNone,
- LioOpcode::LIO_WRITE)
- };
-
- let mut rcb = AioCb::from_mut_slice( f.as_raw_fd(),
- 8, //offset
- &mut rbuf,
- 0, //priority
- SigevNotify::SigevNone,
- LioOpcode::LIO_READ);
{
- let cbbuf = [&mut wcb, &mut rcb];
- let err = lio_listio(LioMode::LIO_WAIT, &cbbuf[..], SigevNotify::SigevNone);
+ let mut wcb = unsafe {
+ AioCb::from_slice( f.as_raw_fd(),
+ 2, //offset
+ &WBUF,
+ 0, //priority
+ SigevNotify::SigevNone,
+ LioOpcode::LIO_WRITE)
+ };
+
+ let mut rcb = AioCb::from_mut_slice( f.as_raw_fd(),
+ 8, //offset
+ &mut rbuf,
+ 0, //priority
+ SigevNotify::SigevNone,
+ LioOpcode::LIO_READ);
+ let err = lio_listio(LioMode::LIO_WAIT, &[&mut wcb, &mut rcb], SigevNotify::SigevNone);
err.expect("lio_listio failed");
- }
- assert!(aio_return(&mut wcb).unwrap() as usize == WBUF.len());
- assert!(aio_return(&mut rcb).unwrap() as usize == rbuf.len());
+ assert!(aio_return(&mut wcb).unwrap() as usize == WBUF.len());
+ assert!(aio_return(&mut rcb).unwrap() as usize == WBUF.len());
+ }
assert!(rbuf == b"3456");
f.seek(SeekFrom::Start(0)).unwrap();
@@ -286,31 +287,30 @@ fn test_lio_listio_nowait() {
f.write(INITIAL).unwrap();
- let mut wcb = unsafe {
- AioCb::from_slice( f.as_raw_fd(),
- 2, //offset
- &WBUF,
- 0, //priority
- SigevNotify::SigevNone,
- LioOpcode::LIO_WRITE)
- };
-
- let mut rcb = AioCb::from_mut_slice( f.as_raw_fd(),
- 8, //offset
- &mut rbuf,
- 0, //priority
- SigevNotify::SigevNone,
- LioOpcode::LIO_READ);
{
- let cbbuf = [&mut wcb, &mut rcb];
- let err = lio_listio(LioMode::LIO_NOWAIT, &cbbuf[..], SigevNotify::SigevNone);
+ let mut wcb = unsafe {
+ AioCb::from_slice( f.as_raw_fd(),
+ 2, //offset
+ &WBUF,
+ 0, //priority
+ SigevNotify::SigevNone,
+ LioOpcode::LIO_WRITE)
+ };
+
+ let mut rcb = AioCb::from_mut_slice( f.as_raw_fd(),
+ 8, //offset
+ &mut rbuf,
+ 0, //priority
+ SigevNotify::SigevNone,
+ LioOpcode::LIO_READ);
+ let err = lio_listio(LioMode::LIO_NOWAIT, &[&mut wcb, &mut rcb], SigevNotify::SigevNone);
err.expect("lio_listio failed");
- }
- poll_aio(&mut wcb).unwrap();
- poll_aio(&mut rcb).unwrap();
- assert!(aio_return(&mut wcb).unwrap() as usize == WBUF.len());
- assert!(aio_return(&mut rcb).unwrap() as usize == rbuf.len());
+ poll_aio(&mut wcb).unwrap();
+ poll_aio(&mut rcb).unwrap();
+ assert!(aio_return(&mut wcb).unwrap() as usize == WBUF.len());
+ assert!(aio_return(&mut rcb).unwrap() as usize == WBUF.len());
+ }
assert!(rbuf == b"3456");
f.seek(SeekFrom::Start(0)).unwrap();
@@ -338,34 +338,33 @@ fn test_lio_listio_signal() {
f.write(INITIAL).unwrap();
- let mut wcb = unsafe {
- AioCb::from_slice( f.as_raw_fd(),
- 2, //offset
- &WBUF,
- 0, //priority
- SigevNotify::SigevNone,
- LioOpcode::LIO_WRITE)
- };
-
- let mut rcb = AioCb::from_mut_slice( f.as_raw_fd(),
- 8, //offset
- &mut rbuf,
- 0, //priority
- SigevNotify::SigevNone,
- LioOpcode::LIO_READ);
- unsafe {signaled = 0 };
- unsafe { sigaction(Signal::SIGUSR2, &sa) }.unwrap();
{
- let cbbuf = [&mut wcb, &mut rcb];
- let err = lio_listio(LioMode::LIO_NOWAIT, &cbbuf[..], sigev_notify);
+ let mut wcb = unsafe {
+ AioCb::from_slice( f.as_raw_fd(),
+ 2, //offset
+ &WBUF,
+ 0, //priority
+ SigevNotify::SigevNone,
+ LioOpcode::LIO_WRITE)
+ };
+
+ let mut rcb = AioCb::from_mut_slice( f.as_raw_fd(),
+ 8, //offset
+ &mut rbuf,
+ 0, //priority
+ SigevNotify::SigevNone,
+ LioOpcode::LIO_READ);
+ unsafe {signaled = 0 };
+ unsafe { sigaction(Signal::SIGUSR2, &sa) }.unwrap();
+ let err = lio_listio(LioMode::LIO_NOWAIT, &[&mut wcb, &mut rcb], sigev_notify);
err.expect("lio_listio failed");
- }
- while unsafe { signaled == 0 } {
- thread::sleep(time::Duration::from_millis(10));
- }
+ while unsafe { signaled == 0 } {
+ thread::sleep(time::Duration::from_millis(10));
+ }
- assert!(aio_return(&mut wcb).unwrap() as usize == WBUF.len());
- assert!(aio_return(&mut rcb).unwrap() as usize == rbuf.len());
+ assert!(aio_return(&mut wcb).unwrap() as usize == WBUF.len());
+ assert!(aio_return(&mut rcb).unwrap() as usize == WBUF.len());
+ }
assert!(rbuf == b"3456");
f.seek(SeekFrom::Start(0)).unwrap();