@@ -16,116 +16,153 @@ impl Debug for Extra {
1616
1717impl < I : Into < imp:: Extra > > From < I > for Extra {
1818 fn from ( inner : I ) -> Self {
19- Self :: new ( inner. into ( ) )
19+ Self ( inner. into ( ) )
2020 }
2121}
2222
2323impl Extra {
24- pub ( in crate :: sys) fn new ( inner : imp:: Extra ) -> Self {
25- Self ( inner)
26- }
24+ iour_only ! {
25+ /// Checks whether this completion reports a notification (2nd CQE returned for a zerocopy op).
26+ ///
27+ /// # Behaviour
28+ ///
29+ /// This is only supported on `io_uring` drivers, in which the driver will
30+ /// check whether the `IORING_CQE_F_NOTIF` flag was set by the kernel for
31+ /// the CQE. On other platforms, this will always return the
32+ /// [`Unsupported`] error.
33+ ///
34+ /// [`Unsupported`]: io::ErrorKind::Unsupported
35+ get fn is_notification( & self ) -> io:: Result <bool > = |extra| Ok ( extra. is_notification( ) ) ;
2736
28- /// Set the personality, returning the modified Extra.
29- ///
30- /// This is a no-op when not using `io_uring` driver.
31- pub fn with_personality ( mut self , personality : u16 ) -> Self {
32- self . set_personality ( personality) ;
33- self
34- }
37+ /// Try to get the buffer ID associated with this operation.
38+ ///
39+ /// # Behavior
40+ ///
41+ /// This is only supported on `io_uring` drivers, in which the driver will
42+ /// try to extract `buffer_id` returned by the kernel as a part of `flags`.
43+ /// If the id cannot be extracted from the flag, an [`InvalidInput`]
44+ /// [`io::Error`] will be returned. On other platforms, this will always
45+ /// return [`Unsupported`] error.
46+ ///
47+ /// [`InvalidInput`]: io::ErrorKind::InvalidInput
48+ /// [`Unsupported`]: io::ErrorKind::Unsupported
49+ get fn buffer_id( & self ) -> io:: Result <u16 > =
50+ |extra| extra
51+ . buffer_id( )
52+ . ok_or_else( || io:: Error :: new( io:: ErrorKind :: InvalidInput , "Buffer id was not set" ) ) ;
3553
36- /// Set the personality for this operation.
37- ///
38- /// This is a no-op when not using `io_uring` driver.
39- pub fn set_personality ( & mut self , personality : u16 ) {
40- #[ cfg( io_uring) ]
41- if let Some ( extra) = self . try_as_iour_mut ( ) {
42- extra. set_personality ( personality) ;
43- }
44- #[ cfg( not( io_uring) ) ]
45- let _ = personality;
46- }
4754
48- /// Get the personality for this operation.
49- ///
50- /// If the personality was not set with [`set_personality`] or the platform
51- /// does not support it, returns [`None`].
52- ///
53- /// [`set_personality`]: Extra::set_personality
54- pub fn get_personality ( & self ) -> Option < u16 > {
55- #[ cfg( io_uring) ]
56- if let Some ( extra) = self . try_as_iour ( ) {
57- extra. get_personality ( )
58- } else {
59- None
60- }
61- #[ cfg( not( io_uring) ) ]
62- None
55+ /// Get the personality for this operation.
56+ ///
57+ /// # Behavior
58+ ///
59+ /// - If the driver is not `io_uring`, return [`Unsupported`] error,
60+ /// - If the personality was not set with [`set_personality`], return `Ok(None)`
61+ /// - Otherwise, return `Ok(Some(personality))`
62+ ///
63+ /// [`Unsupported`]: io::ErrorKind::Unsupported
64+ /// [`set_personality`]: Extra::set_personality
65+ get fn get_personality( & self ) -> io:: Result <Option <u16 >> = |extra| Ok ( extra. get_personality( ) ) ;
66+
67+ /// Checks whether the underlying socket has more data to be read.
68+ ///
69+ /// # Behaviour
70+ ///
71+ /// This method must be used only on the flags for any of the `receive`
72+ /// variants supported by `IO_URING`. The driver will try to check whether
73+ /// the `IORING_CQE_F_SOCK_NONEMPTY` flag was set by the kernel for the CQE.
74+ /// On other platforms, this will always return the [`Unsupported`] error.
75+ ///
76+ /// [`Unsupported`]: io::ErrorKind::Unsupported
77+ get fn sock_nonempty( & self ) -> io:: Result <bool > = |extra| Ok ( extra. sock_nonempty( ) ) ;
78+
79+ /// Set the `IOSQE_IO_DRAIN` flag for this operation.
80+ ///
81+ /// This ensures that this operation won't start until all previously submitted operations complete.
82+ ///
83+ /// See [`io_uring_sqe_set_flags(3)`] for more details.
84+ ///
85+ /// [`io_uring_sqe_set_flags(3)`]: https://man7.org/linux/man-pages/man3/io_uring_sqe_set_flags.3.html
86+ set fn drain( & mut self ) = |extra| extra. set_drain( ) ;
87+
88+ /// Set the `IOSQE_IO_LINK` flag for this operation.
89+ ///
90+ /// This links this operation with the next one. The next operation will not start until this operation
91+ /// completed successfully.
92+ ///
93+ /// See [`io_uring_sqe_set_flags(3)`] for more details.
94+ ///
95+ /// [`io_uring_sqe_set_flags(3)`]: https://man7.org/linux/man-pages/man3/io_uring_sqe_set_flags.3.html
96+ set fn link( & mut self ) = |extra| extra. set_link( ) ;
97+
98+ /// Set the `IOSQE_IO_HARDLINK` flag for this operation.
99+ ///
100+ /// Like link, but the next operation will execute regardless of this operation's result.
101+ ///
102+ /// See [`io_uring_sqe_set_flags(3)`] for more details.
103+ ///
104+ /// [`io_uring_sqe_set_flags(3)`]: https://man7.org/linux/man-pages/man3/io_uring_sqe_set_flags.3.html
105+ set fn hardlink( & mut self ) = |extra| extra. set_hardlink( ) ;
106+
107+ /// Set the personality for this operation.
108+ ///
109+ /// A personality represents a set of credentials (uid, gid, etc.) that will be used for this operation.
110+ ///
111+ /// The personality can be retrieved with [`Proactor::register_personality`].
112+ ///
113+ /// [`Proactor::register_personality`]: crate::Proactor::register_personality
114+ set fn personality( & mut self , personality: u16 ) = |extra| extra. set_personality( personality) ;
63115 }
116+ }
64117
65- /// Try to get the buffer ID associated with this operation.
66- ///
67- /// # Behavior
68- ///
69- /// This is only supported on `io_uring` drivers, in which the driver will
70- /// try to extract `buffer_id` returned by the kernel as a part of `flags`.
71- /// If the id cannot be extracted from the flag, an [`InvalidInput`]
72- /// [`io::Error`] will be returned. On other platforms, this will always
73- /// return [`Unsupported`] error.
74- ///
75- /// [`InvalidInput`]: io::ErrorKind::InvalidInput
76- /// [`Unsupported`]: io::ErrorKind::Unsupported
77- pub fn buffer_id ( & self ) -> io:: Result < u16 > {
78- #[ cfg( io_uring) ]
79- {
80- if let Some ( extra) = self . try_as_iour ( ) {
81- extra
82- . buffer_id ( )
83- . ok_or_else ( || io:: Error :: new ( io:: ErrorKind :: InvalidInput , "flags are invalid" ) )
118+ macro_rules! iour_only {
119+ { } => { } ;
120+ {
121+ $( #[ $doc: meta] ) *
122+ get fn $fn: ident( & $this: ident) -> io:: Result <$ret: ty> = |$extra: ident| $body: expr;
123+ $( $rest: tt) *
124+ } => {
125+ $( #[ $doc] ) *
126+ pub fn $fn ( & $this) -> io:: Result <$ret> {
127+ const UNSUPPORTED : & str = concat!( stringify!( $fn) , " is only supported on the io_uring driver" ) ;
128+ #[ cfg( io_uring) ]
129+ if let Some ( $extra) = $this. try_as_iour( ) {
130+ $body
84131 } else {
85- Err ( io:: Error :: new (
86- io:: ErrorKind :: Unsupported ,
87- "buffer_id is only supported on io_uring driver" ,
88- ) )
132+ Err ( io:: Error :: new( io:: ErrorKind :: Unsupported , UNSUPPORTED ) )
89133 }
134+ #[ cfg( not( io_uring) ) ]
135+ Err ( io:: Error :: new( io:: ErrorKind :: Unsupported , UNSUPPORTED ) )
90136 }
91- #[ cfg( not( io_uring) ) ]
92- {
93- Err ( io:: Error :: new (
94- io:: ErrorKind :: Unsupported ,
95- "buffer_id is only supported on io_uring driver" ,
96- ) )
97- }
98- }
137+ iour_only!( $( $rest) * ) ;
138+ } ;
139+ {
140+ $( #[ $doc: meta] ) *
141+ set fn $val: ident( & mut $this: ident $( , $arg: ident: $arg_ty: ty) * ) = |$extra: ident| $body: expr;
142+ $( $rest: tt) *
143+ } => {
144+ paste:: paste! {
145+ $( #[ $doc] ) *
146+ #[ doc = " This is a no-op when not using `io_uring` driver." ]
147+ pub fn [ <set_ $val>] ( & mut $this $( , $arg: $arg_ty) * ) {
148+ #[ cfg( io_uring) ]
149+ if let Some ( $extra) = $this. try_as_iour_mut( ) {
150+ $body
151+ }
152+ #[ cfg( not( io_uring) ) ]
153+ { $( let _ = $arg; ) * }
154+ }
99155
100- /// Checks whether the underlying socket has more data to be read.
101- ///
102- /// # Behaviour
103- ///
104- /// This method must be used only on the flags for any of the `receive`
105- /// variants supported by `IO_URING`.
106- /// The driver will try to check whether the `IORING_CQE_F_SOCK_NONEMPTY`
107- /// flag was set by the kernel for the CQE. On other platforms, this will
108- /// always return the [`Unsupported`] error.
109- ///
110- /// [`Unsupported`]: io::ErrorKind::Unsupported
111- pub fn sock_nonempty ( & self ) -> io:: Result < bool > {
112- #[ cfg( io_uring) ]
113- {
114- if let Some ( extra) = self . try_as_iour ( ) {
115- Ok ( extra. sock_nonempty ( ) )
116- } else {
117- Err ( io:: Error :: new (
118- io:: ErrorKind :: Unsupported ,
119- "IORING_CQE_F_SOCK_NONEMPTY flag is available only on the io_uring driver" ,
120- ) )
156+ #[ doc = concat!( "Call [`set_" , stringify!( $val) , "`] and return the modified `Extra`." ) ]
157+ #[ doc = "" ]
158+ #[ doc = concat!( "[`set_" , stringify!( $val) , "`]: Self::set_" , stringify!( $val) ) ]
159+ pub fn [ <with_ $val>] ( mut $this $( , $arg: $arg_ty) * ) -> Self {
160+ $this. [ <set_ $val>] ( $( $arg) ,* ) ;
161+ $this
121162 }
122163 }
123- #[ cfg( not( io_uring) ) ]
124- {
125- Err ( io:: Error :: new (
126- io:: ErrorKind :: Unsupported ,
127- "IORING_CQE_F_SOCK_NONEMPTY flag is available only on the io_uring driver" ,
128- ) )
129- }
130- }
164+ iour_only!( $( $rest) * ) ;
165+ } ;
131166}
167+
168+ use iour_only;
0 commit comments