Skip to content

Commit c41b5d8

Browse files
committed
Replace calls to Pin::new_unchecked with pin_project.
This is a breaking change, as it changes some public methods to take `Pin<&mut Self>` rather than `&mut self`. This brings these methods into line with `Stream::poll_next`, which also takes a `Pin<&mut Self>`
1 parent 693d513 commit c41b5d8

File tree

7 files changed

+116
-104
lines changed

7 files changed

+116
-104
lines changed

actix-codec/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ futures-core = "0.3.1"
2323
futures-sink = "0.3.1"
2424
tokio = { version = "0.2.4", default-features=false }
2525
tokio-util = { version = "0.2.0", default-features=false, features=["codec"] }
26-
log = "0.4"
26+
log = "0.4"
27+
pin-project = "0.4.8"

actix-codec/src/framed.rs

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::{fmt, io};
55
use bytes::{Buf, BytesMut};
66
use futures_core::{ready, Stream};
77
use futures_sink::Sink;
8+
use pin_project::pin_project;
89

910
use crate::{AsyncRead, AsyncWrite, Decoder, Encoder};
1011

@@ -20,16 +21,16 @@ bitflags::bitflags! {
2021

2122
/// A unified `Stream` and `Sink` interface to an underlying I/O object, using
2223
/// the `Encoder` and `Decoder` traits to encode and decode frames.
24+
#[pin_project]
2325
pub struct Framed<T, U> {
26+
#[pin]
2427
io: T,
2528
codec: U,
2629
flags: Flags,
2730
read_buf: BytesMut,
2831
write_buf: BytesMut,
2932
}
3033

31-
impl<T, U> Unpin for Framed<T, U> {}
32-
3334
impl<T, U> Framed<T, U>
3435
where
3536
T: AsyncRead + AsyncWrite,
@@ -185,17 +186,18 @@ impl<T, U> Framed<T, U> {
185186

186187
impl<T, U> Framed<T, U> {
187188
/// Serialize item and Write to the inner buffer
188-
pub fn write(&mut self, item: <U as Encoder>::Item) -> Result<(), <U as Encoder>::Error>
189+
pub fn write(mut self: Pin<&mut Self>, item: <U as Encoder>::Item) -> Result<(), <U as Encoder>::Error>
189190
where
190191
T: AsyncWrite,
191192
U: Encoder,
192193
{
193-
let remaining = self.write_buf.capacity() - self.write_buf.len();
194+
let this = self.as_mut().project();
195+
let remaining = this.write_buf.capacity() - this.write_buf.len();
194196
if remaining < LW {
195-
self.write_buf.reserve(HW - remaining);
197+
this.write_buf.reserve(HW - remaining);
196198
}
197199

198-
self.codec.encode(item, &mut self.write_buf)?;
200+
this.codec.encode(item, this.write_buf)?;
199201
Ok(())
200202
}
201203

@@ -207,21 +209,22 @@ impl<T, U> Framed<T, U> {
207209
}
208210

209211
/// Try to read underlying I/O stream and decode item.
210-
pub fn next_item(&mut self, cx: &mut Context<'_>) -> Poll<Option<Result<U::Item, U::Error>>>
212+
pub fn next_item(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<U::Item, U::Error>>>
211213
where
212214
T: AsyncRead,
213215
U: Decoder,
214216
{
215217
loop {
218+
let mut this = self.as_mut().project();
216219
// Repeatedly call `decode` or `decode_eof` as long as it is
217220
// "readable". Readable is defined as not having returned `None`. If
218221
// the upstream has returned EOF, and the decoder is no longer
219222
// readable, it can be assumed that the decoder will never become
220223
// readable again, at which point the stream is terminated.
221224

222-
if self.flags.contains(Flags::READABLE) {
223-
if self.flags.contains(Flags::EOF) {
224-
match self.codec.decode_eof(&mut self.read_buf) {
225+
if this.flags.contains(Flags::READABLE) {
226+
if this.flags.contains(Flags::EOF) {
227+
match this.codec.decode_eof(&mut this.read_buf) {
225228
Ok(Some(frame)) => return Poll::Ready(Some(Ok(frame))),
226229
Ok(None) => return Poll::Ready(None),
227230
Err(e) => return Poll::Ready(Some(Err(e))),
@@ -230,7 +233,7 @@ impl<T, U> Framed<T, U> {
230233

231234
log::trace!("attempting to decode a frame");
232235

233-
match self.codec.decode(&mut self.read_buf) {
236+
match this.codec.decode(&mut this.read_buf) {
234237
Ok(Some(frame)) => {
235238
log::trace!("frame decoded from buffer");
236239
return Poll::Ready(Some(Ok(frame)));
@@ -239,45 +242,44 @@ impl<T, U> Framed<T, U> {
239242
_ => (), // Need more data
240243
}
241244

242-
self.flags.remove(Flags::READABLE);
245+
this.flags.remove(Flags::READABLE);
243246
}
244247

245-
debug_assert!(!self.flags.contains(Flags::EOF));
248+
debug_assert!(!this.flags.contains(Flags::EOF));
246249

247250
// Otherwise, try to read more data and try again. Make sure we've got room
248-
let remaining = self.read_buf.capacity() - self.read_buf.len();
251+
let remaining = this.read_buf.capacity() - this.read_buf.len();
249252
if remaining < LW {
250-
self.read_buf.reserve(HW - remaining)
253+
this.read_buf.reserve(HW - remaining)
251254
}
252-
let cnt = match unsafe {
253-
Pin::new_unchecked(&mut self.io).poll_read_buf(cx, &mut self.read_buf)
254-
} {
255+
let cnt = match this.io.poll_read_buf(cx, &mut this.read_buf) {
255256
Poll::Pending => return Poll::Pending,
256257
Poll::Ready(Err(e)) => return Poll::Ready(Some(Err(e.into()))),
257258
Poll::Ready(Ok(cnt)) => cnt,
258259
};
259260

260261
if cnt == 0 {
261-
self.flags.insert(Flags::EOF);
262+
this.flags.insert(Flags::EOF);
262263
}
263-
self.flags.insert(Flags::READABLE);
264+
this.flags.insert(Flags::READABLE);
264265
}
265266
}
266267

267268
/// Flush write buffer to underlying I/O stream.
268-
pub fn flush(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), U::Error>>
269+
pub fn flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), U::Error>>
269270
where
270271
T: AsyncWrite,
271272
U: Encoder,
272273
{
274+
let mut this = self.as_mut().project();
273275
log::trace!("flushing framed transport");
274276

275-
while !self.write_buf.is_empty() {
276-
log::trace!("writing; remaining={}", self.write_buf.len());
277+
while !this.write_buf.is_empty() {
278+
log::trace!("writing; remaining={}", this.write_buf.len());
277279

278-
let n = ready!(unsafe {
279-
Pin::new_unchecked(&mut self.io).poll_write(cx, &self.write_buf)
280-
})?;
280+
let n = ready!(
281+
this.io.as_mut().poll_write(cx, this.write_buf)
282+
)?;
281283

282284
if n == 0 {
283285
return Poll::Ready(Err(io::Error::new(
@@ -288,26 +290,25 @@ impl<T, U> Framed<T, U> {
288290
}
289291

290292
// remove written data
291-
self.write_buf.advance(n);
293+
this.write_buf.advance(n);
292294
}
293295

294296
// Try flushing the underlying IO
295-
ready!(unsafe { Pin::new_unchecked(&mut self.io).poll_flush(cx) })?;
297+
ready!(this.io.poll_flush(cx))?;
296298

297299
log::trace!("framed transport flushed");
298300
Poll::Ready(Ok(()))
299301
}
300302

301303
/// Flush write buffer and shutdown underlying I/O stream.
302-
pub fn close(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), U::Error>>
304+
pub fn close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), U::Error>>
303305
where
304306
T: AsyncWrite,
305307
U: Encoder,
306308
{
307-
unsafe {
308-
ready!(Pin::new_unchecked(&mut self.io).poll_flush(cx))?;
309-
ready!(Pin::new_unchecked(&mut self.io).poll_shutdown(cx))?;
310-
}
309+
let mut this = self.as_mut().project();
310+
ready!(this.io.as_mut().poll_flush(cx))?;
311+
ready!(this.io.as_mut().poll_shutdown(cx))?;
311312
Poll::Ready(Ok(()))
312313
}
313314
}
@@ -319,7 +320,7 @@ where
319320
{
320321
type Item = Result<U::Item, U::Error>;
321322

322-
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
323+
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
323324
self.next_item(cx)
324325
}
325326
}
@@ -341,21 +342,21 @@ where
341342
}
342343

343344
fn start_send(
344-
mut self: Pin<&mut Self>,
345+
self: Pin<&mut Self>,
345346
item: <U as Encoder>::Item,
346347
) -> Result<(), Self::Error> {
347348
self.write(item)
348349
}
349350

350351
fn poll_flush(
351-
mut self: Pin<&mut Self>,
352+
self: Pin<&mut Self>,
352353
cx: &mut Context<'_>,
353354
) -> Poll<Result<(), Self::Error>> {
354355
self.flush(cx)
355356
}
356357

357358
fn poll_close(
358-
mut self: Pin<&mut Self>,
359+
self: Pin<&mut Self>,
359360
cx: &mut Context<'_>,
360361
) -> Poll<Result<(), Self::Error>> {
361362
self.close(cx)

actix-ioframe/src/connect.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ where
4242
pub struct ConnectResult<Io, St, Codec: Encoder + Decoder, Out> {
4343
pub(crate) state: St,
4444
pub(crate) out: Option<Out>,
45+
#[pin]
4546
pub(crate) framed: Framed<Io, Codec>,
4647
}
4748

@@ -97,8 +98,8 @@ where
9798
{
9899
type Error = <Codec as Encoder>::Error;
99100

100-
fn poll_ready(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
101-
if self.framed.is_write_ready() {
101+
fn poll_ready(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
102+
if self.as_mut().project().framed.is_write_ready() {
102103
Poll::Ready(Ok(()))
103104
} else {
104105
Poll::Pending
@@ -112,11 +113,11 @@ where
112113
self.project().framed.write(item)
113114
}
114115

115-
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
116-
self.get_mut().framed.flush(cx)
116+
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
117+
self.as_mut().project().framed.flush(cx)
117118
}
118119

119-
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
120-
self.get_mut().framed.close(cx)
120+
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
121+
self.as_mut().project().framed.close(cx)
121122
}
122123
}

0 commit comments

Comments
 (0)