Remove P generic from type
This commit is contained in:
@@ -19,7 +19,7 @@ pub struct Connection<T, P, B: IntoBuf = Bytes> {
|
||||
// TODO: Remove <B>
|
||||
ping_pong: PingPong<B::Buf>,
|
||||
settings: Settings,
|
||||
streams: Streams<P, B::Buf>,
|
||||
streams: Streams<B::Buf>,
|
||||
|
||||
_phantom: PhantomData<P>,
|
||||
}
|
||||
@@ -31,7 +31,7 @@ impl<T, P, B> Connection<T, P, B>
|
||||
{
|
||||
pub fn new(codec: Codec<T, B::Buf>) -> Connection<T, P, B> {
|
||||
// TODO: Actually configure
|
||||
let streams = Streams::new(streams::Config {
|
||||
let streams = Streams::new::<P>(streams::Config {
|
||||
max_remote_initiated: None,
|
||||
init_remote_window_sz: DEFAULT_INITIAL_WINDOW_SIZE,
|
||||
max_local_initiated: None,
|
||||
@@ -123,7 +123,7 @@ impl<T, P, B> Connection<T, P, B>
|
||||
Some(Headers(frame)) => {
|
||||
trace!("recv HEADERS; frame={:?}", frame);
|
||||
|
||||
if let Some(frame) = try!(self.streams.recv_headers(frame)) {
|
||||
if let Some(frame) = try!(self.streams.recv_headers::<P>(frame)) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
@@ -138,15 +138,15 @@ impl<T, P, B> Connection<T, P, B>
|
||||
}
|
||||
Some(Data(frame)) => {
|
||||
trace!("recv DATA; frame={:?}", frame);
|
||||
try!(self.streams.recv_data(frame));
|
||||
try!(self.streams.recv_data::<P>(frame));
|
||||
}
|
||||
Some(Reset(frame)) => {
|
||||
trace!("recv RST_STREAM; frame={:?}", frame);
|
||||
try!(self.streams.recv_reset(frame));
|
||||
try!(self.streams.recv_reset::<P>(frame));
|
||||
}
|
||||
Some(PushPromise(frame)) => {
|
||||
trace!("recv PUSH_PROMISE; frame={:?}", frame);
|
||||
self.streams.recv_push_promise(frame)?;
|
||||
self.streams.recv_push_promise::<P>(frame)?;
|
||||
}
|
||||
Some(Settings(frame)) => {
|
||||
trace!("recv SETTINGS; frame={:?}", frame);
|
||||
@@ -263,7 +263,7 @@ impl<T, B> Connection<T, client::Peer, B>
|
||||
{
|
||||
/// Initialize a new HTTP/2.0 stream and send the message.
|
||||
pub fn send_request(&mut self, request: Request<()>, end_of_stream: bool)
|
||||
-> Result<StreamRef<client::Peer, B::Buf>, ConnectionError>
|
||||
-> Result<StreamRef<B::Buf>, ConnectionError>
|
||||
{
|
||||
self.streams.send_request(request, end_of_stream)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use std::collections::VecDeque;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct Recv<P, B> {
|
||||
pub(super) struct Recv<B> {
|
||||
/// Maximum number of remote initiated streams
|
||||
max_streams: Option<usize>,
|
||||
|
||||
@@ -31,7 +31,7 @@ pub(super) struct Recv<P, B> {
|
||||
/// Refused StreamId, this represents a frame that must be sent out.
|
||||
refused: Option<StreamId>,
|
||||
|
||||
_p: PhantomData<(P, B)>,
|
||||
_p: PhantomData<(B)>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -46,10 +46,7 @@ struct Indices {
|
||||
tail: store::Key,
|
||||
}
|
||||
|
||||
impl<P, B> Recv<P, B>
|
||||
where P: Peer,
|
||||
B: Buf,
|
||||
{
|
||||
impl<B> Recv<B> where B: Buf {
|
||||
pub fn new(config: &Config) -> Self {
|
||||
Recv {
|
||||
max_streams: config.max_remote_initiated,
|
||||
@@ -66,10 +63,12 @@ impl<P, B> Recv<P, B>
|
||||
/// Update state reflecting a new, remotely opened stream
|
||||
///
|
||||
/// Returns the stream state if successful. `None` if refused
|
||||
pub fn open(&mut self, id: StreamId) -> Result<Option<Stream<B>>, ConnectionError> {
|
||||
pub fn open<P: Peer>(&mut self, id: StreamId)
|
||||
-> Result<Option<Stream<B>>, ConnectionError>
|
||||
{
|
||||
assert!(self.refused.is_none());
|
||||
|
||||
try!(self.ensure_can_open(id));
|
||||
try!(self.ensure_can_open::<P>(id));
|
||||
|
||||
if !self.can_inc_num_streams() {
|
||||
self.refused = Some(id);
|
||||
@@ -79,10 +78,30 @@ impl<P, B> Recv<P, B>
|
||||
Ok(Some(Stream::new(id)))
|
||||
}
|
||||
|
||||
pub fn poll_response(&mut self, stream: &mut store::Ptr<B>)
|
||||
-> Poll<Response<()>, ConnectionError> {
|
||||
// If the buffer is not empty, then the first frame must be a HEADERS
|
||||
// frame or the user violated the contract.
|
||||
match stream.pending_recv.pop_front(&mut self.buffer) {
|
||||
Some(Frame::Headers(v)) => {
|
||||
// TODO: This error should probably be caught on receipt of the
|
||||
// frame vs. now.
|
||||
Ok(client::Peer::convert_poll_message(v)?.into())
|
||||
}
|
||||
Some(frame) => unimplemented!(),
|
||||
None => {
|
||||
stream.state.ensure_recv_open()?;
|
||||
|
||||
stream.recv_task = Some(task::current());
|
||||
Ok(Async::NotReady)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Transition the stream state based on receiving headers
|
||||
pub fn recv_headers(&mut self,
|
||||
frame: frame::Headers,
|
||||
stream: &mut store::Ptr<B>)
|
||||
pub fn recv_headers<P: Peer>(&mut self,
|
||||
frame: frame::Headers,
|
||||
stream: &mut store::Ptr<B>)
|
||||
-> Result<Option<frame::Headers>, ConnectionError>
|
||||
{
|
||||
let is_initial = stream.state.recv_open(self.init_window_sz, frame.is_end_stream())?;
|
||||
@@ -155,11 +174,13 @@ impl<P, B> Recv<P, B>
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn recv_push_promise(&mut self, frame: frame::PushPromise, stream: &mut store::Ptr<B>)
|
||||
pub fn recv_push_promise<P: Peer>(&mut self,
|
||||
frame: frame::PushPromise,
|
||||
stream: &mut store::Ptr<B>)
|
||||
-> Result<(), ConnectionError>
|
||||
{
|
||||
// First, make sure that the values are legit
|
||||
self.ensure_can_reserve(frame.promised_id())?;
|
||||
self.ensure_can_reserve::<P>(frame.promised_id())?;
|
||||
|
||||
// Make sure that the stream state is valid
|
||||
stream.state.ensure_recv_open()?;
|
||||
@@ -241,7 +262,9 @@ impl<P, B> Recv<P, B>
|
||||
}
|
||||
|
||||
/// Returns true if the remote peer can initiate a stream with the given ID.
|
||||
fn ensure_can_open(&self, id: StreamId) -> Result<(), ConnectionError> {
|
||||
fn ensure_can_open<P: Peer>(&self, id: StreamId)
|
||||
-> Result<(), ConnectionError>
|
||||
{
|
||||
if !P::is_server() {
|
||||
// Remote is a server and cannot open streams. PushPromise is
|
||||
// registered by reserving, so does not go through this path.
|
||||
@@ -257,7 +280,9 @@ impl<P, B> Recv<P, B>
|
||||
}
|
||||
|
||||
/// Returns true if the remote peer can reserve a stream with the given ID.
|
||||
fn ensure_can_reserve(&self, promised_id: StreamId) -> Result<(), ConnectionError> {
|
||||
fn ensure_can_reserve<P: Peer>(&self, promised_id: StreamId)
|
||||
-> Result<(), ConnectionError>
|
||||
{
|
||||
// TODO: Are there other rules?
|
||||
if P::is_server() {
|
||||
// The remote is a client and cannot reserve
|
||||
@@ -400,27 +425,3 @@ impl<P, B> Recv<P, B>
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl<B> Recv<client::Peer, B>
|
||||
where B: Buf,
|
||||
{
|
||||
pub fn poll_response(&mut self, stream: &mut store::Ptr<B>)
|
||||
-> Poll<Response<()>, ConnectionError> {
|
||||
// If the buffer is not empty, then the first frame must be a HEADERS
|
||||
// frame or the user violated the contract.
|
||||
match stream.pending_recv.pop_front(&mut self.buffer) {
|
||||
Some(Frame::Headers(v)) => {
|
||||
// TODO: This error should probably be caught on receipt of the
|
||||
// frame vs. now.
|
||||
Ok(client::Peer::convert_poll_message(v)?.into())
|
||||
}
|
||||
Some(frame) => unimplemented!(),
|
||||
None => {
|
||||
stream.state.ensure_recv_open()?;
|
||||
|
||||
stream.recv_task = Some(task::current());
|
||||
Ok(Async::NotReady)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use std::collections::VecDeque;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct Send<P, B> {
|
||||
pub(super) struct Send<B> {
|
||||
/// Maximum number of locally initiated streams
|
||||
max_streams: Option<usize>,
|
||||
|
||||
@@ -36,15 +36,12 @@ pub(super) struct Send<P, B> {
|
||||
/// be notified later. Access to poll_window_update must not be shared across tasks,
|
||||
/// as we only track a single task (and *not* i.e. a task per stream id).
|
||||
blocked: Option<task::Task>,
|
||||
|
||||
_p: PhantomData<P>,
|
||||
}
|
||||
|
||||
impl<P, B> Send<P, B>
|
||||
where P: Peer,
|
||||
B: Buf,
|
||||
{
|
||||
pub fn new(config: &Config) -> Self {
|
||||
impl<B> Send<B> where B: Buf {
|
||||
|
||||
/// Create a new `Send`
|
||||
pub fn new<P: Peer>(config: &Config) -> Self {
|
||||
let next_stream_id = if P::is_server() {
|
||||
2
|
||||
} else {
|
||||
@@ -60,15 +57,16 @@ impl<P, B> Send<P, B>
|
||||
prioritize: Prioritize::new(),
|
||||
pending_window_updates: VecDeque::new(),
|
||||
blocked: None,
|
||||
_p: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Update state reflecting a new, locally opened stream
|
||||
///
|
||||
/// Returns the stream state if successful. `None` if refused
|
||||
pub fn open(&mut self) -> Result<Stream<B>, ConnectionError> {
|
||||
try!(self.ensure_can_open());
|
||||
pub fn open<P: Peer>(&mut self)
|
||||
-> Result<Stream<B>, ConnectionError>
|
||||
{
|
||||
try!(self.ensure_can_open::<P>());
|
||||
|
||||
if let Some(max) = self.max_streams {
|
||||
if max <= self.num_streams {
|
||||
@@ -229,7 +227,7 @@ impl<P, B> Send<P, B>
|
||||
}
|
||||
|
||||
/// Returns true if the local actor can initiate a stream with the given ID.
|
||||
fn ensure_can_open(&self) -> Result<(), ConnectionError> {
|
||||
fn ensure_can_open<P: Peer>(&self) -> Result<(), ConnectionError> {
|
||||
if P::is_server() {
|
||||
// Servers cannot open streams. PushPromise must first be reserved.
|
||||
return Err(UnexpectedFrameType.into());
|
||||
|
||||
@@ -2,28 +2,28 @@ use client;
|
||||
use proto::*;
|
||||
use super::*;
|
||||
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
// TODO: All the VecDeques should become linked lists using the State
|
||||
// values.
|
||||
#[derive(Debug)]
|
||||
pub struct Streams<P, B> {
|
||||
inner: Arc<Mutex<Inner<P, B>>>,
|
||||
pub struct Streams<B> {
|
||||
inner: Arc<Mutex<Inner<B>>>,
|
||||
}
|
||||
|
||||
/// Reference to the stream state
|
||||
#[derive(Debug)]
|
||||
pub struct StreamRef<P, B> {
|
||||
inner: Arc<Mutex<Inner<P, B>>>,
|
||||
pub struct StreamRef<B> {
|
||||
inner: Arc<Mutex<Inner<B>>>,
|
||||
key: store::Key,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Chunk<P, B>
|
||||
where P: Peer,
|
||||
B: Buf,
|
||||
pub struct Chunk<B>
|
||||
where B: Buf,
|
||||
{
|
||||
inner: Arc<Mutex<Inner<P, B>>>,
|
||||
inner: Arc<Mutex<Inner<B>>>,
|
||||
recv: recv::Chunk,
|
||||
}
|
||||
|
||||
@@ -32,30 +32,29 @@ pub struct Chunk<P, B>
|
||||
///
|
||||
/// TODO: better name
|
||||
#[derive(Debug)]
|
||||
struct Inner<P, B> {
|
||||
actions: Actions<P, B>,
|
||||
struct Inner<B> {
|
||||
actions: Actions<B>,
|
||||
store: Store<B>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Actions<P, B> {
|
||||
struct Actions<B> {
|
||||
/// Manages state transitions initiated by receiving frames
|
||||
recv: Recv<P, B>,
|
||||
recv: Recv<B>,
|
||||
|
||||
/// Manages state transitions initiated by sending frames
|
||||
send: Send<P, B>,
|
||||
send: Send<B>,
|
||||
}
|
||||
|
||||
impl<P, B> Streams<P, B>
|
||||
where P: Peer,
|
||||
B: Buf,
|
||||
impl<B> Streams<B>
|
||||
where B: Buf,
|
||||
{
|
||||
pub fn new(config: Config) -> Self {
|
||||
pub fn new<P: Peer>(config: Config) -> Self {
|
||||
Streams {
|
||||
inner: Arc::new(Mutex::new(Inner {
|
||||
actions: Actions {
|
||||
recv: Recv::new(&config),
|
||||
send: Send::new(&config),
|
||||
send: Send::new::<P>(&config),
|
||||
},
|
||||
store: Store::new(),
|
||||
})),
|
||||
@@ -63,7 +62,7 @@ impl<P, B> Streams<P, B>
|
||||
}
|
||||
|
||||
/// Process inbound headers
|
||||
pub fn recv_headers(&mut self, frame: frame::Headers)
|
||||
pub fn recv_headers<P: Peer>(&mut self, frame: frame::Headers)
|
||||
-> Result<Option<frame::Headers>, ConnectionError>
|
||||
{
|
||||
let id = frame.stream_id();
|
||||
@@ -81,7 +80,7 @@ impl<P, B> Streams<P, B>
|
||||
return Err(ProtocolError.into());
|
||||
}
|
||||
|
||||
match try!(me.actions.recv.open(id)) {
|
||||
match try!(me.actions.recv.open::<P>(id)) {
|
||||
Some(stream) => e.insert(stream),
|
||||
None => return Ok(None),
|
||||
}
|
||||
@@ -90,7 +89,7 @@ impl<P, B> Streams<P, B>
|
||||
|
||||
let stream = me.store.resolve(key);
|
||||
|
||||
me.actions.transition(stream, |actions, stream| {
|
||||
me.actions.transition::<P, _, _>(stream, |actions, stream| {
|
||||
if frame.is_trailers() {
|
||||
unimplemented!();
|
||||
/*
|
||||
@@ -102,12 +101,12 @@ impl<P, B> Streams<P, B>
|
||||
try!(me.actions.recv.recv_eos(stream));
|
||||
*/
|
||||
} else {
|
||||
actions.recv.recv_headers(frame, stream)
|
||||
actions.recv.recv_headers::<P>(frame, stream)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn recv_data(&mut self, frame: frame::Data)
|
||||
pub fn recv_data<P: Peer>(&mut self, frame: frame::Data)
|
||||
-> Result<(), ConnectionError>
|
||||
{
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
@@ -120,12 +119,12 @@ impl<P, B> Streams<P, B>
|
||||
None => return Err(ProtocolError.into()),
|
||||
};
|
||||
|
||||
me.actions.transition(stream, |actions, stream| {
|
||||
me.actions.transition::<P, _, _>(stream, |actions, stream| {
|
||||
actions.recv.recv_data(frame, stream)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn recv_reset(&mut self, frame: frame::Reset)
|
||||
pub fn recv_reset<P: Peer>(&mut self, frame: frame::Reset)
|
||||
-> Result<(), ConnectionError>
|
||||
{
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
@@ -139,7 +138,7 @@ impl<P, B> Streams<P, B>
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
me.actions.transition(stream, |actions, stream| {
|
||||
me.actions.transition::<P, _, _>(stream, |actions, stream| {
|
||||
actions.recv.recv_reset(frame, stream)?;
|
||||
assert!(stream.state.is_closed());
|
||||
Ok(())
|
||||
@@ -173,7 +172,7 @@ impl<P, B> Streams<P, B>
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn recv_push_promise(&mut self, frame: frame::PushPromise)
|
||||
pub fn recv_push_promise<P: Peer>(&mut self, frame: frame::PushPromise)
|
||||
-> Result<(), ConnectionError>
|
||||
{
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
@@ -186,7 +185,7 @@ impl<P, B> Streams<P, B>
|
||||
None => return Err(ProtocolError.into()),
|
||||
};
|
||||
|
||||
me.actions.recv.recv_push_promise(frame, &mut stream)
|
||||
me.actions.recv.recv_push_promise::<P>(frame, &mut stream)
|
||||
}
|
||||
|
||||
pub fn send_headers(&mut self, headers: frame::Headers)
|
||||
@@ -274,11 +273,11 @@ impl<P, B> Streams<P, B>
|
||||
}
|
||||
}
|
||||
|
||||
impl<B> Streams<client::Peer, B>
|
||||
impl<B> Streams<B>
|
||||
where B: Buf,
|
||||
{
|
||||
pub fn send_request(&mut self, request: Request<()>, end_of_stream: bool)
|
||||
-> Result<StreamRef<client::Peer, B>, ConnectionError>
|
||||
-> Result<StreamRef<B>, ConnectionError>
|
||||
{
|
||||
// TODO: There is a hazard with assigning a stream ID before the
|
||||
// prioritize layer. If prioritization reorders new streams, this
|
||||
@@ -290,7 +289,7 @@ impl<B> Streams<client::Peer, B>
|
||||
let me = &mut *me;
|
||||
|
||||
// Initialize a new stream. This fails if the connection is at capacity.
|
||||
let mut stream = me.actions.send.open()?;
|
||||
let mut stream = me.actions.send.open::<client::Peer>()?;
|
||||
|
||||
// Convert the message
|
||||
let headers = client::Peer::convert_send_message(
|
||||
@@ -316,11 +315,10 @@ impl<B> Streams<client::Peer, B>
|
||||
|
||||
// ===== impl StreamRef =====
|
||||
|
||||
impl<P, B> StreamRef<P, B>
|
||||
where P: Peer,
|
||||
B: Buf,
|
||||
impl<B> StreamRef<B>
|
||||
where B: Buf,
|
||||
{
|
||||
pub fn send_data(&mut self, data: B, end_of_stream: bool)
|
||||
pub fn send_data<P: Peer>(&mut self, data: B, end_of_stream: bool)
|
||||
-> Result<(), ConnectionError>
|
||||
{
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
@@ -331,13 +329,22 @@ impl<P, B> StreamRef<P, B>
|
||||
// Create the data frame
|
||||
let frame = frame::Data::from_buf(stream.id, data, end_of_stream);
|
||||
|
||||
me.actions.transition(stream, |actions, stream| {
|
||||
me.actions.transition::<P, _, _>(stream, |actions, stream| {
|
||||
// Send the data frame
|
||||
actions.send.send_data(frame, stream)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn poll_data(&mut self) -> Poll<Option<Chunk<P, B>>, ConnectionError> {
|
||||
pub fn poll_response(&mut self) -> Poll<Response<()>, ConnectionError> {
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
|
||||
let mut stream = me.store.resolve(self.key);
|
||||
|
||||
me.actions.recv.poll_response(&mut stream)
|
||||
}
|
||||
|
||||
pub fn poll_data(&mut self) -> Poll<Option<Chunk<B>>, ConnectionError> {
|
||||
let recv = {
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
@@ -359,22 +366,7 @@ impl<P, B> StreamRef<P, B>
|
||||
}
|
||||
}
|
||||
|
||||
impl<B> StreamRef<client::Peer, B>
|
||||
where B: Buf,
|
||||
{
|
||||
pub fn poll_response(&mut self) -> Poll<Response<()>, ConnectionError> {
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
|
||||
let mut stream = me.store.resolve(self.key);
|
||||
|
||||
me.actions.recv.poll_response(&mut stream)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl<P, B> Clone for StreamRef<P, B> {
|
||||
impl<B> Clone for StreamRef<B> {
|
||||
fn clone(&self) -> Self {
|
||||
StreamRef {
|
||||
inner: self.inner.clone(),
|
||||
@@ -385,9 +377,8 @@ impl<P, B> Clone for StreamRef<P, B> {
|
||||
|
||||
// ===== impl Chunk =====
|
||||
|
||||
impl<P, B> Chunk<P, B>
|
||||
where P: Peer,
|
||||
B: Buf,
|
||||
impl<B> Chunk<B>
|
||||
where B: Buf,
|
||||
{
|
||||
// TODO: Come up w/ a better API
|
||||
pub fn pop_bytes(&mut self) -> Option<Bytes> {
|
||||
@@ -398,9 +389,8 @@ impl<P, B> Chunk<P, B>
|
||||
}
|
||||
}
|
||||
|
||||
impl<P, B> Drop for Chunk<P, B>
|
||||
where P: Peer,
|
||||
B: Buf,
|
||||
impl<B> Drop for Chunk<B>
|
||||
where B: Buf,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
@@ -413,32 +403,32 @@ impl<P, B> Drop for Chunk<P, B>
|
||||
|
||||
// ===== impl Actions =====
|
||||
|
||||
impl<P, B> Actions<P, B>
|
||||
where P: Peer,
|
||||
B: Buf,
|
||||
impl<B> Actions<B>
|
||||
where B: Buf,
|
||||
{
|
||||
fn dec_num_streams(&mut self, id: StreamId) {
|
||||
if self.is_local_init(id) {
|
||||
fn dec_num_streams<P: Peer>(&mut self, id: StreamId) {
|
||||
if self.is_local_init::<P>(id) {
|
||||
self.send.dec_num_streams();
|
||||
} else {
|
||||
self.recv.dec_num_streams();
|
||||
}
|
||||
}
|
||||
|
||||
fn is_local_init(&self, id: StreamId) -> bool {
|
||||
fn is_local_init<P: Peer>(&self, id: StreamId) -> bool {
|
||||
assert!(!id.is_zero());
|
||||
P::is_server() == id.is_server_initiated()
|
||||
}
|
||||
|
||||
fn transition<F, U>(&mut self, mut stream: store::Ptr<B>, f: F) -> U
|
||||
fn transition<P, F, U>(&mut self, mut stream: store::Ptr<B>, f: F) -> U
|
||||
where F: FnOnce(&mut Self, &mut store::Ptr<B>) -> U,
|
||||
P: Peer,
|
||||
{
|
||||
let is_counted = stream.state.is_counted();
|
||||
|
||||
let ret = f(self, &mut stream);
|
||||
|
||||
if is_counted && stream.state.is_closed() {
|
||||
self.dec_num_streams(stream.id);
|
||||
self.dec_num_streams::<P>(stream.id);
|
||||
}
|
||||
|
||||
ret
|
||||
|
||||
Reference in New Issue
Block a user