mirror of
https://github.com/actix/actix-web.git
synced 2024-11-25 19:11:10 +00:00
refactor(multipart): move Safety to module
This commit is contained in:
parent
e189e4a3bf
commit
2136e07bdd
3 changed files with 63 additions and 61 deletions
|
@ -60,6 +60,7 @@ extern crate self as actix_multipart;
|
||||||
mod error;
|
mod error;
|
||||||
mod extractor;
|
mod extractor;
|
||||||
pub mod form;
|
pub mod form;
|
||||||
|
pub(crate) mod safety;
|
||||||
mod server;
|
mod server;
|
||||||
pub mod test;
|
pub mod test;
|
||||||
|
|
||||||
|
|
60
actix-multipart/src/safety.rs
Normal file
60
actix-multipart/src/safety.rs
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
use std::{cell::Cell, marker::PhantomData, rc::Rc, task};
|
||||||
|
|
||||||
|
use local_waker::LocalWaker;
|
||||||
|
|
||||||
|
/// Counter. It tracks of number of clones of payloads and give access to payload only to top most.
|
||||||
|
///
|
||||||
|
/// - When dropped, parent task is awakened. This is to support the case where `Field` is dropped in
|
||||||
|
/// a separate task than `Multipart`.
|
||||||
|
/// - Assumes that parent owners don't move to different tasks; only the top-most is allowed to.
|
||||||
|
/// - If dropped and is not top most owner, is_clean flag is set to false.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct Safety {
|
||||||
|
task: LocalWaker,
|
||||||
|
level: usize,
|
||||||
|
payload: Rc<PhantomData<bool>>,
|
||||||
|
clean: Rc<Cell<bool>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Safety {
|
||||||
|
pub(crate) fn new() -> Safety {
|
||||||
|
let payload = Rc::new(PhantomData);
|
||||||
|
Safety {
|
||||||
|
task: LocalWaker::new(),
|
||||||
|
level: Rc::strong_count(&payload),
|
||||||
|
clean: Rc::new(Cell::new(true)),
|
||||||
|
payload,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn current(&self) -> bool {
|
||||||
|
Rc::strong_count(&self.payload) == self.level && self.clean.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn is_clean(&self) -> bool {
|
||||||
|
self.clean.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn clone(&self, cx: &task::Context<'_>) -> Safety {
|
||||||
|
let payload = Rc::clone(&self.payload);
|
||||||
|
let s = Safety {
|
||||||
|
task: LocalWaker::new(),
|
||||||
|
level: Rc::strong_count(&payload),
|
||||||
|
clean: self.clean.clone(),
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
s.task.register(cx.waker());
|
||||||
|
s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Safety {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if Rc::strong_count(&self.payload) != self.level {
|
||||||
|
// Multipart dropped leaving a Field
|
||||||
|
self.clean.set(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.task.wake();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,8 @@
|
||||||
//! Multipart response payload support.
|
//! Multipart response payload support.
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
cell::{Cell, RefCell, RefMut},
|
cell::{RefCell, RefMut},
|
||||||
cmp, fmt,
|
cmp, fmt,
|
||||||
marker::PhantomData,
|
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
|
@ -17,10 +16,9 @@ use actix_web::{
|
||||||
};
|
};
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
use futures_core::stream::{LocalBoxStream, Stream};
|
use futures_core::stream::{LocalBoxStream, Stream};
|
||||||
use local_waker::LocalWaker;
|
|
||||||
use mime::Mime;
|
use mime::Mime;
|
||||||
|
|
||||||
use crate::error::MultipartError;
|
use crate::{error::MultipartError, safety::Safety};
|
||||||
|
|
||||||
const MAX_HEADERS: usize = 32;
|
const MAX_HEADERS: usize = 32;
|
||||||
|
|
||||||
|
@ -797,63 +795,6 @@ impl Clone for PayloadRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Counter. It tracks of number of clones of payloads and give access to payload only to top most.
|
|
||||||
///
|
|
||||||
/// - When dropped, parent task is awakened. This is to support the case where `Field` is dropped in
|
|
||||||
/// a separate task than `Multipart`.
|
|
||||||
/// - Assumes that parent owners don't move to different tasks; only the top-most is allowed to.
|
|
||||||
/// - If dropped and is not top most owner, is_clean flag is set to false.
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct Safety {
|
|
||||||
task: LocalWaker,
|
|
||||||
level: usize,
|
|
||||||
payload: Rc<PhantomData<bool>>,
|
|
||||||
clean: Rc<Cell<bool>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Safety {
|
|
||||||
fn new() -> Safety {
|
|
||||||
let payload = Rc::new(PhantomData);
|
|
||||||
Safety {
|
|
||||||
task: LocalWaker::new(),
|
|
||||||
level: Rc::strong_count(&payload),
|
|
||||||
clean: Rc::new(Cell::new(true)),
|
|
||||||
payload,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current(&self) -> bool {
|
|
||||||
Rc::strong_count(&self.payload) == self.level && self.clean.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_clean(&self) -> bool {
|
|
||||||
self.clean.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clone(&self, cx: &Context<'_>) -> Safety {
|
|
||||||
let payload = Rc::clone(&self.payload);
|
|
||||||
let s = Safety {
|
|
||||||
task: LocalWaker::new(),
|
|
||||||
level: Rc::strong_count(&payload),
|
|
||||||
clean: self.clean.clone(),
|
|
||||||
payload,
|
|
||||||
};
|
|
||||||
s.task.register(cx.waker());
|
|
||||||
s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Safety {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if Rc::strong_count(&self.payload) != self.level {
|
|
||||||
// Multipart dropped leaving a Field
|
|
||||||
self.clean.set(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.task.wake();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Payload buffer.
|
/// Payload buffer.
|
||||||
struct PayloadBuffer {
|
struct PayloadBuffer {
|
||||||
eof: bool,
|
eof: bool,
|
||||||
|
|
Loading…
Reference in a new issue