@@ -13,38 +13,41 @@ use sys::time::TimeSpec;
13
13
14
14
/// Mode for `AioCb::fsync`. Controls whether only data or both data and
15
15
/// metadata are synced.
16
- #[ repr( i32 ) ]
17
- #[ derive( Clone , Copy , Debug , PartialEq ) ]
18
- pub enum AioFsyncMode {
19
- /// do it like `fsync`
20
- O_SYNC = libc:: O_SYNC ,
21
- /// on supported operating systems only, do it like `fdatasync`
22
- #[ cfg( any( target_os = "openbsd" , target_os = "bitrig" ,
23
- target_os = "netbsd" , target_os = "macos" , target_os = "ios" ,
24
- target_os = "linux" ) ) ]
25
- O_DSYNC = libc:: O_DSYNC
16
+ libc_enum ! {
17
+ #[ repr( i32 ) ]
18
+ pub enum AioFsyncMode {
19
+ /// do it like `fsync`
20
+ O_SYNC ,
21
+ /// on supported operating systems only, do it like `fdatasync`
22
+ #[ cfg( any( target_os = "openbsd" , target_os = "bitrig" ,
23
+ target_os = "netbsd" , target_os = "macos" , target_os = "ios" ,
24
+ target_os = "linux" ) ) ]
25
+ O_DSYNC
26
+ }
26
27
}
27
28
28
- /// When used with `lio_listio`, determines whether a given `aiocb` should be
29
- /// used for a read operation, a write operation, or ignored. Has no effect for
30
- /// any other aio functions.
31
- #[ repr( i32 ) ]
32
- #[ derive( Clone , Copy , Debug , PartialEq ) ]
33
- pub enum LioOpcode {
34
- LIO_NOP = libc:: LIO_NOP ,
35
- LIO_WRITE = libc:: LIO_WRITE ,
36
- LIO_READ = libc:: LIO_READ
29
+ libc_enum ! {
30
+ /// When used with `lio_listio`, determines whether a given `aiocb` should be
31
+ /// used for a read operation, a write operation, or ignored. Has no effect for
32
+ /// any other aio functions.
33
+ #[ repr( i32 ) ]
34
+ pub enum LioOpcode {
35
+ LIO_NOP ,
36
+ LIO_WRITE ,
37
+ LIO_READ ,
38
+ }
37
39
}
38
40
39
- /// Mode for `lio_listio`.
40
- #[ repr( i32 ) ]
41
- #[ derive( Clone , Copy , Debug , PartialEq ) ]
42
- pub enum LioMode {
43
- /// Requests that `lio_listio` block until all requested operations have
44
- /// been completed
45
- LIO_WAIT = libc:: LIO_WAIT ,
46
- /// Requests that `lio_listio` return immediately
47
- LIO_NOWAIT = libc:: LIO_NOWAIT ,
41
+ libc_enum ! {
42
+ /// Mode for `lio_listio`.
43
+ #[ repr( i32 ) ]
44
+ pub enum LioMode {
45
+ /// Requests that `lio_listio` block until all requested operations have
46
+ /// been completed
47
+ LIO_WAIT ,
48
+ /// Requests that `lio_listio` return immediately
49
+ LIO_NOWAIT ,
50
+ }
48
51
}
49
52
50
53
/// Return values for `AioCb::cancel and aio_cancel_all`
@@ -68,7 +71,7 @@ enum Keeper<'a> {
68
71
/// Keeps a reference to a Boxed slice
69
72
boxed( Rc < Box < [ u8 ] > > ) ,
70
73
/// Keeps a reference to a slice
71
- phantom( PhantomData < & ' a mut [ u8 ] > )
74
+ phantom( PhantomData < & ' a mut [ u8 ] > ) ,
72
75
}
73
76
74
77
/// The basic structure used by all aio functions. Each `aiocb` represents one
@@ -80,7 +83,7 @@ pub struct AioCb<'a> {
80
83
/// Could this `AioCb` potentially have any in-kernel state?
81
84
in_progress : bool ,
82
85
/// Used to keep buffers from Drop'ing
83
- keeper : Keeper < ' a >
86
+ keeper : Keeper < ' a > ,
84
87
}
85
88
86
89
impl < ' a > AioCb < ' a > {
@@ -97,15 +100,18 @@ impl<'a> AioCb<'a> {
97
100
/// be prioritized at the process's priority level minus `prio`
98
101
/// * `sigev_notify` Determines how you will be notified of event
99
102
/// completion.
100
- pub fn from_fd ( fd : RawFd , prio : libc:: c_int ,
101
- sigev_notify : SigevNotify ) -> AioCb < ' a > {
103
+ pub fn from_fd ( fd : RawFd , prio : libc:: c_int , sigev_notify : SigevNotify ) -> AioCb < ' a > {
102
104
let mut a = AioCb :: common_init ( fd, prio, sigev_notify) ;
103
105
a. aio_offset = 0 ;
104
106
a. aio_nbytes = 0 ;
105
107
a. aio_buf = null_mut ( ) ;
106
108
107
- let aiocb = AioCb { aiocb : a, mutable : false , in_progress : false ,
108
- keeper : Keeper :: none} ;
109
+ let aiocb = AioCb {
110
+ aiocb : a,
111
+ mutable : false ,
112
+ in_progress : false ,
113
+ keeper : Keeper :: none,
114
+ } ;
109
115
aiocb
110
116
}
111
117
@@ -120,17 +126,26 @@ impl<'a> AioCb<'a> {
120
126
/// completion.
121
127
/// * `opcode` This field is only used for `lio_listio`. It determines
122
128
/// which operation to use for this individual aiocb
123
- pub fn from_mut_slice ( fd : RawFd , offs : off_t , buf : & ' a mut [ u8 ] ,
124
- prio : libc:: c_int , sigev_notify : SigevNotify ,
125
- opcode : LioOpcode ) -> AioCb < ' a > {
129
+ pub fn from_mut_slice (
130
+ fd : RawFd ,
131
+ offs : off_t ,
132
+ buf : & ' a mut [ u8 ] ,
133
+ prio : libc:: c_int ,
134
+ sigev_notify : SigevNotify ,
135
+ opcode : LioOpcode ,
136
+ ) -> AioCb < ' a > {
126
137
let mut a = AioCb :: common_init ( fd, prio, sigev_notify) ;
127
138
a. aio_offset = offs;
128
139
a. aio_nbytes = buf. len ( ) as size_t ;
129
140
a. aio_buf = buf. as_ptr ( ) as * mut c_void ;
130
141
a. aio_lio_opcode = opcode as libc:: c_int ;
131
142
132
- let aiocb = AioCb { aiocb : a, mutable : true , in_progress : false ,
133
- keeper : Keeper :: phantom ( PhantomData ) } ;
143
+ let aiocb = AioCb {
144
+ aiocb : a,
145
+ mutable : true ,
146
+ in_progress : false ,
147
+ keeper : Keeper :: phantom ( PhantomData ) ,
148
+ } ;
134
149
aiocb
135
150
}
136
151
@@ -148,17 +163,26 @@ impl<'a> AioCb<'a> {
148
163
/// completion.
149
164
/// * `opcode` This field is only used for `lio_listio`. It determines
150
165
/// which operation to use for this individual aiocb
151
- pub fn from_boxed_slice ( fd : RawFd , offs : off_t , buf : Rc < Box < [ u8 ] > > ,
152
- prio : libc:: c_int , sigev_notify : SigevNotify ,
153
- opcode : LioOpcode ) -> AioCb < ' a > {
166
+ pub fn from_boxed_slice (
167
+ fd : RawFd ,
168
+ offs : off_t ,
169
+ buf : Rc < Box < [ u8 ] > > ,
170
+ prio : libc:: c_int ,
171
+ sigev_notify : SigevNotify ,
172
+ opcode : LioOpcode ,
173
+ ) -> AioCb < ' a > {
154
174
let mut a = AioCb :: common_init ( fd, prio, sigev_notify) ;
155
175
a. aio_offset = offs;
156
176
a. aio_nbytes = buf. len ( ) as size_t ;
157
177
a. aio_buf = buf. as_ptr ( ) as * mut c_void ;
158
178
a. aio_lio_opcode = opcode as libc:: c_int ;
159
179
160
- let aiocb = AioCb { aiocb : a, mutable : true , in_progress : false ,
161
- keeper : Keeper :: boxed ( buf) } ;
180
+ let aiocb = AioCb {
181
+ aiocb : a,
182
+ mutable : true ,
183
+ in_progress : false ,
184
+ keeper : Keeper :: boxed ( buf) ,
185
+ } ;
162
186
aiocb
163
187
}
164
188
@@ -175,31 +199,42 @@ impl<'a> AioCb<'a> {
175
199
// then lio_listio wouldn't work, because that function needs a slice of
176
200
// AioCb, and they must all be the same type. We're basically stuck with
177
201
// using an unsafe function, since aio (as designed in C) is an unsafe API.
178
- pub fn from_slice ( fd : RawFd , offs : off_t , buf : & ' a [ u8 ] ,
179
- prio : libc:: c_int , sigev_notify : SigevNotify ,
180
- opcode : LioOpcode ) -> AioCb {
202
+ pub fn from_slice (
203
+ fd : RawFd ,
204
+ offs : off_t ,
205
+ buf : & ' a [ u8 ] ,
206
+ prio : libc:: c_int ,
207
+ sigev_notify : SigevNotify ,
208
+ opcode : LioOpcode ,
209
+ ) -> AioCb {
181
210
let mut a = AioCb :: common_init ( fd, prio, sigev_notify) ;
182
211
a. aio_offset = offs;
183
212
a. aio_nbytes = buf. len ( ) as size_t ;
184
213
// casting an immutable buffer to a mutable pointer looks unsafe,
185
214
// but technically its only unsafe to dereference it, not to create
186
215
// it.
187
216
a. aio_buf = buf. as_ptr ( ) as * mut c_void ;
188
- assert ! ( opcode != LioOpcode :: LIO_READ , "Can't read into an immutable buffer" ) ;
217
+ assert ! (
218
+ opcode != LioOpcode :: LIO_READ ,
219
+ "Can't read into an immutable buffer"
220
+ ) ;
189
221
a. aio_lio_opcode = opcode as libc:: c_int ;
190
222
191
- let aiocb = AioCb { aiocb : a, mutable : false , in_progress : false ,
192
- keeper : Keeper :: none} ;
223
+ let aiocb = AioCb {
224
+ aiocb : a,
225
+ mutable : false ,
226
+ in_progress : false ,
227
+ keeper : Keeper :: none,
228
+ } ;
193
229
aiocb
194
230
}
195
231
196
- fn common_init ( fd : RawFd , prio : libc:: c_int ,
197
- sigev_notify : SigevNotify ) -> libc:: aiocb {
232
+ fn common_init ( fd : RawFd , prio : libc:: c_int , sigev_notify : SigevNotify ) -> libc:: aiocb {
198
233
// Use mem::zeroed instead of explicitly zeroing each field, because the
199
234
// number and name of reserved fields is OS-dependent. On some OSes,
200
235
// some reserved fields are used the kernel for state, and must be
201
236
// explicitly zeroed when allocated.
202
- let mut a = unsafe { mem:: zeroed :: < libc:: aiocb > ( ) } ;
237
+ let mut a = unsafe { mem:: zeroed :: < libc:: aiocb > ( ) } ;
203
238
a. aio_fildes = fd;
204
239
a. aio_reqprio = prio;
205
240
a. aio_sigevent = SigEvent :: new ( sigev_notify) . sigevent ( ) ;
@@ -218,7 +253,7 @@ impl<'a> AioCb<'a> {
218
253
libc:: AIO_NOTCANCELED => Ok ( AioCancelStat :: AioNotCanceled ) ,
219
254
libc:: AIO_ALLDONE => Ok ( AioCancelStat :: AioAllDone ) ,
220
255
-1 => Err ( Error :: last ( ) ) ,
221
- _ => panic ! ( "unknown aio_cancel return value" )
256
+ _ => panic ! ( "unknown aio_cancel return value" ) ,
222
257
}
223
258
}
224
259
@@ -230,18 +265,15 @@ impl<'a> AioCb<'a> {
230
265
0 => Ok ( ( ) ) ,
231
266
num if num > 0 => Err ( Error :: from_errno ( Errno :: from_i32 ( num) ) ) ,
232
267
-1 => Err ( Error :: last ( ) ) ,
233
- num => panic ! ( "unknown aio_error return value {:?}" , num)
268
+ num => panic ! ( "unknown aio_error return value {:?}" , num) ,
234
269
}
235
270
}
236
271
237
272
/// An asynchronous version of `fsync`.
238
273
pub fn fsync ( & mut self , mode : AioFsyncMode ) -> Result < ( ) > {
239
274
let p: * mut libc:: aiocb = & mut self . aiocb ;
240
- Errno :: result ( unsafe {
241
- libc:: aio_fsync ( mode as libc:: c_int , p)
242
- } ) . map ( |_| {
243
- self . in_progress = true ;
244
- } )
275
+ Errno :: result ( unsafe { libc:: aio_fsync ( mode as libc:: c_int , p) } )
276
+ . map ( |_| { self . in_progress = true ; } )
245
277
}
246
278
247
279
/// Returns the `aiocb`'s `LioOpcode` field
@@ -253,7 +285,7 @@ impl<'a> AioCb<'a> {
253
285
libc:: LIO_READ => Some ( LioOpcode :: LIO_READ ) ,
254
286
libc:: LIO_WRITE => Some ( LioOpcode :: LIO_WRITE ) ,
255
287
libc:: LIO_NOP => Some ( LioOpcode :: LIO_NOP ) ,
256
- _ => None
288
+ _ => None ,
257
289
}
258
290
}
259
291
@@ -280,11 +312,7 @@ impl<'a> AioCb<'a> {
280
312
pub fn read ( & mut self ) -> Result < ( ) > {
281
313
assert ! ( self . mutable, "Can't read into an immutable buffer" ) ;
282
314
let p: * mut libc:: aiocb = & mut self . aiocb ;
283
- Errno :: result ( unsafe {
284
- libc:: aio_read ( p)
285
- } ) . map ( |_| {
286
- self . in_progress = true ;
287
- } )
315
+ Errno :: result ( unsafe { libc:: aio_read ( p) } ) . map ( |_| { self . in_progress = true ; } )
288
316
}
289
317
290
318
/// Returns the `SigEvent` stored in the `AioCb`
@@ -305,13 +333,8 @@ impl<'a> AioCb<'a> {
305
333
/// Asynchronously writes from a buffer to a file descriptor
306
334
pub fn write ( & mut self ) -> Result < ( ) > {
307
335
let p: * mut libc:: aiocb = & mut self . aiocb ;
308
- Errno :: result ( unsafe {
309
- libc:: aio_write ( p)
310
- } ) . map ( |_| {
311
- self . in_progress = true ;
312
- } )
336
+ Errno :: result ( unsafe { libc:: aio_write ( p) } ) . map ( |_| { self . in_progress = true ; } )
313
337
}
314
-
315
338
}
316
339
317
340
/// Cancels outstanding AIO requests. All requests for `fd` will be cancelled.
@@ -321,7 +344,7 @@ pub fn aio_cancel_all(fd: RawFd) -> Result<AioCancelStat> {
321
344
libc:: AIO_NOTCANCELED => Ok ( AioCancelStat :: AioNotCanceled ) ,
322
345
libc:: AIO_ALLDONE => Ok ( AioCancelStat :: AioAllDone ) ,
323
346
-1 => Err ( Error :: last ( ) ) ,
324
- _ => panic ! ( "unknown aio_cancel return value" )
347
+ _ => panic ! ( "unknown aio_cancel return value" ) ,
325
348
}
326
349
}
327
350
@@ -331,32 +354,25 @@ pub fn aio_cancel_all(fd: RawFd) -> Result<AioCancelStat> {
331
354
pub fn aio_suspend ( list : & [ & AioCb ] , timeout : Option < TimeSpec > ) -> Result < ( ) > {
332
355
// We must use transmute because Rust doesn't understand that a pointer to a
333
356
// Struct is the same as a pointer to its first element.
334
- let plist = unsafe {
335
- mem:: transmute :: < & [ & AioCb ] , * const [ * const libc:: aiocb ] > ( list)
336
- } ;
357
+ let plist = unsafe { mem:: transmute :: < & [ & AioCb ] , * const [ * const libc:: aiocb ] > ( list) } ;
337
358
let p = plist as * const * const libc:: aiocb ;
338
359
let timep = match timeout {
339
- None => null :: < libc:: timespec > ( ) ,
340
- Some ( x) => x. as_ref ( ) as * const libc:: timespec
360
+ None => null :: < libc:: timespec > ( ) ,
361
+ Some ( x) => x. as_ref ( ) as * const libc:: timespec ,
341
362
} ;
342
- Errno :: result ( unsafe {
343
- libc:: aio_suspend ( p, list. len ( ) as i32 , timep)
344
- } ) . map ( drop)
363
+ Errno :: result ( unsafe { libc:: aio_suspend ( p, list. len ( ) as i32 , timep) } ) . map ( drop)
345
364
}
346
365
347
366
348
367
/// Submits multiple asynchronous I/O requests with a single system call. The
349
368
/// order in which the requests are carried out is not specified.
350
369
#[ cfg( not( any( target_os = "ios" , target_os = "macos" ) ) ) ]
351
- pub fn lio_listio ( mode : LioMode , list : & [ & mut AioCb ] ,
352
- sigev_notify : SigevNotify ) -> Result < ( ) > {
370
+ pub fn lio_listio ( mode : LioMode , list : & [ & mut AioCb ] , sigev_notify : SigevNotify ) -> Result < ( ) > {
353
371
let sigev = SigEvent :: new ( sigev_notify) ;
354
372
let sigevp = & mut sigev. sigevent ( ) as * mut libc:: sigevent ;
355
373
// We must use transmute because Rust doesn't understand that a pointer to a
356
374
// Struct is the same as a pointer to its first element.
357
- let plist = unsafe {
358
- mem:: transmute :: < & [ & mut AioCb ] , * const [ * mut libc:: aiocb ] > ( list)
359
- } ;
375
+ let plist = unsafe { mem:: transmute :: < & [ & mut AioCb ] , * const [ * mut libc:: aiocb ] > ( list) } ;
360
376
let p = plist as * const * mut libc:: aiocb ;
361
377
Errno :: result ( unsafe {
362
378
libc:: lio_listio ( mode as i32 , p, list. len ( ) as i32 , sigevp)
0 commit comments