@@ -5,6 +5,7 @@ use std::error::Error;
5
5
use std:: fmt:: { self , Display , Formatter } ;
6
6
use std:: sync:: atomic;
7
7
8
+ use crate :: opcode:: PrepareSQE ;
8
9
use crate :: sys;
9
10
use crate :: util:: { unsync_load, Mmap } ;
10
11
@@ -43,6 +44,14 @@ pub struct SubmissionQueue<'a> {
43
44
#[ derive( Clone ) ]
44
45
pub struct Entry ( pub ( crate ) sys:: io_uring_sqe ) ;
45
46
47
+ /// Common options for Submission Queue Entry.
48
+ #[ derive( Clone , Copy , Default , Debug ) ]
49
+ pub struct OptionValues {
50
+ user_data : u64 ,
51
+ personality : u16 ,
52
+ flags : u8 ,
53
+ }
54
+
46
55
bitflags ! {
47
56
/// Submission flags
48
57
pub struct Flags : u8 {
@@ -269,6 +278,64 @@ impl SubmissionQueue<'_> {
269
278
Ok ( ( ) )
270
279
}
271
280
281
+ /// Attempts to push an opcode into the submission queue.
282
+ /// If the queue is full, an error is returned.
283
+ ///
284
+ /// # Safety
285
+ ///
286
+ /// Developers must ensure that parameters of the opcode (such as buffer) are valid and will
287
+ /// be valid for the entire duration of the operation, otherwise it may cause memory problems.
288
+ #[ inline]
289
+ pub unsafe fn push_opcode < ' a , T : PrepareSQE > (
290
+ & ' a mut self ,
291
+ opcode : & T ,
292
+ options : Option < & OptionValues > ,
293
+ ) -> Result < ( ) , PushError > {
294
+ if !self . is_full ( ) {
295
+ let sqe = self . next_sqe ( ) ;
296
+ opcode. prepare ( sqe) ;
297
+ options. map ( |o| Self :: set_sqe_options ( sqe, o) ) ;
298
+ Ok ( ( ) )
299
+ } else {
300
+ Err ( PushError )
301
+ }
302
+ }
303
+
304
+ /// Attempts to push several opcodes into the queue.
305
+ /// If the queue does not have space for all of the entries, an error is returned.
306
+ ///
307
+ /// # Safety
308
+ ///
309
+ /// Developers must ensure that parameters of all the entries (such as buffer) are valid and
310
+ /// will be valid for the entire duration of the operation, otherwise it may cause memory
311
+ /// problems.
312
+ #[ cfg( feature = "unstable" ) ]
313
+ #[ inline]
314
+ pub unsafe fn push_multiple_opcode < ' a , T : PrepareSQE > (
315
+ & ' a mut self ,
316
+ ops : & [ ( T , Option < & OptionValues > ) ] ,
317
+ ) -> Result < ( ) , PushError > {
318
+ if self . capacity ( ) - self . len ( ) < ops. len ( ) {
319
+ return Err ( PushError ) ;
320
+ }
321
+
322
+ for ( opcode, options) in ops {
323
+ let sqe = self . next_sqe ( ) ;
324
+ opcode. prepare ( sqe) ;
325
+ options. map ( |o| Self :: set_sqe_options ( sqe, o) ) ;
326
+ self . move_forward ( ) ;
327
+ }
328
+
329
+ Ok ( ( ) )
330
+ }
331
+
332
+ #[ inline]
333
+ fn set_sqe_options ( sqe : & mut sys:: io_uring_sqe , options : & OptionValues ) {
334
+ sqe. user_data = options. user_data ;
335
+ sqe. personality = options. personality ;
336
+ sqe. flags = options. flags ;
337
+ }
338
+
272
339
#[ inline]
273
340
fn next_sqe ( & mut self ) -> & mut sys:: io_uring_sqe {
274
341
// Safe because we are accessing an entry in the allocated submission queue.
@@ -320,6 +387,44 @@ impl Entry {
320
387
}
321
388
}
322
389
390
+ impl OptionValues {
391
+ /// Create a new instance of `OptionValues`.
392
+ pub fn new ( user_data : u64 , personality : u16 , flags : Flags ) -> Self {
393
+ OptionValues {
394
+ user_data,
395
+ personality,
396
+ flags : flags. bits ( ) ,
397
+ }
398
+ }
399
+
400
+ /// Set the user data.
401
+ ///
402
+ /// This is an application-supplied value that will be passed straight through into the
403
+ /// [completion queue entry](crate::cqueue::Entry::user_data).
404
+ #[ inline]
405
+ pub fn user_data ( mut self , user_data : u64 ) -> Self {
406
+ self . user_data = user_data;
407
+ self
408
+ }
409
+
410
+ /// Set the personality of this event.
411
+ ///
412
+ /// You can obtain a personality using
413
+ /// [`Submitter::register_personality`](crate::Submitter::register_personality).
414
+ #[ inline]
415
+ pub fn personality ( mut self , personality : u16 ) -> Self {
416
+ self . personality = personality;
417
+ self
418
+ }
419
+
420
+ /// Set the submission event's [flags](Flags).
421
+ #[ inline]
422
+ pub fn flags ( mut self , flags : Flags ) -> Self {
423
+ self . flags |= flags. bits ( ) ;
424
+ self
425
+ }
426
+ }
427
+
323
428
/// An error pushing to the submission queue due to it being full.
324
429
#[ derive( Debug , Clone , PartialEq , Eq ) ]
325
430
#[ non_exhaustive]
0 commit comments