summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sys/aio.rs100
-rw-r--r--test/sys/test_aio.rs74
2 files changed, 90 insertions, 84 deletions
diff --git a/src/sys/aio.rs b/src/sys/aio.rs
index f0fce435..17c20288 100644
--- a/src/sys/aio.rs
+++ b/src/sys/aio.rs
@@ -153,56 +153,67 @@ impl<'a> AioCb<'a> {
pub fn set_sigev_notify(&mut self, sigev_notify: SigevNotify) {
self.aiocb.aio_sigevent = SigEvent::new(sigev_notify).sigevent();
}
-}
-/// Cancels outstanding AIO requests. If `aiocb` is `None`, then all requests
-/// for `fd` will be cancelled. Otherwise, only the given `AioCb` will be
-/// cancelled.
-pub fn aio_cancel(fd: RawFd, aiocb: Option<&mut AioCb>) -> Result<AioCancelStat> {
- let p: *mut libc::aiocb = match aiocb {
- None => null_mut(),
- Some(x) => &mut x.aiocb
- };
- match unsafe { libc::aio_cancel(fd, p) } {
- libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled),
- libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled),
- libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone),
- -1 => Err(Error::last()),
- _ => panic!("unknown aio_cancel return value")
+ /// Cancels an outstanding AIO request.
+ pub fn cancel(&mut self) -> Result<AioCancelStat> {
+ match unsafe { libc::aio_cancel(self.aiocb.aio_fildes, &mut self.aiocb) } {
+ libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled),
+ libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled),
+ libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone),
+ -1 => Err(Error::last()),
+ _ => panic!("unknown aio_cancel return value")
+ }
}
-}
-/// Retrieve error status of an asynchronous operation. If the request has not
-/// yet completed, returns `EINPROGRESS`. Otherwise, returns `Ok` or any other
-/// error.
-pub fn aio_error(aiocb: &mut AioCb) -> Result<()> {
- let p: *mut libc::aiocb = &mut aiocb.aiocb;
- match unsafe { libc::aio_error(p) } {
- 0 => Ok(()),
- num if num > 0 => Err(Error::from_errno(Errno::from_i32(num))),
- -1 => Err(Error::last()),
- num => panic!("unknown aio_error return value {:?}", num)
+ /// Retrieve error status of an asynchronous operation. If the request has not
+ /// yet completed, returns `EINPROGRESS`. Otherwise, returns `Ok` or any other
+ /// error.
+ pub fn error(&mut self) -> Result<()> {
+ match unsafe { libc::aio_error(&mut self.aiocb as *mut libc::aiocb) } {
+ 0 => Ok(()),
+ num if num > 0 => Err(Error::from_errno(Errno::from_i32(num))),
+ -1 => Err(Error::last()),
+ num => panic!("unknown aio_error return value {:?}", num)
+ }
}
-}
-/// An asynchronous version of `fsync`.
-pub fn aio_fsync(mode: AioFsyncMode, aiocb: &mut AioCb) -> Result<()> {
- let p: *mut libc::aiocb = &mut aiocb.aiocb;
- Errno::result(unsafe { libc::aio_fsync(mode as ::c_int, p) }).map(drop)
-}
+ /// An asynchronous version of `fsync`.
+ pub fn fsync(&mut self, mode: AioFsyncMode) -> Result<()> {
+ let p: *mut libc::aiocb = &mut self.aiocb;
+ Errno::result(unsafe { libc::aio_fsync(mode as ::c_int, p) }).map(drop)
+ }
+
+ /// Asynchronously reads from a file descriptor into a buffer
+ pub fn read(&mut self) -> Result<()> {
+ let p: *mut libc::aiocb = &mut self.aiocb;
+ Errno::result(unsafe { libc::aio_read(p) }).map(drop)
+ }
+
+ /// Retrieve return status of an asynchronous operation. Should only be called
+ /// once for each `AioCb`, after `aio_error` indicates that it has completed.
+ /// The result the same as for `read`, `write`, of `fsync`.
+ pub fn aio_return(&mut self) -> Result<isize> {
+ let p: *mut libc::aiocb = &mut self.aiocb;
+ Errno::result(unsafe { libc::aio_return(p) })
+ }
+
+ /// Asynchronously writes from a buffer to a file descriptor
+ pub fn write(&mut self) -> Result<()> {
+ let p: *mut libc::aiocb = &mut self.aiocb;
+ Errno::result(unsafe { libc::aio_write(p) }).map(drop)
+ }
-/// 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)
}
-/// Retrieve return status of an asynchronous operation. Should only be called
-/// once for each `AioCb`, after `aio_error` indicates that it has completed.
-/// The result the same as for `read`, `write`, of `fsync`.
-pub fn aio_return(aiocb: &mut AioCb) -> Result<isize> {
- let p: *mut libc::aiocb = &mut aiocb.aiocb;
- Errno::result(unsafe { libc::aio_return(p) })
+/// Cancels outstanding AIO requests. All requests for `fd` will be cancelled.
+pub fn aio_cancel_all(fd: RawFd) -> Result<AioCancelStat> {
+ match unsafe { libc::aio_cancel(fd, null_mut()) } {
+ libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled),
+ libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled),
+ libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone),
+ -1 => Err(Error::last()),
+ _ => panic!("unknown aio_cancel return value")
+ }
}
/// Suspends the calling process until at least one of the specified `AioCb`s
@@ -224,11 +235,6 @@ pub fn aio_suspend(list: &[&AioCb], timeout: Option<TimeSpec>) -> Result<()> {
}).map(drop)
}
-/// Asynchronously writes from a buffer to a file descriptor
-pub fn aio_write(aiocb: &mut AioCb) -> Result<()> {
- let p: *mut libc::aiocb = &mut aiocb.aiocb;
- Errno::result(unsafe { libc::aio_write(p) }).map(drop)
-}
/// Submits multiple asynchronous I/O requests with a single system call. The
/// order in which the requests are carried out is not specified.
diff --git a/test/sys/test_aio.rs b/test/sys/test_aio.rs
index 825282f1..41070c04 100644
--- a/test/sys/test_aio.rs
+++ b/test/sys/test_aio.rs
@@ -12,17 +12,17 @@ use tempfile::tempfile;
// Helper that polls an AioCb for completion or error
fn poll_aio(mut aiocb: &mut AioCb) -> Result<()> {
loop {
- let err = aio_error(&mut aiocb);
+ let err = aiocb.error();
if err != Err(Error::from(Errno::EINPROGRESS)) { return err; };
thread::sleep(time::Duration::from_millis(10));
}
}
-// Tests aio_cancel. We aren't trying to test the OS's implementation, only our
-// bindings. So it's sufficient to check that aio_cancel returned any
+// Tests AioCb.cancel. We aren't trying to test the OS's implementation, only our
+// bindings. So it's sufficient to check that AioCb.cancel returned any
// AioCancelStat value.
#[test]
-fn test_aio_cancel() {
+fn test_cancel() {
let mut wbuf = "CDEF".to_string().into_bytes();
let f = tempfile().unwrap();
@@ -32,19 +32,19 @@ fn test_aio_cancel() {
0, //priority
SigevNotify::SigevNone,
LioOpcode::LIO_NOP);
- aio_write(&mut aiocb).unwrap();
- let err = aio_error(&mut aiocb);
+ aiocb.write().unwrap();
+ let err = aiocb.error();
assert!(err == Ok(()) || err == Err(Error::from(Errno::EINPROGRESS)));
- let cancelstat = aio_cancel(f.as_raw_fd(), Some(&mut aiocb));
+ let cancelstat = aiocb.cancel();
assert!(cancelstat.is_ok());
// Wait for aiocb to complete, but don't care whether it succeeded
let _ = poll_aio(&mut aiocb);
- let _ = aio_return(&mut aiocb);
+ let _ = aiocb.aio_return();
}
-// Tests using aio_cancel for all outstanding IOs.
+// Tests using aio_cancel_all for all outstanding IOs.
#[test]
fn test_aio_cancel_all() {
let mut wbuf = "CDEF".to_string().into_bytes();
@@ -56,30 +56,30 @@ fn test_aio_cancel_all() {
0, //priority
SigevNotify::SigevNone,
LioOpcode::LIO_NOP);
- aio_write(&mut aiocb).unwrap();
- let err = aio_error(&mut aiocb);
+ aiocb.write().unwrap();
+ let err = aiocb.error();
assert!(err == Ok(()) || err == Err(Error::from(Errno::EINPROGRESS)));
- let cancelstat = aio_cancel(f.as_raw_fd(), None);
+ let cancelstat = aio_cancel_all(f.as_raw_fd());
assert!(cancelstat.is_ok());
// Wait for aiocb to complete, but don't care whether it succeeded
let _ = poll_aio(&mut aiocb);
- let _ = aio_return(&mut aiocb);
+ let _ = aiocb.aio_return();
}
#[test]
-fn test_aio_fsync() {
+fn test_fsync() {
const INITIAL: &'static [u8] = b"abcdef123456";
let mut f = tempfile().unwrap();
f.write(INITIAL).unwrap();
let mut aiocb = AioCb::from_fd( f.as_raw_fd(),
0, //priority
SigevNotify::SigevNone);
- let err = aio_fsync(AioFsyncMode::O_SYNC, &mut aiocb);
+ let err = aiocb.fsync(AioFsyncMode::O_SYNC);
assert!(err.is_ok());
poll_aio(&mut aiocb).unwrap();
- aio_return(&mut aiocb).unwrap();
+ aiocb.aio_return().unwrap();
}
@@ -107,27 +107,27 @@ fn test_aio_suspend() {
0, //priority
SigevNotify::SigevNone,
LioOpcode::LIO_READ);
- aio_write(&mut wcb).unwrap();
- aio_read(&mut rcb).unwrap();
+ wcb.write().unwrap();
+ rcb.read().unwrap();
loop {
{
let cbbuf = [&wcb, &rcb];
assert!(aio_suspend(&cbbuf[..], Some(timeout)).is_ok());
}
- if aio_error(&mut rcb) != Err(Error::from(Errno::EINPROGRESS)) &&
- aio_error(&mut wcb) != Err(Error::from(Errno::EINPROGRESS)) {
+ if rcb.error() != Err(Error::from(Errno::EINPROGRESS)) &&
+ wcb.error() != Err(Error::from(Errno::EINPROGRESS)) {
break
}
}
- assert!(aio_return(&mut wcb).unwrap() as usize == WBUF.len());
- assert!(aio_return(&mut rcb).unwrap() as usize == WBUF.len());
+ assert!(wcb.aio_return().unwrap() as usize == WBUF.len());
+ assert!(rcb.aio_return().unwrap() as usize == WBUF.len());
}
// Test a simple aio operation with no completion notification. We must poll
// for completion
#[test]
-fn test_aio_read() {
+fn test_read() {
const INITIAL: &'static [u8] = b"abcdef123456";
let mut rbuf = vec![0; 4];
const EXPECT: &'static [u8] = b"cdef";
@@ -140,11 +140,11 @@ fn test_aio_read() {
0, //priority
SigevNotify::SigevNone,
LioOpcode::LIO_NOP);
- aio_read(&mut aiocb).unwrap();
+ aiocb.read().unwrap();
let err = poll_aio(&mut aiocb);
assert!(err == Ok(()));
- assert!(aio_return(&mut aiocb).unwrap() as usize == EXPECT.len());
+ assert!(aiocb.aio_return().unwrap() as usize == EXPECT.len());
}
assert!(rbuf == EXPECT);
@@ -153,7 +153,7 @@ fn test_aio_read() {
// Test a simple aio operation with no completion notification. We must poll
// for completion. Unlike test_aio_read, this test uses AioCb::from_slice
#[test]
-fn test_aio_write() {
+fn test_write() {
const INITIAL: &'static [u8] = b"abcdef123456";
const WBUF: &'static [u8] = b"CDEF"; //"CDEF".to_string().into_bytes();
let mut rbuf = Vec::new();
@@ -169,11 +169,11 @@ fn test_aio_write() {
SigevNotify::SigevNone,
LioOpcode::LIO_NOP)
};
- aio_write(&mut aiocb).unwrap();
+ aiocb.write().unwrap();
let err = poll_aio(&mut aiocb);
assert!(err == Ok(()));
- assert!(aio_return(&mut aiocb).unwrap() as usize == WBUF.len());
+ assert!(aiocb.aio_return().unwrap() as usize == WBUF.len());
f.seek(SeekFrom::Start(0)).unwrap();
let len = f.read_to_end(&mut rbuf).unwrap();
@@ -192,7 +192,7 @@ extern fn sigfunc(_: c_int) {
// Test an aio operation with completion delivered by a signal
#[test]
-fn test_aio_write_sigev_signal() {
+fn test_write_sigev_signal() {
let sa = SigAction::new(SigHandler::Handler(sigfunc),
SA_RESETHAND,
SigSet::empty());
@@ -217,12 +217,12 @@ fn test_aio_write_sigev_signal() {
},
LioOpcode::LIO_NOP)
};
- aio_write(&mut aiocb).unwrap();
+ aiocb.write().unwrap();
while unsafe { signaled == 0 } {
thread::sleep(time::Duration::from_millis(10));
}
- assert!(aio_return(&mut aiocb).unwrap() as usize == WBUF.len());
+ assert!(aiocb.aio_return().unwrap() as usize == WBUF.len());
f.seek(SeekFrom::Start(0)).unwrap();
let len = f.read_to_end(&mut rbuf).unwrap();
assert!(len == EXPECT.len());
@@ -262,8 +262,8 @@ fn test_lio_listio_wait() {
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 == WBUF.len());
+ assert!(wcb.aio_return().unwrap() as usize == WBUF.len());
+ assert!(rcb.aio_return().unwrap() as usize == WBUF.len());
}
assert!(rbuf == b"3456");
@@ -308,8 +308,8 @@ fn test_lio_listio_nowait() {
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!(wcb.aio_return().unwrap() as usize == WBUF.len());
+ assert!(rcb.aio_return().unwrap() as usize == WBUF.len());
}
assert!(rbuf == b"3456");
@@ -362,8 +362,8 @@ fn test_lio_listio_signal() {
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 == WBUF.len());
+ assert!(wcb.aio_return().unwrap() as usize == WBUF.len());
+ assert!(rcb.aio_return().unwrap() as usize == WBUF.len());
}
assert!(rbuf == b"3456");