fix graceful shutdown to close once idle (#296)
This commit is contained in:
		
				
					committed by
					
						 Carl Lerche
						Carl Lerche
					
				
			
			
				
	
			
			
			
						parent
						
							fdfb873438
						
					
				
				
					commit
					c564273986
				
			| @@ -127,6 +127,8 @@ impl GoAway { | |||||||
|                 .expect("invalid GOAWAY frame"); |                 .expect("invalid GOAWAY frame"); | ||||||
|  |  | ||||||
|             return Ok(Async::Ready(Some(reason))); |             return Ok(Async::Ready(Some(reason))); | ||||||
|  |         } else if self.should_close_now() { | ||||||
|  |             return Ok(Async::Ready(self.going_away_reason())); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         Ok(Async::Ready(None)) |         Ok(Async::Ready(None)) | ||||||
|   | |||||||
| @@ -364,6 +364,17 @@ impl AsyncWrite for Mock { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | impl Drop for Mock { | ||||||
|  |     fn drop(&mut self) { | ||||||
|  |         let mut me = self.pipe.inner.lock().unwrap(); | ||||||
|  |         me.closed = true; | ||||||
|  |  | ||||||
|  |         if let Some(task) = me.tx_task.take() { | ||||||
|  |             task.notify(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| // ===== impl Pipe ===== | // ===== impl Pipe ===== | ||||||
|  |  | ||||||
| impl io::Read for Pipe { | impl io::Read for Pipe { | ||||||
| @@ -375,7 +386,12 @@ impl io::Read for Pipe { | |||||||
|  |  | ||||||
|         let mut me = self.inner.lock().unwrap(); |         let mut me = self.inner.lock().unwrap(); | ||||||
|  |  | ||||||
|  |  | ||||||
|         if me.tx.is_empty() { |         if me.tx.is_empty() { | ||||||
|  |             if me.closed { | ||||||
|  |                 return Ok(0); | ||||||
|  |             } | ||||||
|  |  | ||||||
|             me.tx_task = Some(task::current()); |             me.tx_task = Some(task::current()); | ||||||
|             return Err(WouldBlock.into()); |             return Err(WouldBlock.into()); | ||||||
|         } |         } | ||||||
| @@ -442,7 +458,7 @@ pub trait HandleFutureExt { | |||||||
|             Box::new(map); |             Box::new(map); | ||||||
|         RecvFrame { |         RecvFrame { | ||||||
|             inner: boxed, |             inner: boxed, | ||||||
|             frame: settings.into().into(), |             frame: Some(settings.into().into()), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -460,7 +476,14 @@ pub trait HandleFutureExt { | |||||||
|         Self: IntoRecvFrame + Sized, |         Self: IntoRecvFrame + Sized, | ||||||
|         T: Into<Frame>, |         T: Into<Frame>, | ||||||
|     { |     { | ||||||
|         self.into_recv_frame(frame.into()) |         self.into_recv_frame(Some(frame.into())) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn recv_eof(self) -> RecvFrame<<Self as IntoRecvFrame>::Future> | ||||||
|  |     where | ||||||
|  |         Self: IntoRecvFrame + Sized, | ||||||
|  |     { | ||||||
|  |         self.into_recv_frame(None) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fn send_frame<T>(self, frame: T) -> SendFrameFut<Self> |     fn send_frame<T>(self, frame: T) -> SendFrameFut<Self> | ||||||
| @@ -623,7 +646,7 @@ pub trait HandleFutureExt { | |||||||
|  |  | ||||||
| pub struct RecvFrame<T> { | pub struct RecvFrame<T> { | ||||||
|     inner: T, |     inner: T, | ||||||
|     frame: Frame, |     frame: Option<Frame>, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<T> Future for RecvFrame<T> | impl<T> Future for RecvFrame<T> | ||||||
| @@ -642,10 +665,8 @@ where | |||||||
|             Async::NotReady => return Ok(Async::NotReady), |             Async::NotReady => return Ok(Async::NotReady), | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         let frame = frame.unwrap(); |  | ||||||
|  |  | ||||||
|         match (frame, &self.frame) { |         match (frame, &self.frame) { | ||||||
|             (Data(ref a), &Data(ref b)) => { |             (Some(Data(ref a)), &Some(Data(ref b))) => { | ||||||
|                 assert_eq!(a.payload().len(), b.payload().len(), "recv_frame data payload len"); |                 assert_eq!(a.payload().len(), b.payload().len(), "recv_frame data payload len"); | ||||||
|                 assert_eq!(a, b, "recv_frame"); |                 assert_eq!(a, b, "recv_frame"); | ||||||
|             } |             } | ||||||
| @@ -712,13 +733,13 @@ where | |||||||
|  |  | ||||||
| pub trait IntoRecvFrame { | pub trait IntoRecvFrame { | ||||||
|     type Future: Future; |     type Future: Future; | ||||||
|     fn into_recv_frame(self, frame: Frame) -> RecvFrame<Self::Future>; |     fn into_recv_frame(self, frame: Option<Frame>) -> RecvFrame<Self::Future>; | ||||||
| } | } | ||||||
|  |  | ||||||
| impl IntoRecvFrame for Handle { | impl IntoRecvFrame for Handle { | ||||||
|     type Future = ::futures::stream::StreamFuture<Self>; |     type Future = ::futures::stream::StreamFuture<Self>; | ||||||
|  |  | ||||||
|     fn into_recv_frame(self, frame: Frame) -> RecvFrame<Self::Future> { |     fn into_recv_frame(self, frame: Option<Frame>) -> RecvFrame<Self::Future> { | ||||||
|         RecvFrame { |         RecvFrame { | ||||||
|             inner: self.into_future(), |             inner: self.into_future(), | ||||||
|             frame: frame, |             frame: frame, | ||||||
| @@ -733,7 +754,7 @@ where | |||||||
| { | { | ||||||
|     type Future = Box<Future<Item = (Option<Frame>, Handle), Error = ()>>; |     type Future = Box<Future<Item = (Option<Frame>, Handle), Error = ()>>; | ||||||
|  |  | ||||||
|     fn into_recv_frame(self, frame: Frame) -> RecvFrame<Self::Future> { |     fn into_recv_frame(self, frame: Option<Frame>) -> RecvFrame<Self::Future> { | ||||||
|         let into_fut = Box::new( |         let into_fut = Box::new( | ||||||
|             self.unwrap() |             self.unwrap() | ||||||
|                 .and_then(|handle| handle.into_future().unwrap()), |                 .and_then(|handle| handle.into_future().unwrap()), | ||||||
|   | |||||||
| @@ -268,7 +268,7 @@ fn graceful_shutdown() { | |||||||
|         .send_frame(frames::data(7, "").eos()) |         .send_frame(frames::data(7, "").eos()) | ||||||
|         .send_frame(frames::data(3, "").eos()) |         .send_frame(frames::data(3, "").eos()) | ||||||
|         .recv_frame(frames::headers(3).response(200).eos()) |         .recv_frame(frames::headers(3).response(200).eos()) | ||||||
|         .close(); //TODO: closed()? |         .recv_eof(); | ||||||
|  |  | ||||||
|     let srv = server::handshake(io) |     let srv = server::handshake(io) | ||||||
|         .expect("handshake") |         .expect("handshake") | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user