Promote SendRequest::pending to an OpaqueStreamRef. (#281)
Because `self.pending` doesn't necessarily get cleaned up in a timely fashion - rather, only when the user calls `poll_ready()` - it was possible for it to refer to a stream that has already been closed. This would lead to a panic the next time that `poll_ready()` was called. Instead, use an `OpaqueStreamRef`, bumping the refcount. A change to an existing test is included which demonstrates the issue.
This commit is contained in:
		
				
					committed by
					
						 Sean McArthur
						Sean McArthur
					
				
			
			
				
	
			
			
			
						parent
						
							1b9469ff75
						
					
				
				
					commit
					23234fa14f
				
			| @@ -567,7 +567,7 @@ where | ||||
|         &mut self, | ||||
|         request: Request<()>, | ||||
|         end_of_stream: bool, | ||||
|         pending: Option<&store::Key>, | ||||
|         pending: Option<&OpaqueStreamRef>, | ||||
|     ) -> Result<StreamRef<B>, SendError> { | ||||
|         use http::Method; | ||||
|         use super::stream::ContentLength; | ||||
| @@ -593,8 +593,8 @@ where | ||||
|             // | ||||
|             // If that stream is still pending, the Client isn't allowed to | ||||
|             // queue up another pending stream. They should use `poll_ready`. | ||||
|             if let Some(key) = pending { | ||||
|                 if me.store.resolve(*key).is_pending_open { | ||||
|             if let Some(stream) = pending { | ||||
|                 if me.store.resolve(stream.key).is_pending_open { | ||||
|                     return Err(UserError::Rejected.into()); | ||||
|                 } | ||||
|             } | ||||
| @@ -697,15 +697,15 @@ impl<B> Streams<B, client::Peer> | ||||
| where | ||||
|     B: Buf, | ||||
| { | ||||
|     pub fn poll_pending_open(&mut self, key: Option<&store::Key>) -> Poll<(), ::Error> { | ||||
|     pub fn poll_pending_open(&mut self, pending: Option<&OpaqueStreamRef>) -> Poll<(), ::Error> { | ||||
|         let mut me = self.inner.lock().unwrap(); | ||||
|         let me = &mut *me; | ||||
|  | ||||
|         me.actions.ensure_no_conn_error()?; | ||||
|         me.actions.send.ensure_next_stream_id()?; | ||||
|  | ||||
|         if let Some(key) = key { | ||||
|             let mut stream = me.store.resolve(*key); | ||||
|         if let Some(pending) = pending { | ||||
|             let mut stream = me.store.resolve(pending.key); | ||||
|             trace!("poll_pending_open; stream = {:?}", stream.is_pending_open); | ||||
|             if stream.is_pending_open { | ||||
|                 stream.wait_send(); | ||||
| @@ -941,10 +941,6 @@ impl<B> StreamRef<B> { | ||||
|             .map_err(From::from) | ||||
|     } | ||||
|  | ||||
|     pub(crate) fn key(&self) -> store::Key { | ||||
|         self.opaque.key | ||||
|     } | ||||
|  | ||||
|     pub fn clone_to_opaque(&self) -> OpaqueStreamRef | ||||
|         where B: 'static, | ||||
|     { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user