11use crate :: io:: uring:: open:: Open ;
22use crate :: io:: uring:: write:: Write ;
33use crate :: runtime:: Handle ;
4+
45use io_uring:: cqueue;
56use io_uring:: squeue:: Entry ;
67use std:: future:: Future ;
8+ use std:: io:: { self , Error } ;
9+ use std:: mem;
710use std:: pin:: Pin ;
8- use std:: task:: Context ;
9- use std:: task:: Poll ;
10- use std:: task:: Waker ;
11- use std:: { io, mem} ;
11+ use std:: task:: { Context , Poll , Waker } ;
1212
1313// This field isn't accessed directly, but it holds cancellation data,
1414// so `#[allow(dead_code)]` is needed.
@@ -110,7 +110,13 @@ impl From<cqueue::Entry> for CqeResult {
110110/// A trait that converts a CQE result into a usable value for each operation.
111111pub ( crate ) trait Completable {
112112 type Output ;
113- fn complete ( self , cqe : CqeResult ) -> io:: Result < Self :: Output > ;
113+ fn complete ( self , cqe : CqeResult ) -> Self :: Output ;
114+
115+ // This is used when you want to terminate an operation with an error.
116+ //
117+ // The `Op` type that implements this trait can return the passed error
118+ // upstream by embedding it in the `Output`.
119+ fn complete_with_error ( self , error : Error ) -> Self :: Output ;
114120}
115121
116122/// Extracts the `CancelData` needed to safely cancel an in-flight io_uring operation.
@@ -121,7 +127,7 @@ pub(crate) trait Cancellable {
121127impl < T : Cancellable > Unpin for Op < T > { }
122128
123129impl < T : Cancellable + Completable + Send > Future for Op < T > {
124- type Output = io :: Result < T :: Output > ;
130+ type Output = T :: Output ;
125131
126132 fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
127133 let this = self . get_mut ( ) ;
@@ -132,9 +138,21 @@ impl<T: Cancellable + Completable + Send> Future for Op<T> {
132138 State :: Initialize ( entry_opt) => {
133139 let entry = entry_opt. take ( ) . expect ( "Entry must be present" ) ;
134140 let waker = cx. waker ( ) . clone ( ) ;
141+
135142 // SAFETY: entry is valid for the entire duration of the operation
136- let idx = unsafe { driver. register_op ( entry, waker) ? } ;
137- this. state = State :: Polled ( idx) ;
143+ match unsafe { driver. register_op ( entry, waker) } {
144+ Ok ( idx) => this. state = State :: Polled ( idx) ,
145+ Err ( err) => {
146+ let data = this
147+ . take_data ( )
148+ . expect ( "Data must be present on Initialization" ) ;
149+
150+ this. state = State :: Complete ;
151+
152+ return Poll :: Ready ( data. complete_with_error ( err) ) ;
153+ }
154+ } ;
155+
138156 Poll :: Pending
139157 }
140158
0 commit comments