Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Make HtmlRewriter Send + Sync. #217

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions src/base/encoding.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::rewriter::AsciiCompatibleEncoding;
use encoding_rs::Encoding;
use std::cell::Cell;
use std::ops::Deref;
use std::rc::Rc;
use std::sync::{Arc, Mutex};

/// A charset encoding that can be shared and modified.
///
Expand All @@ -11,22 +10,22 @@ use std::rc::Rc;
/// [crate::Settings::adjust_charset_on_meta_tag]).
#[derive(Clone)]
pub struct SharedEncoding {
encoding: Rc<Cell<AsciiCompatibleEncoding>>,
encoding: Arc<Mutex<AsciiCompatibleEncoding>>,
}

impl SharedEncoding {
pub fn new(encoding: AsciiCompatibleEncoding) -> SharedEncoding {
SharedEncoding {
encoding: Rc::new(Cell::new(encoding)),
encoding: Arc::new(Mutex::new(encoding)),
}
}

pub fn get(&self) -> &'static Encoding {
self.encoding.get().into()
(*self.encoding.lock().unwrap().deref()).into()
}

pub fn set(&self, encoding: AsciiCompatibleEncoding) {
self.encoding.set(encoding);
*self.encoding.lock().unwrap() = encoding;
}
}

Expand Down
34 changes: 17 additions & 17 deletions src/memory/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub struct Arena {

impl Arena {
pub fn new(limiter: SharedMemoryLimiter, preallocated_size: usize) -> Self {
limiter.borrow_mut().preallocate(preallocated_size);
limiter.lock().unwrap().preallocate(preallocated_size);

Arena {
limiter,
Expand All @@ -27,7 +27,7 @@ impl Arena {

// NOTE: approximate usage, as `Vec::reserve_exact` doesn't
// give guarantees about exact capacity value :).
self.limiter.borrow_mut().increase_usage(additional)?;
self.limiter.lock().unwrap().increase_usage(additional)?;

// NOTE: with wicely choosen preallocated size this branch should be
// executed quite rarely. We can't afford to use double capacity
Expand Down Expand Up @@ -60,24 +60,24 @@ impl Arena {
mod tests {
use super::super::limiter::MemoryLimiter;
use super::*;
use std::rc::Rc;
use std::sync::Arc;

#[test]
fn append() {
let limiter = MemoryLimiter::new_shared(10);
let mut arena = Arena::new(Rc::clone(&limiter), 2);
let mut arena = Arena::new(Arc::clone(&limiter), 2);

arena.append(&[1, 2]).unwrap();
assert_eq!(arena.bytes(), &[1, 2]);
assert_eq!(limiter.borrow().current_usage(), 2);
assert_eq!(limiter.lock().unwrap().current_usage(), 2);

arena.append(&[3, 4]).unwrap();
assert_eq!(arena.bytes(), &[1, 2, 3, 4]);
assert_eq!(limiter.borrow().current_usage(), 4);
assert_eq!(limiter.lock().unwrap().current_usage(), 4);

arena.append(&[5, 6, 7, 8, 9, 10]).unwrap();
assert_eq!(arena.bytes(), &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
assert_eq!(limiter.borrow().current_usage(), 10);
assert_eq!(limiter.lock().unwrap().current_usage(), 10);

let err = arena.append(&[11]).unwrap_err();

Expand All @@ -87,23 +87,23 @@ mod tests {
#[test]
fn init_with() {
let limiter = MemoryLimiter::new_shared(5);
let mut arena = Arena::new(Rc::clone(&limiter), 0);
let mut arena = Arena::new(Arc::clone(&limiter), 0);

arena.init_with(&[1]).unwrap();
assert_eq!(arena.bytes(), &[1]);
assert_eq!(limiter.borrow().current_usage(), 1);
assert_eq!(limiter.lock().unwrap().current_usage(), 1);

arena.append(&[1, 2]).unwrap();
assert_eq!(arena.bytes(), &[1, 1, 2]);
assert_eq!(limiter.borrow().current_usage(), 3);
assert_eq!(limiter.lock().unwrap().current_usage(), 3);

arena.init_with(&[1, 2, 3]).unwrap();
assert_eq!(arena.bytes(), &[1, 2, 3]);
assert_eq!(limiter.borrow().current_usage(), 3);
assert_eq!(limiter.lock().unwrap().current_usage(), 3);

arena.init_with(&[]).unwrap();
assert_eq!(arena.bytes(), &[]);
assert_eq!(limiter.borrow().current_usage(), 3);
assert_eq!(limiter.lock().unwrap().current_usage(), 3);

let err = arena.init_with(&[1, 2, 3, 4, 5, 6, 7]).unwrap_err();

Expand All @@ -113,24 +113,24 @@ mod tests {
#[test]
fn shift() {
let limiter = MemoryLimiter::new_shared(10);
let mut arena = Arena::new(Rc::clone(&limiter), 0);
let mut arena = Arena::new(Arc::clone(&limiter), 0);

arena.append(&[0, 1, 2, 3]).unwrap();
arena.shift(2);
assert_eq!(arena.bytes(), &[2, 3]);
assert_eq!(limiter.borrow().current_usage(), 4);
assert_eq!(limiter.lock().unwrap().current_usage(), 4);

arena.append(&[0, 1]).unwrap();
assert_eq!(arena.bytes(), &[2, 3, 0, 1]);
assert_eq!(limiter.borrow().current_usage(), 4);
assert_eq!(limiter.lock().unwrap().current_usage(), 4);

arena.shift(3);
assert_eq!(arena.bytes(), &[1]);
assert_eq!(limiter.borrow().current_usage(), 4);
assert_eq!(limiter.lock().unwrap().current_usage(), 4);

arena.append(&[2, 3, 4, 5]).unwrap();
arena.shift(1);
assert_eq!(arena.bytes(), &[2, 3, 4, 5]);
assert_eq!(limiter.borrow().current_usage(), 5);
assert_eq!(limiter.lock().unwrap().current_usage(), 5);
}
}
39 changes: 22 additions & 17 deletions src/memory/limited_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ impl<T> LimitedVec<T> {
}

pub fn push(&mut self, element: T) -> Result<(), MemoryLimitExceededError> {
self.limiter.borrow_mut().increase_usage(size_of::<T>())?;
self.limiter
.lock()
.unwrap()
.increase_usage(size_of::<T>())?;
self.vec.push(element);
Ok(())
}
Expand Down Expand Up @@ -65,7 +68,8 @@ impl<T> LimitedVec<T> {
};

self.limiter
.borrow_mut()
.lock()
.unwrap()
.decrease_usage(size_of::<T>() * (end - start));

self.vec.drain(range)
Expand All @@ -92,7 +96,8 @@ impl<T> Index<usize> for LimitedVec<T> {
impl<T> Drop for LimitedVec<T> {
fn drop(&mut self) {
self.limiter
.borrow_mut()
.lock()
.unwrap()
.decrease_usage(size_of::<T>() * self.vec.len());
}
}
Expand All @@ -101,33 +106,33 @@ impl<T> Drop for LimitedVec<T> {
mod tests {
use super::super::MemoryLimiter;
use super::*;
use std::rc::Rc;
use std::sync::Arc;

#[test]
fn current_usage() {
{
let limiter = MemoryLimiter::new_shared(10);
let mut vec_u8: LimitedVec<u8> = LimitedVec::new(Rc::clone(&limiter));
let mut vec_u8: LimitedVec<u8> = LimitedVec::new(Arc::clone(&limiter));

vec_u8.push(1).unwrap();
vec_u8.push(2).unwrap();
assert_eq!(limiter.borrow().current_usage(), 2);
assert_eq!(limiter.lock().unwrap().current_usage(), 2);
}

{
let limiter = MemoryLimiter::new_shared(10);
let mut vec_u32: LimitedVec<u32> = LimitedVec::new(Rc::clone(&limiter));
let mut vec_u32: LimitedVec<u32> = LimitedVec::new(Arc::clone(&limiter));

vec_u32.push(1).unwrap();
vec_u32.push(2).unwrap();
assert_eq!(limiter.borrow().current_usage(), 8);
assert_eq!(limiter.lock().unwrap().current_usage(), 8);
}
}

#[test]
fn max_limit() {
let limiter = MemoryLimiter::new_shared(2);
let mut vector: LimitedVec<u8> = LimitedVec::new(Rc::clone(&limiter));
let mut vector: LimitedVec<u8> = LimitedVec::new(Arc::clone(&limiter));

vector.push(1).unwrap();
vector.push(2).unwrap();
Expand All @@ -142,35 +147,35 @@ mod tests {
let limiter = MemoryLimiter::new_shared(1);

{
let mut vector: LimitedVec<u8> = LimitedVec::new(Rc::clone(&limiter));
let mut vector: LimitedVec<u8> = LimitedVec::new(Arc::clone(&limiter));

vector.push(1).unwrap();
assert_eq!(limiter.borrow().current_usage(), 1);
assert_eq!(limiter.lock().unwrap().current_usage(), 1);
}

assert_eq!(limiter.borrow().current_usage(), 0);
assert_eq!(limiter.lock().unwrap().current_usage(), 0);
}

#[test]
fn drain() {
let limiter = MemoryLimiter::new_shared(10);
let mut vector: LimitedVec<u8> = LimitedVec::new(Rc::clone(&limiter));
let mut vector: LimitedVec<u8> = LimitedVec::new(Arc::clone(&limiter));

vector.push(1).unwrap();
vector.push(2).unwrap();
vector.push(3).unwrap();
assert_eq!(limiter.borrow().current_usage(), 3);
assert_eq!(limiter.lock().unwrap().current_usage(), 3);

vector.drain(0..3);
assert_eq!(limiter.borrow().current_usage(), 0);
assert_eq!(limiter.lock().unwrap().current_usage(), 0);

vector.push(1).unwrap();
vector.push(2).unwrap();
vector.push(3).unwrap();
vector.push(4).unwrap();
assert_eq!(limiter.borrow().current_usage(), 4);
assert_eq!(limiter.lock().unwrap().current_usage(), 4);

vector.drain(1..=2);
assert_eq!(limiter.borrow().current_usage(), 2);
assert_eq!(limiter.lock().unwrap().current_usage(), 2);
}
}
11 changes: 5 additions & 6 deletions src/memory/limiter.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use std::cell::RefCell;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use thiserror::Error;

pub type SharedMemoryLimiter = Rc<RefCell<MemoryLimiter>>;
pub type SharedMemoryLimiter = Arc<Mutex<MemoryLimiter>>;

/// An error that occures when rewriter exceedes the memory limit specified in the
/// [`MemorySettings`].
Expand All @@ -20,7 +19,7 @@ pub struct MemoryLimiter {

impl MemoryLimiter {
pub fn new_shared(max: usize) -> SharedMemoryLimiter {
Rc::new(RefCell::new(MemoryLimiter {
Arc::new(Mutex::new(MemoryLimiter {
max,
current_usage: 0,
}))
Expand Down Expand Up @@ -62,7 +61,7 @@ mod tests {
#[test]
fn current_usage() {
let limiter = MemoryLimiter::new_shared(10);
let mut limiter = limiter.borrow_mut();
let mut limiter = limiter.lock().unwrap();

assert_eq!(limiter.current_usage(), 0);

Expand All @@ -86,7 +85,7 @@ mod tests {
)]
fn preallocate() {
let limiter = MemoryLimiter::new_shared(10);
let mut limiter = limiter.borrow_mut();
let mut limiter = limiter.lock().unwrap();

limiter.preallocate(8);
assert_eq!(limiter.current_usage(), 8);
Expand Down
8 changes: 4 additions & 4 deletions src/parser/lexer/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl<S: LexemeSink> StateMachineActions for Lexer<S> {
} = lexeme.token_outline
{
self.last_start_tag_name_hash = name_hash;
*ns = self.tree_builder_simulator.borrow().current_ns();
*ns = self.tree_builder_simulator.lock().unwrap().current_ns();
}

match self
Expand Down Expand Up @@ -122,13 +122,13 @@ impl<S: LexemeSink> StateMachineActions for Lexer<S> {

#[inline]
fn create_start_tag(&mut self, _input: &[u8]) {
self.attr_buffer.borrow_mut().clear();
self.attr_buffer.lock().unwrap().clear();

self.current_tag_token = Some(StartTag {
name: Range::default(),
name_hash: LocalNameHash::new(),
ns: Namespace::default(),
attributes: Rc::clone(&self.attr_buffer),
attributes: Arc::clone(&self.attr_buffer),
self_closing: false,
});
}
Expand Down Expand Up @@ -295,7 +295,7 @@ impl<S: LexemeSink> StateMachineActions for Lexer<S> {
#[inline]
fn finish_attr(&mut self, _input: &[u8]) {
if let Some(attr) = self.current_attr.take() {
self.attr_buffer.borrow_mut().push(attr);
self.attr_buffer.lock().unwrap().push(attr);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/parser/lexer/lexeme/token_outline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl Align for TagTokenOutline {
name, attributes, ..
} => {
name.align(offset);
attributes.borrow_mut().align(offset);
attributes.lock().unwrap().align(offset);
}
TagTokenOutline::EndTag { name, .. } => name.align(offset),
}
Expand Down
Loading
Loading