@@ -86,7 +86,7 @@ impl<T, U> Sender<T, U> {
86
86
}
87
87
let ( tx, rx) = oneshot:: channel ( ) ;
88
88
self . inner
89
- . send ( Envelope ( Some ( ( val, Callback :: Retry ( tx ) ) ) ) )
89
+ . send ( Envelope ( Some ( ( val, Callback :: Retry ( Some ( tx ) ) ) ) ) )
90
90
. map ( move |_| rx)
91
91
. map_err ( |mut e| ( e. 0 ) . 0 . take ( ) . expect ( "envelope not dropped" ) . 0 )
92
92
}
@@ -97,7 +97,7 @@ impl<T, U> Sender<T, U> {
97
97
}
98
98
let ( tx, rx) = oneshot:: channel ( ) ;
99
99
self . inner
100
- . send ( Envelope ( Some ( ( val, Callback :: NoRetry ( tx ) ) ) ) )
100
+ . send ( Envelope ( Some ( ( val, Callback :: NoRetry ( Some ( tx ) ) ) ) ) )
101
101
. map ( move |_| rx)
102
102
. map_err ( |mut e| ( e. 0 ) . 0 . take ( ) . expect ( "envelope not dropped" ) . 0 )
103
103
}
@@ -124,7 +124,7 @@ impl<T, U> UnboundedSender<T, U> {
124
124
pub ( crate ) fn try_send ( & mut self , val : T ) -> Result < RetryPromise < T , U > , T > {
125
125
let ( tx, rx) = oneshot:: channel ( ) ;
126
126
self . inner
127
- . send ( Envelope ( Some ( ( val, Callback :: Retry ( tx ) ) ) ) )
127
+ . send ( Envelope ( Some ( ( val, Callback :: Retry ( Some ( tx ) ) ) ) ) )
128
128
. map ( move |_| rx)
129
129
. map_err ( |mut e| ( e. 0 ) . 0 . take ( ) . expect ( "envelope not dropped" ) . 0 )
130
130
}
@@ -198,33 +198,59 @@ impl<T, U> Drop for Envelope<T, U> {
198
198
}
199
199
200
200
pub ( crate ) enum Callback < T , U > {
201
- Retry ( oneshot:: Sender < Result < U , ( crate :: Error , Option < T > ) > > ) ,
202
- NoRetry ( oneshot:: Sender < Result < U , crate :: Error > > ) ,
201
+ Retry ( Option < oneshot:: Sender < Result < U , ( crate :: Error , Option < T > ) > > > ) ,
202
+ NoRetry ( Option < oneshot:: Sender < Result < U , crate :: Error > > > ) ,
203
+ }
204
+
205
+ impl < T , U > Drop for Callback < T , U > {
206
+ fn drop ( & mut self ) {
207
+ // FIXME(nox): What errors do we want here?
208
+ let error = crate :: Error :: new_user_dispatch_gone ( ) . with ( if std:: thread:: panicking ( ) {
209
+ "user code panicked"
210
+ } else {
211
+ "runtime dropped the dispatch task"
212
+ } ) ;
213
+
214
+ match self {
215
+ Callback :: Retry ( tx) => {
216
+ if let Some ( tx) = tx. take ( ) {
217
+ let _ = tx. send ( Err ( ( error, None ) ) ) ;
218
+ }
219
+ }
220
+ Callback :: NoRetry ( tx) => {
221
+ if let Some ( tx) = tx. take ( ) {
222
+ let _ = tx. send ( Err ( error) ) ;
223
+ }
224
+ }
225
+ }
226
+ }
203
227
}
204
228
205
229
impl < T , U > Callback < T , U > {
206
230
#[ cfg( feature = "http2" ) ]
207
231
pub ( crate ) fn is_canceled ( & self ) -> bool {
208
232
match * self {
209
- Callback :: Retry ( ref tx) => tx. is_closed ( ) ,
210
- Callback :: NoRetry ( ref tx) => tx. is_closed ( ) ,
233
+ Callback :: Retry ( Some ( ref tx) ) => tx. is_closed ( ) ,
234
+ Callback :: NoRetry ( Some ( ref tx) ) => tx. is_closed ( ) ,
235
+ _ => unreachable ! ( ) ,
211
236
}
212
237
}
213
238
214
239
pub ( crate ) fn poll_canceled ( & mut self , cx : & mut task:: Context < ' _ > ) -> Poll < ( ) > {
215
240
match * self {
216
- Callback :: Retry ( ref mut tx) => tx. poll_closed ( cx) ,
217
- Callback :: NoRetry ( ref mut tx) => tx. poll_closed ( cx) ,
241
+ Callback :: Retry ( Some ( ref mut tx) ) => tx. poll_closed ( cx) ,
242
+ Callback :: NoRetry ( Some ( ref mut tx) ) => tx. poll_closed ( cx) ,
243
+ _ => unreachable ! ( ) ,
218
244
}
219
245
}
220
246
221
- pub ( crate ) fn send ( self , val : Result < U , ( crate :: Error , Option < T > ) > ) {
247
+ pub ( crate ) fn send ( mut self , val : Result < U , ( crate :: Error , Option < T > ) > ) {
222
248
match self {
223
- Callback :: Retry ( tx) => {
224
- let _ = tx. send ( val) ;
249
+ Callback :: Retry ( ref mut tx) => {
250
+ let _ = tx. take ( ) . unwrap ( ) . send ( val) ;
225
251
}
226
- Callback :: NoRetry ( tx) => {
227
- let _ = tx. send ( val. map_err ( |e| e. 0 ) ) ;
252
+ Callback :: NoRetry ( ref mut tx) => {
253
+ let _ = tx. take ( ) . unwrap ( ) . send ( val. map_err ( |e| e. 0 ) ) ;
228
254
}
229
255
}
230
256
}
0 commit comments