Skip to content

Commit 85d59cf

Browse files
committed
Turn most aio functions into AioCb methods
1 parent d4ba02f commit 85d59cf

File tree

2 files changed

+90
-84
lines changed

2 files changed

+90
-84
lines changed

src/sys/aio.rs

Lines changed: 53 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -153,56 +153,67 @@ impl<'a> AioCb<'a> {
153153
pub fn set_sigev_notify(&mut self, sigev_notify: SigevNotify) {
154154
self.aiocb.aio_sigevent = SigEvent::new(sigev_notify).sigevent();
155155
}
156-
}
157156

158-
/// Cancels outstanding AIO requests. If `aiocb` is `None`, then all requests
159-
/// for `fd` will be cancelled. Otherwise, only the given `AioCb` will be
160-
/// cancelled.
161-
pub fn aio_cancel(fd: RawFd, aiocb: Option<&mut AioCb>) -> Result<AioCancelStat> {
162-
let p: *mut libc::aiocb = match aiocb {
163-
None => null_mut(),
164-
Some(x) => &mut x.aiocb
165-
};
166-
match unsafe { libc::aio_cancel(fd, p) } {
167-
libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled),
168-
libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled),
169-
libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone),
170-
-1 => Err(Error::last()),
171-
_ => panic!("unknown aio_cancel return value")
157+
/// Cancels an outstanding AIO request.
158+
pub fn cancel(&mut self) -> Result<AioCancelStat> {
159+
match unsafe { libc::aio_cancel(self.aiocb.aio_fildes, &mut self.aiocb) } {
160+
libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled),
161+
libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled),
162+
libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone),
163+
-1 => Err(Error::last()),
164+
_ => panic!("unknown aio_cancel return value")
165+
}
172166
}
173-
}
174167

175-
/// Retrieve error status of an asynchronous operation. If the request has not
176-
/// yet completed, returns `EINPROGRESS`. Otherwise, returns `Ok` or any other
177-
/// error.
178-
pub fn aio_error(aiocb: &mut AioCb) -> Result<()> {
179-
let p: *mut libc::aiocb = &mut aiocb.aiocb;
180-
match unsafe { libc::aio_error(p) } {
181-
0 => Ok(()),
182-
num if num > 0 => Err(Error::from_errno(Errno::from_i32(num))),
183-
-1 => Err(Error::last()),
184-
num => panic!("unknown aio_error return value {:?}", num)
168+
/// Retrieve error status of an asynchronous operation. If the request has not
169+
/// yet completed, returns `EINPROGRESS`. Otherwise, returns `Ok` or any other
170+
/// error.
171+
pub fn error(&mut self) -> Result<()> {
172+
match unsafe { libc::aio_error(&mut self.aiocb as *mut libc::aiocb) } {
173+
0 => Ok(()),
174+
num if num > 0 => Err(Error::from_errno(Errno::from_i32(num))),
175+
-1 => Err(Error::last()),
176+
num => panic!("unknown aio_error return value {:?}", num)
177+
}
185178
}
186-
}
187179

188-
/// An asynchronous version of `fsync`.
189-
pub fn aio_fsync(mode: AioFsyncMode, aiocb: &mut AioCb) -> Result<()> {
190-
let p: *mut libc::aiocb = &mut aiocb.aiocb;
191-
Errno::result(unsafe { libc::aio_fsync(mode as ::c_int, p) }).map(drop)
192-
}
180+
/// An asynchronous version of `fsync`.
181+
pub fn fsync(&mut self, mode: AioFsyncMode) -> Result<()> {
182+
let p: *mut libc::aiocb = &mut self.aiocb;
183+
Errno::result(unsafe { libc::aio_fsync(mode as ::c_int, p) }).map(drop)
184+
}
185+
186+
/// Asynchronously reads from a file descriptor into a buffer
187+
pub fn read(&mut self) -> Result<()> {
188+
let p: *mut libc::aiocb = &mut self.aiocb;
189+
Errno::result(unsafe { libc::aio_read(p) }).map(drop)
190+
}
191+
192+
/// Retrieve return status of an asynchronous operation. Should only be called
193+
/// once for each `AioCb`, after `aio_error` indicates that it has completed.
194+
/// The result the same as for `read`, `write`, of `fsync`.
195+
pub fn aio_return(&mut self) -> Result<isize> {
196+
let p: *mut libc::aiocb = &mut self.aiocb;
197+
Errno::result(unsafe { libc::aio_return(p) })
198+
}
199+
200+
/// Asynchronously writes from a buffer to a file descriptor
201+
pub fn write(&mut self) -> Result<()> {
202+
let p: *mut libc::aiocb = &mut self.aiocb;
203+
Errno::result(unsafe { libc::aio_write(p) }).map(drop)
204+
}
193205

194-
/// Asynchronously reads from a file descriptor into a buffer
195-
pub fn aio_read(aiocb: &mut AioCb) -> Result<()> {
196-
let p: *mut libc::aiocb = &mut aiocb.aiocb;
197-
Errno::result(unsafe { libc::aio_read(p) }).map(drop)
198206
}
199207

200-
/// Retrieve return status of an asynchronous operation. Should only be called
201-
/// once for each `AioCb`, after `aio_error` indicates that it has completed.
202-
/// The result the same as for `read`, `write`, of `fsync`.
203-
pub fn aio_return(aiocb: &mut AioCb) -> Result<isize> {
204-
let p: *mut libc::aiocb = &mut aiocb.aiocb;
205-
Errno::result(unsafe { libc::aio_return(p) })
208+
/// Cancels outstanding AIO requests. All requests for `fd` will be cancelled.
209+
pub fn aio_cancel_all(fd: RawFd) -> Result<AioCancelStat> {
210+
match unsafe { libc::aio_cancel(fd, null_mut()) } {
211+
libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled),
212+
libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled),
213+
libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone),
214+
-1 => Err(Error::last()),
215+
_ => panic!("unknown aio_cancel return value")
216+
}
206217
}
207218

208219
/// 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<()> {
224235
}).map(drop)
225236
}
226237

227-
/// Asynchronously writes from a buffer to a file descriptor
228-
pub fn aio_write(aiocb: &mut AioCb) -> Result<()> {
229-
let p: *mut libc::aiocb = &mut aiocb.aiocb;
230-
Errno::result(unsafe { libc::aio_write(p) }).map(drop)
231-
}
232238

233239
/// Submits multiple asynchronous I/O requests with a single system call. The
234240
/// order in which the requests are carried out is not specified.

test/sys/test_aio.rs

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@ use tempfile::tempfile;
1212
// Helper that polls an AioCb for completion or error
1313
fn poll_aio(mut aiocb: &mut AioCb) -> Result<()> {
1414
loop {
15-
let err = aio_error(&mut aiocb);
15+
let err = aiocb.error();
1616
if err != Err(Error::from(Errno::EINPROGRESS)) { return err; };
1717
thread::sleep(time::Duration::from_millis(10));
1818
}
1919
}
2020

21-
// Tests aio_cancel. We aren't trying to test the OS's implementation, only our
22-
// bindings. So it's sufficient to check that aio_cancel returned any
21+
// Tests AioCb.cancel. We aren't trying to test the OS's implementation, only our
22+
// bindings. So it's sufficient to check that AioCb.cancel returned any
2323
// AioCancelStat value.
2424
#[test]
25-
fn test_aio_cancel() {
25+
fn test_cancel() {
2626
let mut wbuf = "CDEF".to_string().into_bytes();
2727

2828
let f = tempfile().unwrap();
@@ -32,19 +32,19 @@ fn test_aio_cancel() {
3232
0, //priority
3333
SigevNotify::SigevNone,
3434
LioOpcode::LIO_NOP);
35-
aio_write(&mut aiocb).unwrap();
36-
let err = aio_error(&mut aiocb);
35+
aiocb.write().unwrap();
36+
let err = aiocb.error();
3737
assert!(err == Ok(()) || err == Err(Error::from(Errno::EINPROGRESS)));
3838

39-
let cancelstat = aio_cancel(f.as_raw_fd(), Some(&mut aiocb));
39+
let cancelstat = aiocb.cancel();
4040
assert!(cancelstat.is_ok());
4141

4242
// Wait for aiocb to complete, but don't care whether it succeeded
4343
let _ = poll_aio(&mut aiocb);
44-
let _ = aio_return(&mut aiocb);
44+
let _ = aiocb.aio_return();
4545
}
4646

47-
// Tests using aio_cancel for all outstanding IOs.
47+
// Tests using aio_cancel_all for all outstanding IOs.
4848
#[test]
4949
fn test_aio_cancel_all() {
5050
let mut wbuf = "CDEF".to_string().into_bytes();
@@ -56,30 +56,30 @@ fn test_aio_cancel_all() {
5656
0, //priority
5757
SigevNotify::SigevNone,
5858
LioOpcode::LIO_NOP);
59-
aio_write(&mut aiocb).unwrap();
60-
let err = aio_error(&mut aiocb);
59+
aiocb.write().unwrap();
60+
let err = aiocb.error();
6161
assert!(err == Ok(()) || err == Err(Error::from(Errno::EINPROGRESS)));
6262

63-
let cancelstat = aio_cancel(f.as_raw_fd(), None);
63+
let cancelstat = aio_cancel_all(f.as_raw_fd());
6464
assert!(cancelstat.is_ok());
6565

6666
// Wait for aiocb to complete, but don't care whether it succeeded
6767
let _ = poll_aio(&mut aiocb);
68-
let _ = aio_return(&mut aiocb);
68+
let _ = aiocb.aio_return();
6969
}
7070

7171
#[test]
72-
fn test_aio_fsync() {
72+
fn test_fsync() {
7373
const INITIAL: &'static [u8] = b"abcdef123456";
7474
let mut f = tempfile().unwrap();
7575
f.write(INITIAL).unwrap();
7676
let mut aiocb = AioCb::from_fd( f.as_raw_fd(),
7777
0, //priority
7878
SigevNotify::SigevNone);
79-
let err = aio_fsync(AioFsyncMode::O_SYNC, &mut aiocb);
79+
let err = aiocb.fsync(AioFsyncMode::O_SYNC);
8080
assert!(err.is_ok());
8181
poll_aio(&mut aiocb).unwrap();
82-
aio_return(&mut aiocb).unwrap();
82+
aiocb.aio_return().unwrap();
8383
}
8484

8585

@@ -107,27 +107,27 @@ fn test_aio_suspend() {
107107
0, //priority
108108
SigevNotify::SigevNone,
109109
LioOpcode::LIO_READ);
110-
aio_write(&mut wcb).unwrap();
111-
aio_read(&mut rcb).unwrap();
110+
wcb.write().unwrap();
111+
rcb.read().unwrap();
112112
loop {
113113
{
114114
let cbbuf = [&wcb, &rcb];
115115
assert!(aio_suspend(&cbbuf[..], Some(timeout)).is_ok());
116116
}
117-
if aio_error(&mut rcb) != Err(Error::from(Errno::EINPROGRESS)) &&
118-
aio_error(&mut wcb) != Err(Error::from(Errno::EINPROGRESS)) {
117+
if rcb.error() != Err(Error::from(Errno::EINPROGRESS)) &&
118+
wcb.error() != Err(Error::from(Errno::EINPROGRESS)) {
119119
break
120120
}
121121
}
122122

123-
assert!(aio_return(&mut wcb).unwrap() as usize == WBUF.len());
124-
assert!(aio_return(&mut rcb).unwrap() as usize == WBUF.len());
123+
assert!(wcb.aio_return().unwrap() as usize == WBUF.len());
124+
assert!(rcb.aio_return().unwrap() as usize == WBUF.len());
125125
}
126126

127127
// Test a simple aio operation with no completion notification. We must poll
128128
// for completion
129129
#[test]
130-
fn test_aio_read() {
130+
fn test_read() {
131131
const INITIAL: &'static [u8] = b"abcdef123456";
132132
let mut rbuf = vec![0; 4];
133133
const EXPECT: &'static [u8] = b"cdef";
@@ -140,11 +140,11 @@ fn test_aio_read() {
140140
0, //priority
141141
SigevNotify::SigevNone,
142142
LioOpcode::LIO_NOP);
143-
aio_read(&mut aiocb).unwrap();
143+
aiocb.read().unwrap();
144144

145145
let err = poll_aio(&mut aiocb);
146146
assert!(err == Ok(()));
147-
assert!(aio_return(&mut aiocb).unwrap() as usize == EXPECT.len());
147+
assert!(aiocb.aio_return().unwrap() as usize == EXPECT.len());
148148
}
149149

150150
assert!(rbuf == EXPECT);
@@ -153,7 +153,7 @@ fn test_aio_read() {
153153
// Test a simple aio operation with no completion notification. We must poll
154154
// for completion. Unlike test_aio_read, this test uses AioCb::from_slice
155155
#[test]
156-
fn test_aio_write() {
156+
fn test_write() {
157157
const INITIAL: &'static [u8] = b"abcdef123456";
158158
const WBUF: &'static [u8] = b"CDEF"; //"CDEF".to_string().into_bytes();
159159
let mut rbuf = Vec::new();
@@ -169,11 +169,11 @@ fn test_aio_write() {
169169
SigevNotify::SigevNone,
170170
LioOpcode::LIO_NOP)
171171
};
172-
aio_write(&mut aiocb).unwrap();
172+
aiocb.write().unwrap();
173173

174174
let err = poll_aio(&mut aiocb);
175175
assert!(err == Ok(()));
176-
assert!(aio_return(&mut aiocb).unwrap() as usize == WBUF.len());
176+
assert!(aiocb.aio_return().unwrap() as usize == WBUF.len());
177177

178178
f.seek(SeekFrom::Start(0)).unwrap();
179179
let len = f.read_to_end(&mut rbuf).unwrap();
@@ -192,7 +192,7 @@ extern fn sigfunc(_: c_int) {
192192

193193
// Test an aio operation with completion delivered by a signal
194194
#[test]
195-
fn test_aio_write_sigev_signal() {
195+
fn test_write_sigev_signal() {
196196
let sa = SigAction::new(SigHandler::Handler(sigfunc),
197197
SA_RESETHAND,
198198
SigSet::empty());
@@ -217,12 +217,12 @@ fn test_aio_write_sigev_signal() {
217217
},
218218
LioOpcode::LIO_NOP)
219219
};
220-
aio_write(&mut aiocb).unwrap();
220+
aiocb.write().unwrap();
221221
while unsafe { signaled == 0 } {
222222
thread::sleep(time::Duration::from_millis(10));
223223
}
224224

225-
assert!(aio_return(&mut aiocb).unwrap() as usize == WBUF.len());
225+
assert!(aiocb.aio_return().unwrap() as usize == WBUF.len());
226226
f.seek(SeekFrom::Start(0)).unwrap();
227227
let len = f.read_to_end(&mut rbuf).unwrap();
228228
assert!(len == EXPECT.len());
@@ -262,8 +262,8 @@ fn test_lio_listio_wait() {
262262
let err = lio_listio(LioMode::LIO_WAIT, &[&mut wcb, &mut rcb], SigevNotify::SigevNone);
263263
err.expect("lio_listio failed");
264264

265-
assert!(aio_return(&mut wcb).unwrap() as usize == WBUF.len());
266-
assert!(aio_return(&mut rcb).unwrap() as usize == WBUF.len());
265+
assert!(wcb.aio_return().unwrap() as usize == WBUF.len());
266+
assert!(rcb.aio_return().unwrap() as usize == WBUF.len());
267267
}
268268
assert!(rbuf == b"3456");
269269

@@ -308,8 +308,8 @@ fn test_lio_listio_nowait() {
308308

309309
poll_aio(&mut wcb).unwrap();
310310
poll_aio(&mut rcb).unwrap();
311-
assert!(aio_return(&mut wcb).unwrap() as usize == WBUF.len());
312-
assert!(aio_return(&mut rcb).unwrap() as usize == WBUF.len());
311+
assert!(wcb.aio_return().unwrap() as usize == WBUF.len());
312+
assert!(rcb.aio_return().unwrap() as usize == WBUF.len());
313313
}
314314
assert!(rbuf == b"3456");
315315

@@ -362,8 +362,8 @@ fn test_lio_listio_signal() {
362362
thread::sleep(time::Duration::from_millis(10));
363363
}
364364

365-
assert!(aio_return(&mut wcb).unwrap() as usize == WBUF.len());
366-
assert!(aio_return(&mut rcb).unwrap() as usize == WBUF.len());
365+
assert!(wcb.aio_return().unwrap() as usize == WBUF.len());
366+
assert!(rcb.aio_return().unwrap() as usize == WBUF.len());
367367
}
368368
assert!(rbuf == b"3456");
369369

0 commit comments

Comments
 (0)