aboutsummaryrefslogtreecommitdiffstats
path: root/components/util
diff options
context:
space:
mode:
Diffstat (limited to 'components/util')
-rw-r--r--components/util/Cargo.toml8
-rw-r--r--components/util/bloom.rs12
-rw-r--r--components/util/cache.rs99
-rw-r--r--components/util/cursor.rs5
-rw-r--r--components/util/deque/mod.rs268
-rw-r--r--components/util/fnv.rs34
-rw-r--r--components/util/geometry.rs78
-rw-r--r--components/util/lib.rs27
-rw-r--r--components/util/logical_geometry.rs85
-rw-r--r--components/util/memory.rs25
-rw-r--r--components/util/opts.rs37
-rw-r--r--components/util/persistent_list.rs4
-rw-r--r--components/util/range.rs92
-rw-r--r--components/util/rtinstrument.rs197
-rw-r--r--components/util/smallvec.rs128
-rw-r--r--components/util/sort.rs13
-rw-r--r--components/util/str.rs44
-rw-r--r--components/util/task.rs64
-rw-r--r--components/util/task_state.rs8
-rw-r--r--components/util/taskpool.rs18
-rw-r--r--components/util/tid.rs8
-rw-r--r--components/util/time.rs56
-rw-r--r--components/util/vec.rs10
-rw-r--r--components/util/workqueue.rs39
24 files changed, 480 insertions, 879 deletions
diff --git a/components/util/Cargo.toml b/components/util/Cargo.toml
index c418d0b2880..d9209c74e4f 100644
--- a/components/util/Cargo.toml
+++ b/components/util/Cargo.toml
@@ -36,11 +36,7 @@ git = "https://github.com/servo/string-cache"
[dependencies.string_cache_macros]
git = "https://github.com/servo/string-cache"
-[dependencies.url]
-git = "https://github.com/servo/rust-url"
-
-[dependencies.time]
-git = "https://github.com/rust-lang/time"
-
[dependencies]
text_writer = "0.1.1"
+url = "*"
+time = "*" \ No newline at end of file
diff --git a/components/util/bloom.rs b/components/util/bloom.rs
index 2bed80e9e13..6fd5d17e775 100644
--- a/components/util/bloom.rs
+++ b/components/util/bloom.rs
@@ -58,7 +58,7 @@ const KEY_SHIFT: uint = 16;
/// positive rate for N == 100 and to quite bad false positive
/// rates for larger N.
pub struct BloomFilter {
- counters: [u8, ..ARRAY_SIZE],
+ counters: [u8; ARRAY_SIZE],
}
impl Clone for BloomFilter {
@@ -75,7 +75,7 @@ impl BloomFilter {
#[inline]
pub fn new() -> BloomFilter {
BloomFilter {
- counters: [0, ..ARRAY_SIZE],
+ counters: [0; ARRAY_SIZE],
}
}
@@ -101,7 +101,7 @@ impl BloomFilter {
#[inline]
pub fn clear(&mut self) {
- self.counters = [0, ..ARRAY_SIZE]
+ self.counters = [0; ARRAY_SIZE]
}
#[inline]
@@ -231,7 +231,7 @@ fn create_and_insert_some_stuff() {
let false_positives =
range(1001u, 2000).filter(|i| bf.might_contain(i)).count();
- assert!(false_positives < 10) // 1%.
+ assert!(false_positives < 10); // 1%.
for i in range(0u, 100) {
bf.remove(&i);
@@ -256,7 +256,7 @@ fn create_and_insert_some_stuff() {
mod bench {
extern crate test;
- use std::hash::hash;
+ use std::hash::{hash, SipHasher};
use std::iter;
use super::BloomFilter;
@@ -331,7 +331,7 @@ mod bench {
fn hash_a_uint(b: &mut test::Bencher) {
let mut i = 0u;
b.iter(|| {
- test::black_box(hash(&i));
+ test::black_box(hash::<uint, SipHasher>(&i));
i += 1;
})
}
diff --git a/components/util/cache.rs b/components/util/cache.rs
index 35390d309bf..99e086cdbfe 100644
--- a/components/util/cache.rs
+++ b/components/util/cache.rs
@@ -2,69 +2,59 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#![old_impl_check]
+
use std::collections::HashMap;
-use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::hash_map::Entry::{Occupied, Vacant};
+use std::collections::hash_state::DefaultState;
use rand::Rng;
-use std::hash::{Hash, sip};
+use std::hash::{Hash, SipHasher};
use std::iter::repeat;
-use std::rand::task_rng;
-use std::slice::Items;
+use std::rand;
+use std::slice::Iter;
#[cfg(test)]
use std::cell::Cell;
-pub trait Cache<K: PartialEq, V: Clone> {
- fn insert(&mut self, key: K, value: V);
- fn find(&mut self, key: &K) -> Option<V>;
- fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V;
- fn evict_all(&mut self);
-}
-
pub struct HashCache<K, V> {
- entries: HashMap<K, V>,
+ entries: HashMap<K, V, DefaultState<SipHasher>>,
}
-impl<K: Clone + PartialEq + Eq + Hash, V: Clone> HashCache<K,V> {
- pub fn new() -> HashCache<K, V> {
+impl<K, V> HashCache<K,V>
+ where K: Clone + PartialEq + Eq + Hash<SipHasher>,
+ V: Clone,
+{
+ pub fn new() -> HashCache<K,V> {
HashCache {
- entries: HashMap::new(),
+ entries: HashMap::with_hash_state(DefaultState),
}
}
-}
-impl<K: Clone + PartialEq + Eq + Hash, V: Clone> Cache<K,V> for HashCache<K,V> {
- fn insert(&mut self, key: K, value: V) {
+ pub fn insert(&mut self, key: K, value: V) {
self.entries.insert(key, value);
}
- fn find(&mut self, key: &K) -> Option<V> {
+ pub fn find(&self, key: &K) -> Option<V> {
match self.entries.get(key) {
Some(v) => Some(v.clone()),
- None => None,
+ None => None,
}
}
- fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V {
+ pub fn find_or_create<F>(&mut self, key: &K, blk: F) -> V where F: Fn(&K) -> V {
match self.entries.entry(key.clone()) {
Occupied(occupied) => {
(*occupied.get()).clone()
}
Vacant(vacant) => {
- (*vacant.set(blk(key))).clone()
+ (*vacant.insert(blk(key))).clone()
}
}
}
- fn evict_all(&mut self) {
+ pub fn evict_all(&mut self) {
self.entries.clear();
}
-
-}
-
-impl<K,V> HashCache<K,V> where K: Clone + PartialEq + Eq + Hash, V: Clone {
- pub fn find_equiv<'a,Sized? Q>(&'a self, key: &Q) -> Option<&'a V> where Q: Hash + Equiv<K> {
- self.entries.find_equiv(key)
- }
}
#[test]
@@ -98,32 +88,30 @@ impl<K: Clone + PartialEq, V: Clone> LRUCache<K,V> {
let last_index = self.entries.len() - 1;
if pos != last_index {
let entry = self.entries.remove(pos);
- self.entries.push(entry.unwrap());
+ self.entries.push(entry);
}
- self.entries[last_index].ref1().clone()
+ self.entries[last_index].1.clone()
}
- pub fn iter<'a>(&'a self) -> Items<'a,(K,V)> {
+ pub fn iter<'a>(&'a self) -> Iter<'a,(K,V)> {
self.entries.iter()
}
-}
-impl<K: Clone + PartialEq, V: Clone> Cache<K,V> for LRUCache<K,V> {
- fn insert(&mut self, key: K, val: V) {
+ pub fn insert(&mut self, key: K, val: V) {
if self.entries.len() == self.cache_size {
self.entries.remove(0);
}
self.entries.push((key, val));
}
- fn find(&mut self, key: &K) -> Option<V> {
- match self.entries.iter().position(|&(ref k, _)| *k == *key) {
+ pub fn find(&mut self, key: &K) -> Option<V> {
+ match self.entries.iter().position(|&(ref k, _)| key == k) {
Some(pos) => Some(self.touch(pos)),
None => None,
}
}
- fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V {
+ pub fn find_or_create<F>(&mut self, key: &K, blk: F) -> V where F: Fn(&K) -> V {
match self.entries.iter().position(|&(ref k, _)| *k == *key) {
Some(pos) => self.touch(pos),
None => {
@@ -134,7 +122,7 @@ impl<K: Clone + PartialEq, V: Clone> Cache<K,V> for LRUCache<K,V> {
}
}
- fn evict_all(&mut self) {
+ pub fn evict_all(&mut self) {
self.entries.clear();
}
}
@@ -145,9 +133,9 @@ pub struct SimpleHashCache<K,V> {
k1: u64,
}
-impl<K:Clone+PartialEq+Hash,V:Clone> SimpleHashCache<K,V> {
+impl<K:Clone+Eq+Hash<SipHasher>,V:Clone> SimpleHashCache<K,V> {
pub fn new(cache_size: uint) -> SimpleHashCache<K,V> {
- let mut r = task_rng();
+ let mut r = rand::thread_rng();
SimpleHashCache {
entries: repeat(None).take(cache_size).collect(),
k0: r.gen(),
@@ -161,35 +149,26 @@ impl<K:Clone+PartialEq+Hash,V:Clone> SimpleHashCache<K,V> {
}
#[inline]
- fn bucket_for_key<Q:Hash>(&self, key: &Q) -> uint {
- self.to_bucket(sip::hash_with_keys(self.k0, self.k1, key) as uint)
+ fn bucket_for_key<Q:Hash<SipHasher>>(&self, key: &Q) -> uint {
+ let mut hasher = SipHasher::new_with_keys(self.k0, self.k1);
+ key.hash(&mut hasher);
+ self.to_bucket(hasher.result() as uint)
}
- #[inline]
- pub fn find_equiv<'a,Q:Hash+Equiv<K>>(&'a self, key: &Q) -> Option<&'a V> {
- let bucket_index = self.bucket_for_key(key);
- match self.entries[bucket_index] {
- Some((ref existing_key, ref value)) if key.equiv(existing_key) => Some(value),
- _ => None,
- }
- }
-}
-
-impl<K:Clone+PartialEq+Hash,V:Clone> Cache<K,V> for SimpleHashCache<K,V> {
- fn insert(&mut self, key: K, value: V) {
+ pub fn insert(&mut self, key: K, value: V) {
let bucket_index = self.bucket_for_key(&key);
self.entries[bucket_index] = Some((key, value));
}
- fn find(&mut self, key: &K) -> Option<V> {
+ pub fn find<Q>(&self, key: &Q) -> Option<V> where Q: PartialEq<K> + Hash<SipHasher> + Eq {
let bucket_index = self.bucket_for_key(key);
match self.entries[bucket_index] {
- Some((ref existing_key, ref value)) if existing_key == key => Some((*value).clone()),
+ Some((ref existing_key, ref value)) if key == existing_key => Some((*value).clone()),
_ => None,
}
}
- fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V {
+ pub fn find_or_create<F>(&mut self, key: &K, blk: F) -> V where F: Fn(&K) -> V {
match self.find(key) {
Some(value) => return value,
None => {}
@@ -199,7 +178,7 @@ impl<K:Clone+PartialEq+Hash,V:Clone> Cache<K,V> for SimpleHashCache<K,V> {
value
}
- fn evict_all(&mut self) {
+ pub fn evict_all(&mut self) {
for slot in self.entries.iter_mut() {
*slot = None
}
diff --git a/components/util/cursor.rs b/components/util/cursor.rs
index 23ca2c0af4a..ff203f1a0e7 100644
--- a/components/util/cursor.rs
+++ b/components/util/cursor.rs
@@ -8,10 +8,9 @@ use cssparser::ToCss;
use std::ascii::AsciiExt;
use text_writer::TextWriter;
-
macro_rules! define_cursor {
($( $css: expr => $variant: ident = $value: expr, )+) => {
- #[deriving(Clone, Copy, PartialEq, Eq, FromPrimitive, Show)]
+ #[derive(Clone, Copy, PartialEq, Eq, FromPrimitive, Show)]
#[repr(u8)]
pub enum Cursor {
$( $variant = $value ),+
@@ -19,7 +18,7 @@ macro_rules! define_cursor {
impl Cursor {
pub fn from_css_keyword(keyword: &str) -> Result<Cursor, ()> {
- match_ignore_ascii_case! { keyword:
+ match_ignore_ascii_case! { keyword,
$( concat!($css) => Ok(Cursor::$variant) ),+
_ => Err(())
}
diff --git a/components/util/deque/mod.rs b/components/util/deque/mod.rs
index b98c872cf0f..505b09ab021 100644
--- a/components/util/deque/mod.rs
+++ b/components/util/deque/mod.rs
@@ -54,12 +54,13 @@ pub use self::Stolen::{Empty, Abort, Data};
use alloc::arc::Arc;
use alloc::heap::{allocate, deallocate};
-use std::kinds::marker;
+use std::marker;
use std::mem::{forget, min_align_of, size_of, transmute};
use std::ptr;
use std::sync::Mutex;
-use std::sync::atomic::{AtomicInt, AtomicPtr, SeqCst};
+use std::sync::atomic::{AtomicInt, AtomicPtr};
+use std::sync::atomic::Ordering::SeqCst;
// Once the queue is less than 1/K full, then it will be downsized. Note that
// the deque requires that this number be less than 2.
@@ -97,7 +98,7 @@ pub struct Stealer<T> {
}
/// When stealing some data, this is an enumeration of the possible outcomes.
-#[deriving(PartialEq, Show)]
+#[derive(PartialEq, Show)]
pub enum Stolen<T> {
/// The deque was empty at the time of stealing
Empty,
@@ -141,6 +142,8 @@ struct Buffer<T> {
log_size: uint,
}
+unsafe impl<T: 'static> Send for Buffer<T> { }
+
impl<T: Send> BufferPool<T> {
/// Allocates a new buffer pool which in turn can be used to allocate new
/// deques.
@@ -159,16 +162,16 @@ impl<T: Send> BufferPool<T> {
fn alloc(&mut self, bits: uint) -> Box<Buffer<T>> {
unsafe {
- let mut pool = self.pool.lock();
+ let mut pool = self.pool.lock().unwrap();
match pool.iter().position(|x| x.size() >= (1 << bits)) {
- Some(i) => pool.remove(i).unwrap(),
+ Some(i) => pool.remove(i),
None => box Buffer::new(bits)
}
}
}
fn free(&self, buf: Box<Buffer<T>>) {
- let mut pool = self.pool.lock();
+ let mut pool = self.pool.lock().unwrap();
match pool.iter().position(|v| v.size() > buf.size()) {
Some(i) => pool.insert(i, buf),
None => pool.push(buf),
@@ -403,256 +406,3 @@ impl<T: Send> Drop for Buffer<T> {
unsafe { deallocate(self.storage as *mut u8, size, min_align_of::<T>()) }
}
}
-
-#[cfg(test)]
-mod tests {
- use super::{Data, BufferPool, Abort, Empty, Worker, Stealer};
-
- use std::mem;
- use rustrt::thread::Thread;
- use std::rand;
- use std::rand::Rng;
- use std::sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL, SeqCst,
- AtomicUint, INIT_ATOMIC_UINT};
- use std::vec;
-
- #[test]
- fn smoke() {
- let pool = BufferPool::new();
- let (w, s) = pool.deque();
- assert_eq!(w.pop(), None);
- assert_eq!(s.steal(), Empty);
- w.push(1i);
- assert_eq!(w.pop(), Some(1));
- w.push(1);
- assert_eq!(s.steal(), Data(1));
- w.push(1);
- assert_eq!(s.clone().steal(), Data(1));
- }
-
- #[test]
- fn stealpush() {
- static AMT: int = 100000;
- let pool = BufferPool::<int>::new();
- let (w, s) = pool.deque();
- let t = Thread::start(proc() {
- let mut left = AMT;
- while left > 0 {
- match s.steal() {
- Data(i) => {
- assert_eq!(i, 1);
- left -= 1;
- }
- Abort | Empty => {}
- }
- }
- });
-
- for _ in range(0, AMT) {
- w.push(1);
- }
-
- t.join();
- }
-
- #[test]
- fn stealpush_large() {
- static AMT: int = 100000;
- let pool = BufferPool::<(int, int)>::new();
- let (w, s) = pool.deque();
- let t = Thread::start(proc() {
- let mut left = AMT;
- while left > 0 {
- match s.steal() {
- Data((1, 10)) => { left -= 1; }
- Data(..) => panic!(),
- Abort | Empty => {}
- }
- }
- });
-
- for _ in range(0, AMT) {
- w.push((1, 10));
- }
-
- t.join();
- }
-
- fn stampede(w: Worker<Box<int>>, s: Stealer<Box<int>>,
- nthreads: int, amt: uint) {
- for _ in range(0, amt) {
- w.push(box 20);
- }
- let mut remaining = AtomicUint::new(amt);
- let unsafe_remaining: *mut AtomicUint = &mut remaining;
-
- let threads = range(0, nthreads).map(|_| {
- let s = s.clone();
- Thread::start(proc() {
- unsafe {
- while (*unsafe_remaining).load(SeqCst) > 0 {
- match s.steal() {
- Data(box 20) => {
- (*unsafe_remaining).fetch_sub(1, SeqCst);
- }
- Data(..) => panic!(),
- Abort | Empty => {}
- }
- }
- }
- })
- }).collect::<Vec<Thread<()>>>();
-
- while remaining.load(SeqCst) > 0 {
- match w.pop() {
- Some(box 20) => { remaining.fetch_sub(1, SeqCst); }
- Some(..) => panic!(),
- None => {}
- }
- }
-
- for thread in threads.into_iter() {
- thread.join();
- }
- }
-
- #[test]
- fn run_stampede() {
- let pool = BufferPool::<Box<int>>::new();
- let (w, s) = pool.deque();
- stampede(w, s, 8, 10000);
- }
-
- #[test]
- fn many_stampede() {
- static AMT: uint = 4;
- let pool = BufferPool::<Box<int>>::new();
- let threads = range(0, AMT).map(|_| {
- let (w, s) = pool.deque();
- Thread::start(proc() {
- stampede(w, s, 4, 10000);
- })
- }).collect::<Vec<Thread<()>>>();
-
- for thread in threads.into_iter() {
- thread.join();
- }
- }
-
- #[test]
- fn stress() {
- static AMT: int = 100000;
- static NTHREADS: int = 8;
- static DONE: AtomicBool = INIT_ATOMIC_BOOL;
- static HITS: AtomicUint = INIT_ATOMIC_UINT;
- let pool = BufferPool::<int>::new();
- let (w, s) = pool.deque();
-
- let threads = range(0, NTHREADS).map(|_| {
- let s = s.clone();
- Thread::start(proc() {
- loop {
- match s.steal() {
- Data(2) => { HITS.fetch_add(1, SeqCst); }
- Data(..) => panic!(),
- _ if DONE.load(SeqCst) => break,
- _ => {}
- }
- }
- })
- }).collect::<Vec<Thread<()>>>();
-
- let mut rng = rand::task_rng();
- let mut expected = 0;
- while expected < AMT {
- if rng.gen_range(0i, 3) == 2 {
- match w.pop() {
- None => {}
- Some(2) => { HITS.fetch_add(1, SeqCst); },
- Some(_) => panic!(),
- }
- } else {
- expected += 1;
- w.push(2);
- }
- }
-
- while HITS.load(SeqCst) < AMT as uint {
- match w.pop() {
- None => {}
- Some(2) => { HITS.fetch_add(1, SeqCst); },
- Some(_) => panic!(),
- }
- }
- DONE.store(true, SeqCst);
-
- for thread in threads.into_iter() {
- thread.join();
- }
-
- assert_eq!(HITS.load(SeqCst), expected as uint);
- }
-
- #[test]
- #[cfg_attr(windows, ignore)] // apparently windows scheduling is weird?
- fn no_starvation() {
- static AMT: int = 10000;
- static NTHREADS: int = 4;
- static DONE: AtomicBool = INIT_ATOMIC_BOOL;
- let pool = BufferPool::<(int, uint)>::new();
- let (w, s) = pool.deque();
-
- let (threads, hits) = vec::unzip(range(0, NTHREADS).map(|_| {
- let s = s.clone();
- let unique_box = box AtomicUint::new(0);
- let thread_box = unsafe {
- *mem::transmute::<&Box<AtomicUint>,
- *const *mut AtomicUint>(&unique_box)
- };
- (Thread::start(proc() {
- unsafe {
- loop {
- match s.steal() {
- Data((1, 2)) => {
- (*thread_box).fetch_add(1, SeqCst);
- }
- Data(..) => panic!(),
- _ if DONE.load(SeqCst) => break,
- _ => {}
- }
- }
- }
- }), unique_box)
- }));
-
- let mut rng = rand::task_rng();
- let mut myhit = false;
- 'outer: loop {
- for _ in range(0, rng.gen_range(0, AMT)) {
- if !myhit && rng.gen_range(0i, 3) == 2 {
- match w.pop() {
- None => {}
- Some((1, 2)) => myhit = true,
- Some(_) => panic!(),
- }
- } else {
- w.push((1, 2));
- }
- }
-
- for slot in hits.iter() {
- let amt = slot.load(SeqCst);
- if amt == 0 { continue 'outer; }
- }
- if myhit {
- break
- }
- }
-
- DONE.store(true, SeqCst);
-
- for thread in threads.into_iter() {
- thread.join();
- }
- }
-}
diff --git a/components/util/fnv.rs b/components/util/fnv.rs
index 13c8e1c28ad..61b4cd73d48 100644
--- a/components/util/fnv.rs
+++ b/components/util/fnv.rs
@@ -4,7 +4,8 @@
//! This file stolen wholesale from rustc/src/librustc/util/nodemap.rs
-pub use std::hash::{Hash, Hasher, Writer};
+use std::default::Default;
+use std::hash::{Hasher, Writer};
/// A speedy hash algorithm for node ids and def ids. The hashmap in
/// libcollections by default uses SipHash which isn't quite as speedy as we
@@ -13,33 +14,26 @@ pub use std::hash::{Hash, Hasher, Writer};
///
/// This uses FNV hashing, as described here:
/// http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
-#[deriving(Clone)]
-pub struct FnvHasher;
+#[allow(missing_copy_implementations)]
+pub struct FnvHasher(u64);
-pub struct FnvState(u64);
+impl Default for FnvHasher {
+ fn default() -> FnvHasher { FnvHasher(0xcbf29ce484222325) }
+}
-impl Hasher<FnvState> for FnvHasher {
- fn hash<Sized? T: Hash<FnvState>>(&self, t: &T) -> u64 {
- let mut state = FnvState(0xcbf29ce484222325);
- t.hash(&mut state);
- let FnvState(ret) = state;
- return ret;
- }
+impl Hasher for FnvHasher {
+ type Output = u64;
+ fn reset(&mut self) { *self = Default::default(); }
+ fn finish(&self) -> u64 { self.0 }
}
-impl Writer for FnvState {
+impl Writer for FnvHasher {
fn write(&mut self, bytes: &[u8]) {
- let FnvState(mut hash) = *self;
+ let FnvHasher(mut hash) = *self;
for byte in bytes.iter() {
hash = hash ^ (*byte as u64);
hash = hash * 0x100000001b3;
}
- *self = FnvState(hash);
+ *self = FnvHasher(hash);
}
}
-
-#[inline(always)]
-pub fn hash<T: Hash<FnvState>>(t: &T) -> u64 {
- let s = FnvHasher;
- s.hash(t)
-}
diff --git a/components/util/geometry.rs b/components/util/geometry.rs
index 5c3ee808b43..a30849eaf5d 100644
--- a/components/util/geometry.rs
+++ b/components/util/geometry.rs
@@ -8,11 +8,13 @@ use geom::rect::Rect;
use geom::size::Size2D;
use geom::num::Zero;
-use serialize::{Encodable, Encoder};
use std::default::Default;
use std::i32;
-use std::num::{Float, NumCast};
+use std::num::{Float, NumCast, ToPrimitive};
use std::fmt;
+use std::ops::{Add, Sub, Neg, Mul, Div, Rem};
+
+use rustc_serialize::{Encoder, Encodable};
// Units for use with geom::length and geom::scale_factor.
@@ -29,7 +31,7 @@ use std::fmt;
///
/// The ratio between ScreenPx and DevicePixel for a given display be found by calling
/// `servo::windowing::WindowMethods::hidpi_factor`.
-#[deriving(Show, Copy)]
+#[derive(Show, Copy)]
pub enum ScreenPx {}
/// One CSS "px" in the coordinate system of the "initial viewport":
@@ -41,7 +43,7 @@ pub enum ScreenPx {}
///
/// At the default zoom level of 100%, one PagePx is equal to one ScreenPx. However, if the
/// document is zoomed in or out then this scale may be larger or smaller.
-#[deriving(Encodable, Show, Copy)]
+#[derive(RustcEncodable, Show, Copy)]
pub enum ViewportPx {}
/// One CSS "px" in the root coordinate system for the content document.
@@ -50,7 +52,7 @@ pub enum ViewportPx {}
/// This is the mobile-style "pinch zoom" that enlarges content without reflowing it. When the
/// viewport zoom is not equal to 1.0, then the layout viewport is no longer the same physical size
/// as the viewable area.
-#[deriving(Encodable, Show, Copy)]
+#[derive(RustcEncodable, Show, Copy)]
pub enum PagePx {}
// In summary, the hierarchy of pixel units and the factors to convert from one to the next:
@@ -65,7 +67,7 @@ pub enum PagePx {}
// See https://bugzilla.mozilla.org/show_bug.cgi?id=177805 for more info.
//
// FIXME: Implement Au using Length and ScaleFactor instead of a custom type.
-#[deriving(Clone, Copy, Hash, PartialEq, PartialOrd, Eq, Ord)]
+#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Eq, Ord)]
pub struct Au(pub i32);
impl Default for Au {
@@ -112,8 +114,8 @@ pub static MAX_RECT: Rect<Au> = Rect {
pub const MIN_AU: Au = Au(i32::MIN);
pub const MAX_AU: Au = Au(i32::MAX);
-impl<E, S: Encoder<E>> Encodable<S, E> for Au {
- fn encode(&self, e: &mut S) -> Result<(), E> {
+impl Encodable for Au {
+ fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
e.emit_f64(to_frac_px(*self))
}
}
@@ -123,53 +125,65 @@ impl fmt::Show for Au {
write!(f, "{}px", to_frac_px(*self))
}}
-impl Add<Au,Au> for Au {
+impl Add for Au {
+ type Output = Au;
+
#[inline]
- fn add(&self, other: &Au) -> Au {
- let Au(s) = *self;
- let Au(o) = *other;
+ fn add(self, other: Au) -> Au {
+ let Au(s) = self;
+ let Au(o) = other;
Au(s + o)
}
}
-impl Sub<Au,Au> for Au {
+impl Sub for Au {
+ type Output = Au;
+
#[inline]
- fn sub(&self, other: &Au) -> Au {
- let Au(s) = *self;
- let Au(o) = *other;
+ fn sub(self, other: Au) -> Au {
+ let Au(s) = self;
+ let Au(o) = other;
Au(s - o)
}
}
-impl Mul<i32, Au> for Au {
+impl Mul<i32> for Au {
+ type Output = Au;
+
#[inline]
- fn mul(&self, other: &i32) -> Au {
- let Au(s) = *self;
- Au(s * *other)
+ fn mul(self, other: i32) -> Au {
+ let Au(s) = self;
+ Au(s * other)
}
}
-impl Div<i32, Au> for Au {
+impl Div<i32> for Au {
+ type Output = Au;
+
#[inline]
- fn div(&self, other: &i32) -> Au {
- let Au(s) = *self;
- Au(s / *other)
+ fn div(self, other: i32) -> Au {
+ let Au(s) = self;
+ Au(s / other)
}
}
-impl Rem<i32, Au> for Au {
+impl Rem<i32> for Au {
+ type Output = Au;
+
#[inline]
- fn rem(&self, other: &i32) -> Au {
- let Au(s) = *self;
- Au(s % *other)
+ fn rem(self, other: i32) -> Au {
+ let Au(s) = self;
+ Au(s % other)
}
}
-impl Neg<Au> for Au {
+impl Neg for Au {
+ type Output = Au;
+
#[inline]
- fn neg(&self) -> Au {
- let Au(s) = *self;
+ fn neg(self) -> Au {
+ let Au(s) = self;
Au(-s)
}
}
@@ -323,7 +337,7 @@ pub fn to_pt(au: Au) -> f64 {
/// Returns true if the rect contains the given point. Points on the top or left sides of the rect
/// are considered inside the rectangle, while points on the right or bottom sides of the rect are
/// not considered inside the rectangle.
-pub fn rect_contains_point<T:PartialOrd + Add<T,T>>(rect: Rect<T>, point: Point2D<T>) -> bool {
+pub fn rect_contains_point<T:PartialOrd + Add<T, Output=T>>(rect: Rect<T>, point: Point2D<T>) -> bool {
point.x >= rect.origin.x && point.x < rect.origin.x + rect.size.width &&
point.y >= rect.origin.y && point.y < rect.origin.y + rect.size.height
}
diff --git a/components/util/lib.rs b/components/util/lib.rs
index d69bc982e17..bceab7a3014 100644
--- a/components/util/lib.rs
+++ b/components/util/lib.rs
@@ -2,15 +2,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#![feature(default_type_params,macro_rules,unsafe_destructor)]
+#![feature(unsafe_destructor)]
+#![feature(plugin)]
+#![feature(int_uint)]
+#![feature(old_impl_check)]
+#![feature(box_syntax)]
#![deny(unused_imports)]
#![deny(unused_variables)]
#![allow(missing_copy_implementations)]
+#![allow(unstable)]
-#![feature(phase)]
-#[phase(plugin, link)]
-extern crate log;
+#[macro_use] extern crate log;
extern crate alloc;
extern crate collections;
@@ -19,9 +22,9 @@ extern crate geom;
extern crate getopts;
extern crate layers;
extern crate libc;
+#[no_link] #[macro_use] extern crate cssparser;
extern crate rand;
-extern crate rustrt;
-extern crate serialize;
+extern crate "serialize" as rustc_serialize;
#[cfg(target_os="macos")]
extern crate task_info;
extern crate "time" as std_time;
@@ -30,9 +33,9 @@ extern crate string_cache;
extern crate unicode;
extern crate url;
-#[phase(plugin)] extern crate plugins;
-#[phase(plugin)] extern crate string_cache_macros;
-#[phase(plugin)] extern crate lazy_static;
+#[no_link] #[macro_use] #[plugin]
+extern crate string_cache_macros;
+extern crate lazy_static;
use std::sync::Arc;
@@ -51,8 +54,6 @@ pub mod opts;
pub mod persistent_list;
pub mod range;
pub mod resource_files;
-// FIXME: Find replacement for this post-runtime removal
-// pub mod rtinstrument;
pub mod smallvec;
pub mod sort;
pub mod str;
@@ -71,7 +72,7 @@ pub fn breakpoint() {
// Workaround for lack of `ptr_eq` on Arcs...
#[inline]
pub fn arc_ptr_eq<T: 'static + Send + Sync>(a: &Arc<T>, b: &Arc<T>) -> bool {
- let a: &T = a.deref();
- let b: &T = b.deref();
+ let a: &T = &**a;
+ let b: &T = &**b;
(a as *const T) == (b as *const T)
}
diff --git a/components/util/logical_geometry.rs b/components/util/logical_geometry.rs
index eebd0735b81..a76bd1ca21e 100644
--- a/components/util/logical_geometry.rs
+++ b/components/util/logical_geometry.rs
@@ -8,16 +8,17 @@ use geom::{Size2D, Point2D, SideOffsets2D, Rect};
use geom::num::Zero;
use std::cmp::{min, max};
use std::fmt::{Show, Formatter, Error};
+use std::ops::{Add, Sub};
bitflags!(
- #[deriving(Encodable, Copy)]
+ #[derive(RustcEncodable)]
flags WritingMode: u8 {
const FLAG_RTL = 1 << 0,
const FLAG_VERTICAL = 1 << 1,
const FLAG_VERTICAL_LR = 1 << 2,
const FLAG_SIDEWAYS_LEFT = 1 << 3
}
-)
+);
impl WritingMode {
#[inline]
@@ -79,11 +80,11 @@ impl Show for WritingMode {
/// (in addition to taking it as a parameter to methods) and check it.
/// In non-debug builds, make this storage zero-size and the checks no-ops.
#[cfg(ndebug)]
-#[deriving(Encodable, PartialEq, Eq, Clone, Copy)]
+#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)]
struct DebugWritingMode;
#[cfg(not(ndebug))]
-#[deriving(Encodable, PartialEq, Eq, Clone, Copy)]
+#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)]
struct DebugWritingMode {
mode: WritingMode
}
@@ -134,7 +135,7 @@ impl Show for DebugWritingMode {
/// A 2D size in flow-relative dimensions
-#[deriving(Encodable, PartialEq, Eq, Clone, Copy)]
+#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)]
pub struct LogicalSize<T> {
pub inline: T, // inline-size, a.k.a. logical width, a.k.a. measure
pub block: T, // block-size, a.k.a. logical height, a.k.a. extent
@@ -143,7 +144,7 @@ pub struct LogicalSize<T> {
impl<T: Show> Show for LogicalSize<T> {
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
- write!(formatter, "LogicalSize({}, i{}×b{})",
+ write!(formatter, "LogicalSize({:?}, i{:?}×b{:?})",
self.debug_writing_mode, self.inline, self.block)
}
}
@@ -240,9 +241,11 @@ impl<T: Copy> LogicalSize<T> {
}
}
-impl<T: Add<T, T>> Add<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> {
+impl<T: Add<T, Output=T>> Add for LogicalSize<T> {
+ type Output = LogicalSize<T>;
+
#[inline]
- fn add(&self, other: &LogicalSize<T>) -> LogicalSize<T> {
+ fn add(self, other: LogicalSize<T>) -> LogicalSize<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
LogicalSize {
debug_writing_mode: self.debug_writing_mode,
@@ -252,9 +255,11 @@ impl<T: Add<T, T>> Add<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> {
}
}
-impl<T: Sub<T, T>> Sub<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> {
+impl<T: Sub<T, Output=T>> Sub for LogicalSize<T> {
+ type Output = LogicalSize<T>;
+
#[inline]
- fn sub(&self, other: &LogicalSize<T>) -> LogicalSize<T> {
+ fn sub(self, other: LogicalSize<T>) -> LogicalSize<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
LogicalSize {
debug_writing_mode: self.debug_writing_mode,
@@ -266,7 +271,7 @@ impl<T: Sub<T, T>> Sub<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> {
/// A 2D point in flow-relative dimensions
-#[deriving(PartialEq, Encodable, Eq, Clone, Copy)]
+#[derive(PartialEq, RustcEncodable, Eq, Clone, Copy)]
pub struct LogicalPoint<T> {
pub i: T, /// inline-axis coordinate
pub b: T, /// block-axis coordinate
@@ -275,7 +280,7 @@ pub struct LogicalPoint<T> {
impl<T: Show> Show for LogicalPoint<T> {
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
- write!(formatter, "LogicalPoint({} (i{}, b{}))",
+ write!(formatter, "LogicalPoint({:?} (i{:?}, b{:?}))",
self.debug_writing_mode, self.i, self.b)
}
}
@@ -303,7 +308,7 @@ impl<T: Copy> LogicalPoint<T> {
}
}
-impl<T: Copy + Sub<T, T>> LogicalPoint<T> {
+impl<T: Copy + Sub<T, Output=T>> LogicalPoint<T> {
#[inline]
pub fn from_physical(mode: WritingMode, point: Point2D<T>, container_size: Size2D<T>)
-> LogicalPoint<T> {
@@ -391,7 +396,7 @@ impl<T: Copy + Sub<T, T>> LogicalPoint<T> {
}
}
-impl<T: Add<T,T>> LogicalPoint<T> {
+impl<T: Copy + Add<T, Output=T>> LogicalPoint<T> {
/// This doesn’t really makes sense,
/// but happens when dealing with multiple origins.
#[inline]
@@ -405,9 +410,11 @@ impl<T: Add<T,T>> LogicalPoint<T> {
}
}
-impl<T: Add<T,T>> Add<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> {
+impl<T: Copy + Add<T,Output=T>> Add<LogicalSize<T>> for LogicalPoint<T> {
+ type Output = LogicalPoint<T>;
+
#[inline]
- fn add(&self, other: &LogicalSize<T>) -> LogicalPoint<T> {
+ fn add(self, other: LogicalSize<T>) -> LogicalPoint<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
LogicalPoint {
debug_writing_mode: self.debug_writing_mode,
@@ -417,9 +424,11 @@ impl<T: Add<T,T>> Add<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> {
}
}
-impl<T: Sub<T,T>> Sub<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> {
+impl<T: Copy + Sub<T,Output=T>> Sub<LogicalSize<T>> for LogicalPoint<T> {
+ type Output = LogicalPoint<T>;
+
#[inline]
- fn sub(&self, other: &LogicalSize<T>) -> LogicalPoint<T> {
+ fn sub(self, other: LogicalSize<T>) -> LogicalPoint<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
LogicalPoint {
debug_writing_mode: self.debug_writing_mode,
@@ -434,7 +443,7 @@ impl<T: Sub<T,T>> Sub<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> {
/// Represents the four sides of the margins, borders, or padding of a CSS box,
/// or a combination of those.
/// A positive "margin" can be added to a rectangle to obtain a bigger rectangle.
-#[deriving(Encodable, PartialEq, Eq, Clone, Copy)]
+#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)]
pub struct LogicalMargin<T> {
pub block_start: T,
pub inline_end: T,
@@ -446,7 +455,7 @@ pub struct LogicalMargin<T> {
impl<T: Show> Show for LogicalMargin<T> {
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
write!(formatter,
- "LogicalMargin({}, inline: {}..{} block: {}..{})",
+ "LogicalMargin({:?}, inline: {:?}..{:?} block: {:?}..{:?})",
self.debug_writing_mode,
self.inline_start,
self.inline_end,
@@ -656,7 +665,7 @@ impl<T: PartialEq + Zero> LogicalMargin<T> {
}
}
-impl<T: Add<T, T>> LogicalMargin<T> {
+impl<T: Copy + Add<T, Output=T>> LogicalMargin<T> {
#[inline]
pub fn inline_start_end(&self) -> T {
self.inline_start + self.inline_end
@@ -688,9 +697,11 @@ impl<T: Add<T, T>> LogicalMargin<T> {
}
}
-impl<T: Add<T, T>> Add<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T> {
+impl<T: Add<T, Output=T>> Add for LogicalMargin<T> {
+ type Output = LogicalMargin<T>;
+
#[inline]
- fn add(&self, other: &LogicalMargin<T>) -> LogicalMargin<T> {
+ fn add(self, other: LogicalMargin<T>) -> LogicalMargin<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
LogicalMargin {
debug_writing_mode: self.debug_writing_mode,
@@ -702,9 +713,11 @@ impl<T: Add<T, T>> Add<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T>
}
}
-impl<T: Sub<T, T>> Sub<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T> {
+impl<T: Sub<T, Output=T>> Sub for LogicalMargin<T> {
+ type Output = LogicalMargin<T>;
+
#[inline]
- fn sub(&self, other: &LogicalMargin<T>) -> LogicalMargin<T> {
+ fn sub(self, other: LogicalMargin<T>) -> LogicalMargin<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
LogicalMargin {
debug_writing_mode: self.debug_writing_mode,
@@ -718,7 +731,7 @@ impl<T: Sub<T, T>> Sub<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T>
/// A rectangle in flow-relative dimensions
-#[deriving(Encodable, PartialEq, Eq, Clone, Copy)]
+#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)]
pub struct LogicalRect<T> {
pub start: LogicalPoint<T>,
pub size: LogicalSize<T>,
@@ -728,7 +741,7 @@ pub struct LogicalRect<T> {
impl<T: Show> Show for LogicalRect<T> {
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
write!(formatter,
- "LogicalRect({}, i{}×b{}, @ (i{},b{}))",
+ "LogicalRect({:?}, i{:?}×b{:?}, @ (i{:?},b{:?}))",
self.debug_writing_mode,
self.size.inline,
self.size.block,
@@ -772,7 +785,7 @@ impl<T: Copy> LogicalRect<T> {
}
}
-impl<T: Copy + Add<T, T> + Sub<T, T>> LogicalRect<T> {
+impl<T: Copy + Add<T, Output=T> + Sub<T, Output=T>> LogicalRect<T> {
#[inline]
pub fn from_physical(mode: WritingMode, rect: Rect<T>, container_size: Size2D<T>)
-> LogicalRect<T> {
@@ -881,7 +894,7 @@ impl<T: Copy + Add<T, T> + Sub<T, T>> LogicalRect<T> {
}
}
-impl<T: Copy + Ord + Add<T, T> + Sub<T, T>> LogicalRect<T> {
+impl<T: Copy + Ord + Add<T, Output=T> + Sub<T, Output=T>> LogicalRect<T> {
#[inline]
pub fn union(&self, other: &LogicalRect<T>) -> LogicalRect<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
@@ -904,9 +917,11 @@ impl<T: Copy + Ord + Add<T, T> + Sub<T, T>> LogicalRect<T> {
}
}
-impl<T: Add<T, T> + Sub<T, T>> Add<LogicalMargin<T>, LogicalRect<T>> for LogicalRect<T> {
+impl<T: Copy + Add<T, Output=T> + Sub<T, Output=T>> Add<LogicalMargin<T>> for LogicalRect<T> {
+ type Output = LogicalRect<T>;
+
#[inline]
- fn add(&self, other: &LogicalMargin<T>) -> LogicalRect<T> {
+ fn add(self, other: LogicalMargin<T>) -> LogicalRect<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
LogicalRect {
start: LogicalPoint {
@@ -927,9 +942,11 @@ impl<T: Add<T, T> + Sub<T, T>> Add<LogicalMargin<T>, LogicalRect<T>> for Logical
}
-impl<T: Add<T, T> + Sub<T, T>> Sub<LogicalMargin<T>, LogicalRect<T>> for LogicalRect<T> {
+impl<T: Copy + Add<T, Output=T> + Sub<T, Output=T>> Sub<LogicalMargin<T>> for LogicalRect<T> {
+ type Output = LogicalRect<T>;
+
#[inline]
- fn sub(&self, other: &LogicalMargin<T>) -> LogicalRect<T> {
+ fn sub(self, other: LogicalMargin<T>) -> LogicalRect<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
LogicalRect {
start: LogicalPoint {
@@ -950,7 +967,7 @@ impl<T: Add<T, T> + Sub<T, T>> Sub<LogicalMargin<T>, LogicalRect<T>> for Logical
}
#[cfg(test)]
-fn modes() -> [WritingMode, ..10] {
+fn modes() -> [WritingMode; 10] {
[
WritingMode::empty(),
FLAG_VERTICAL,
diff --git a/components/util/memory.rs b/components/util/memory.rs
index 0c1d1dac3b1..5e3033e2aa5 100644
--- a/components/util/memory.rs
+++ b/components/util/memory.rs
@@ -5,13 +5,17 @@
//! Memory profiling functions.
use libc::{c_char,c_int,c_void,size_t};
+use std::borrow::ToOwned;
+use std::ffi::CString;
use std::io::timer::sleep;
#[cfg(target_os="linux")]
use std::io::File;
+use std::mem;
use std::mem::size_of;
#[cfg(target_os="linux")]
use std::os::page_size;
use std::ptr::null_mut;
+use std::sync::mpsc::{Sender, channel, Receiver};
use std::time::duration::Duration;
use task::spawn_named;
#[cfg(target_os="macos")]
@@ -44,16 +48,16 @@ impl MemoryProfiler {
Some(period) => {
let period = Duration::milliseconds((period * 1000f64) as i64);
let chan = chan.clone();
- spawn_named("Memory profiler timer", proc() {
+ spawn_named("Memory profiler timer".to_owned(), move || {
loop {
sleep(period);
- if chan.send_opt(MemoryProfilerMsg::Print).is_err() {
+ if chan.send(MemoryProfilerMsg::Print).is_err() {
break;
}
}
});
// Spawn the memory profiler.
- spawn_named("Memory profiler", proc() {
+ spawn_named("Memory profiler".to_owned(), move || {
let memory_profiler = MemoryProfiler::new(port);
memory_profiler.start();
});
@@ -61,9 +65,9 @@ impl MemoryProfiler {
None => {
// No-op to handle messages when the memory profiler is
// inactive.
- spawn_named("Memory profiler", proc() {
+ spawn_named("Memory profiler".to_owned(), move || {
loop {
- match port.recv_opt() {
+ match port.recv() {
Err(_) | Ok(MemoryProfilerMsg::Exit) => break,
_ => {}
}
@@ -83,7 +87,7 @@ impl MemoryProfiler {
pub fn start(&self) {
loop {
- match self.port.recv_opt() {
+ match self.port.recv() {
Ok(msg) => {
if !self.handle_msg(msg) {
break
@@ -150,12 +154,13 @@ extern {
fn get_jemalloc_stat(name: &'static str) -> Option<u64> {
let mut old: size_t = 0;
- let c_name = name.to_c_str();
+ let c_name = CString::from_slice(name.as_bytes());
let oldp = &mut old as *mut _ as *mut c_void;
let mut oldlen = size_of::<size_t>() as size_t;
let rv: c_int;
unsafe {
- rv = je_mallctl(c_name.into_inner(), oldp, &mut oldlen, null_mut(), 0);
+ rv = je_mallctl(c_name.as_ptr(), oldp, &mut oldlen, null_mut(), 0);
+ mem::forget(c_name); // XXX correct?
}
if rv == 0 { Some(old as u64) } else { None }
}
@@ -163,7 +168,7 @@ fn get_jemalloc_stat(name: &'static str) -> Option<u64> {
// Like std::macros::try!, but for Option<>.
macro_rules! option_try(
($e:expr) => (match $e { Some(e) => e, None => return None })
-)
+);
#[cfg(target_os="linux")]
fn get_proc_self_statm_field(field: uint) -> Option<u64> {
@@ -171,7 +176,7 @@ fn get_proc_self_statm_field(field: uint) -> Option<u64> {
match f.read_to_string() {
Ok(contents) => {
let s = option_try!(contents.as_slice().words().nth(field));
- let npages: u64 = option_try!(from_str(s));
+ let npages: u64 = option_try!(s.parse());
Some(npages * (page_size() as u64))
}
Err(_) => None
diff --git a/components/util/opts.rs b/components/util/opts.rs
index 8ee877bd9fd..ae19723b975 100644
--- a/components/util/opts.rs
+++ b/components/util/opts.rs
@@ -19,14 +19,8 @@ use std::os;
use std::ptr;
use std::rt;
-#[deriving(Clone, Copy)]
-pub enum RenderApi {
- OpenGL,
- Mesa,
-}
-
/// Global flags for Servo, currently set on the command line.
-#[deriving(Clone)]
+#[derive(Clone)]
pub struct Opts {
/// The initial URLs to load.
pub urls: Vec<String>,
@@ -112,8 +106,6 @@ pub struct Opts {
/// Whether to show an error when display list geometry escapes flow overflow regions.
pub validate_display_list_geometry: bool,
- pub render_api: RenderApi,
-
/// A specific path to find required resources (such as user-agent.css).
pub resources_path: Option<String>,
}
@@ -182,7 +174,6 @@ pub fn default_opts() -> Opts {
dump_flow_tree: false,
validate_display_list_geometry: false,
profile_tasks: false,
- render_api: RenderApi::OpenGL,
resources_path: None,
}
}
@@ -250,31 +241,31 @@ pub fn from_cmdline_args(args: &[String]) -> bool {
};
let tile_size: uint = match opt_match.opt_str("s") {
- Some(tile_size_str) => from_str(tile_size_str.as_slice()).unwrap(),
+ Some(tile_size_str) => tile_size_str.parse().unwrap(),
None => 512,
};
let device_pixels_per_px = opt_match.opt_str("device-pixel-ratio").map(|dppx_str|
- ScaleFactor(from_str(dppx_str.as_slice()).unwrap())
+ ScaleFactor(dppx_str.parse().unwrap())
);
let mut n_paint_threads: uint = match opt_match.opt_str("t") {
- Some(n_paint_threads_str) => from_str(n_paint_threads_str.as_slice()).unwrap(),
+ Some(n_paint_threads_str) => n_paint_threads_str.parse().unwrap(),
None => 1, // FIXME: Number of cores.
};
// If only the flag is present, default to a 5 second period for both profilers.
let time_profiler_period = opt_match.opt_default("p", "5").map(|period| {
- from_str(period.as_slice()).unwrap()
+ period.parse().unwrap()
});
let memory_profiler_period = opt_match.opt_default("m", "5").map(|period| {
- from_str(period.as_slice()).unwrap()
+ period.parse().unwrap()
});
let gpu_painting = !FORCE_CPU_PAINTING && opt_match.opt_present("g");
let mut layout_threads: uint = match opt_match.opt_str("y") {
- Some(layout_threads_str) => from_str(layout_threads_str.as_slice()).unwrap(),
+ Some(layout_threads_str) => layout_threads_str.parse().unwrap(),
None => cmp::max(rt::default_sched_threads() * 3 / 4, 1),
};
@@ -289,12 +280,12 @@ pub fn from_cmdline_args(args: &[String]) -> bool {
}
let devtools_port = opt_match.opt_default("devtools", "6000").map(|port| {
- from_str(port.as_slice()).unwrap()
+ port.parse().unwrap()
});
let initial_window_size = match opt_match.opt_str("resolution") {
Some(res_string) => {
- let res: Vec<uint> = res_string.as_slice().split('x').map(|r| from_str(r).unwrap()).collect();
+ let res: Vec<uint> = res_string.split('x').map(|r| r.parse().unwrap()).collect();
TypedSize2D(res[0], res[1])
}
None => {
@@ -302,15 +293,6 @@ pub fn from_cmdline_args(args: &[String]) -> bool {
}
};
- let render_api = match opt_match.opt_str("r").unwrap_or("gl".into_string()).as_slice() {
- "mesa" => RenderApi::Mesa,
- "gl" => RenderApi::OpenGL,
- _ => {
- args_fail("Unknown render api specified");
- return false;
- }
- };
-
let opts = Opts {
urls: urls,
n_paint_threads: n_paint_threads,
@@ -336,7 +318,6 @@ pub fn from_cmdline_args(args: &[String]) -> bool {
enable_text_antialiasing: !debug_options.contains(&"disable-text-aa"),
dump_flow_tree: debug_options.contains(&"dump-flow-tree"),
validate_display_list_geometry: debug_options.contains(&"validate-display-list-geometry"),
- render_api: render_api,
resources_path: opt_match.opt_str("resources-path"),
};
diff --git a/components/util/persistent_list.rs b/components/util/persistent_list.rs
index 458c4c96a2a..f20edff3d38 100644
--- a/components/util/persistent_list.rs
+++ b/components/util/persistent_list.rs
@@ -74,7 +74,9 @@ pub struct PersistentListIterator<'a,T> where T: 'a + Send + Sync {
entry: Option<&'a PersistentListEntry<T>>,
}
-impl<'a,T> Iterator<&'a T> for PersistentListIterator<'a,T> where T: Send + Sync {
+impl<'a,T> Iterator for PersistentListIterator<'a,T> where T: Send + Sync {
+ type Item = &'a T;
+
#[inline]
fn next(&mut self) -> Option<&'a T> {
let entry = match self.entry {
diff --git a/components/util/range.rs b/components/util/range.rs
index ef6e7e0ff47..fbf14f38400 100644
--- a/components/util/range.rs
+++ b/components/util/range.rs
@@ -26,7 +26,7 @@ impl RangeIndex<int> for int {
#[macro_export]
macro_rules! int_range_index {
($(#[$attr:meta])* struct $Self:ident($T:ty)) => (
- #[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Show, Copy)]
+ #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Show, Copy)]
$(#[$attr])*
pub struct $Self(pub $T);
@@ -74,40 +74,42 @@ macro_rules! int_range_index {
}
}
- impl Add<$Self, $Self> for $Self {
+ impl Add<$Self> for $Self {
+ type Output = $Self;
+
#[inline]
- fn add(&self, other: &$Self) -> $Self {
+ fn add(self, other: $Self) -> $Self {
$Self(self.get() + other.get())
}
}
- impl Sub<$Self, $Self> for $Self {
+ impl Sub<$Self> for $Self {
+ type Output = $Self;
+
#[inline]
- fn sub(&self, other: &$Self) -> $Self {
+ fn sub(self, other: $Self) -> $Self {
$Self(self.get() - other.get())
}
}
- impl Mul<$Self, $Self> for $Self {
+ impl Mul<$Self> for $Self {
+ type Output = $Self;
+
#[inline]
- fn mul(&self, other: &$Self) -> $Self {
+ fn mul(self, other: $Self) -> $Self {
$Self(self.get() * other.get())
}
}
- impl Neg<$Self> for $Self {
+ impl Neg for $Self {
+ type Output = $Self;
+
#[inline]
- fn neg(&self) -> $Self {
+ fn neg(self) -> $Self {
$Self(-self.get())
}
}
- impl ::std::num::One for $Self {
- fn one() -> $Self {
- $Self(1)
- }
- }
-
impl ToPrimitive for $Self {
fn to_i64(&self) -> Option<i64> {
Some(self.get() as i64)
@@ -124,66 +126,75 @@ macro_rules! int_range_index {
}
}
- impl Div<$Self, $Self> for $Self {
- fn div(&self, other: &$Self) -> $Self {
+ impl Div<$Self> for $Self {
+ type Output = $Self;
+ fn div(self, other: $Self) -> $Self {
$Self(self.get() / other.get())
}
}
- impl Rem<$Self, $Self> for $Self {
- fn rem(&self, other: &$Self) -> $Self {
+ impl Rem<$Self> for $Self {
+ type Output = $Self;
+ fn rem(self, other: $Self) -> $Self {
$Self(self.get() % other.get())
}
}
- impl Not<$Self> for $Self {
- fn not(&self) -> $Self {
+ impl Not for $Self {
+ type Output = $Self;
+ fn not(self) -> $Self {
$Self(!self.get())
}
}
- impl BitAnd<$Self, $Self> for $Self {
- fn bitand(&self, other: &$Self) -> $Self {
+ impl BitAnd<$Self> for $Self {
+ type Output = $Self;
+ fn bitand(self, other: $Self) -> $Self {
$Self(self.get() & other.get())
}
}
- impl BitOr<$Self, $Self> for $Self {
- fn bitor(&self, other: &$Self) -> $Self {
+ impl BitOr<$Self> for $Self {
+ type Output = $Self;
+ fn bitor(self, other: $Self) -> $Self {
$Self(self.get() | other.get())
}
}
- impl BitXor<$Self, $Self> for $Self {
- fn bitxor(&self, other: &$Self) -> $Self {
+ impl BitXor<$Self> for $Self {
+ type Output = $Self;
+ fn bitxor(self, other: $Self) -> $Self {
$Self(self.get() ^ other.get())
}
}
- impl Shl<uint, $Self> for $Self {
- fn shl(&self, n: &uint) -> $Self {
- $Self(self.get() << *n)
+ impl Shl<uint> for $Self {
+ type Output = $Self;
+ fn shl(self, n: uint) -> $Self {
+ $Self(self.get() << n)
}
}
- impl Shr<uint, $Self> for $Self {
- fn shr(&self, n: &uint) -> $Self {
- $Self(self.get() >> *n)
+ impl Shr<uint> for $Self {
+ type Output = $Self;
+ fn shr(self, n: uint) -> $Self {
+ $Self(self.get() >> n)
}
}
)
}
/// A range of indices
-#[deriving(Clone, Encodable, Copy)]
+#[derive(Clone, RustcEncodable, Copy)]
pub struct Range<I> {
begin: I,
length: I,
}
+#[old_impl_check]
impl<I: RangeIndex<T>, T> fmt::Show for Range<I> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "[{} .. {})", self.begin(), self.end())
+ write!(f, "[{:?} .. {:?})", self.begin(), self.end())
}
}
@@ -196,7 +207,9 @@ pub fn each_index<T: Int, I: RangeIndex<T>>(start: I, stop: I) -> EachIndex<T, I
EachIndex { it: iter::range(start.get(), stop.get()) }
}
-impl<T: Int, I: RangeIndex<T>> Iterator<I> for EachIndex<T, I> {
+impl<T: Int, I: RangeIndex<T>> Iterator for EachIndex<T, I> {
+ type Item = I;
+
#[inline]
fn next(&mut self) -> Option<I> {
self.it.next().map(|i| RangeIndex::new(i))
@@ -208,6 +221,7 @@ impl<T: Int, I: RangeIndex<T>> Iterator<I> for EachIndex<T, I> {
}
}
+#[old_impl_check]
impl<I: RangeIndex<T>, T> Range<I> {
/// Create a new range from beginning and length offsets. This could be
/// denoted as `[begin, begin + length)`.
@@ -345,6 +359,7 @@ impl<I: RangeIndex<T>, T> Range<I> {
}
/// Methods for `Range`s with indices based on integer values
+#[old_impl_check]
impl<T: Int, I: RangeIndex<T>> Range<I> {
/// Returns an iterater that increments over `[begin, end)`.
#[inline]
@@ -363,8 +378,9 @@ impl<T: Int, I: RangeIndex<T>> Range<I> {
&& self.length() <= len
},
None => {
- debug!("Range<T>::is_valid_for_string: string length (len={}) is longer than the \
- max value for the range index (max={})", s_len,
+ debug!("Range<T>::is_valid_for_string: string length \
+ (len={:?}) is longer than the max value for the range \
+ index (max={:?})", s_len,
{
let max: T = Int::max_value();
let val: I = RangeIndex::new(max);
diff --git a/components/util/rtinstrument.rs b/components/util/rtinstrument.rs
deleted file mode 100644
index ea9a5ecef32..00000000000
--- a/components/util/rtinstrument.rs
+++ /dev/null
@@ -1,197 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-use opts;
-use std::any::Any;
-#[cfg(not(test))]
-use std::io::File;
-//use std::mem;
-//use std::raw;
-use std::rt::Runtime;
-use std::rt::local::Local;
-//use std::rt::rtio;
-use std::rt::task::{Task, TaskOpts, BlockedTask};
-use std_time;
-use std::sync::Mutex;
-#[cfg(not(test))]
-use serialize::json;
-
-#[deriving(Encodable)]
-pub enum Event {
- Spawn,
- Schedule,
- Unschedule,
- Death,
-}
-
-#[deriving(Encodable)]
-pub struct Message {
- timestamp: u64,
- event: Event,
-}
-
-#[deriving(Encodable)]
-pub struct TaskStats {
- pub name: String,
- pub messages: Vec<Message>,
- pub task_id: uint,
-}
-
-struct InstrumentedRuntime {
- inner: Option<Box<Runtime + Send>>,
- messages: Vec<Message>,
-}
-
-#[deriving(Encodable)]
-pub struct GlobalState {
- task_stats: Vec<TaskStats>,
-}
-
-#[cfg(not(test))]
-pub fn teardown() {
- if opts::get().profile_tasks {
- let state = GLOBAL_STATE.lock();
- let result = json::encode(&*state);
- let path = Path::new("thread_trace.json");
- let mut file = File::create(&path).unwrap();
- file.write_str(result.as_slice()).unwrap();
- }
-}
-
-impl GlobalState {
- fn new() -> GlobalState {
- GlobalState {
- task_stats: vec!(),
- }
- }
-}
-
-lazy_static! {
- pub static ref GLOBAL_STATE: Mutex<GlobalState> = Mutex::new(GlobalState::new());
-}
-
-/// Instrument all code run inside the specific block, returning a vector of all
-/// messages which occurred.
-pub fn instrument(f: proc()) {
- if opts::get().profile_tasks {
- install();
- f();
- let rt = uninstall();
- let task_id = rt.task_id();
- let name = {
- let task = Local::borrow(None::<Task>);
- match task.name {
- Some(ref name) => name.to_string(),
- None => "unknown".into_string(),
- }
- };
- let stats = TaskStats {
- name: name,
- messages: rt.messages,
- task_id: task_id,
- };
- let mut state = GLOBAL_STATE.lock();
- state.task_stats.push(stats);
- } else {
- f();
- }
-}
-
-/// Installs an instrumented runtime which will append to the given vector of
-/// messages.
-///
-/// The instrumented runtime is installed into the current task.
-fn install() {
- let mut task = Local::borrow(None::<Task>);
- let rt = task.take_runtime();
- let mut new_rt = box InstrumentedRuntime {
- inner: Some(rt),
- messages: vec!(),
- };
- new_rt.log(Event::Spawn);
- task.put_runtime(new_rt);
-}
-
-/// Uninstalls the runtime from the current task, returning the instrumented
-/// runtime.
-fn uninstall() -> InstrumentedRuntime {
- let mut task = Local::borrow(None::<Task>);
- let mut rt = task.maybe_take_runtime::<InstrumentedRuntime>().unwrap();
- rt.log(Event::Death);
- task.put_runtime(rt.inner.take().unwrap());
- *rt
-}
-
-impl InstrumentedRuntime {
- /// Puts this runtime back into the local task
- fn put(mut self: Box<InstrumentedRuntime>, event: Option<Event>) {
- assert!(self.inner.is_none());
-
- let mut task: Box<Task> = Local::take();
- let rt = task.take_runtime();
- self.inner = Some(rt);
- match event {
- Some(event) => self.log(event),
- None => {}
- }
- task.put_runtime(self);
- Local::put(task);
- }
-
- /// Logs a message into this runtime
- fn log(&mut self, event: Event) {
- self.messages.push(Message {
- timestamp: std_time::precise_time_ns(),
- event: event,
- });
- }
-
- fn task_id(&self) -> uint { self as *const _ as uint }
-}
-
-impl Runtime for InstrumentedRuntime {
- fn stack_guard(&self) -> Option<uint> {
- self.inner.as_ref().unwrap().stack_guard()
- }
-
- fn yield_now(mut self: Box<InstrumentedRuntime>, cur_task: Box<Task>) {
- self.inner.take().unwrap().yield_now(cur_task);
- self.put(None)
- }
-
- fn maybe_yield(mut self: Box<InstrumentedRuntime>, cur_task: Box<Task>) {
- self.inner.take().unwrap().maybe_yield(cur_task);
- self.put(None)
- }
-
- fn deschedule(mut self: Box<InstrumentedRuntime>, times: uint, cur_task: Box<Task>,
- f: |BlockedTask| -> Result<(), BlockedTask>) {
- self.log(Event::Unschedule);
- self.inner.take().unwrap().deschedule(times, cur_task, f);
- self.put(Some(Event::Schedule));
- }
-
- fn reawaken(mut self: Box<InstrumentedRuntime>, to_wake: Box<Task>) {
- self.inner.take().unwrap().reawaken(to_wake);
- self.put(None);
- }
-
- fn spawn_sibling(mut self: Box<InstrumentedRuntime>,
- cur_task: Box<Task>,
- opts: TaskOpts,
- f: proc():Send) {
- // Be sure to install an instrumented runtime for the spawned sibling by
- // specifying a new runtime.
- self.inner.take().unwrap().spawn_sibling(cur_task, opts, proc() {
- install();
- f();
- drop(uninstall());
- });
- self.put(None)
- }
-
- fn stack_bounds(&self) -> (uint, uint) { self.inner.as_ref().unwrap().stack_bounds() }
- fn can_block(&self) -> bool { self.inner.as_ref().unwrap().can_block() }
- fn wrap(self: Box<InstrumentedRuntime>) -> Box<Any+'static> { self as Box<Any> }
-}
diff --git a/components/util/smallvec.rs b/components/util/smallvec.rs
index e92d3d3eeba..efd1bfc7f35 100644
--- a/components/util/smallvec.rs
+++ b/components/util/smallvec.rs
@@ -9,7 +9,8 @@ use std::mem::zeroed as i;
use std::cmp;
use std::fmt;
use std::intrinsics;
-use std::kinds::marker::ContravariantLifetime;
+use std::iter::FromIterator;
+use std::marker::ContravariantLifetime;
use std::mem;
use std::ptr;
use std::raw::Slice;
@@ -249,7 +250,9 @@ pub struct SmallVecIterator<'a,T> {
lifetime: ContravariantLifetime<'a>
}
-impl<'a,T> Iterator<&'a T> for SmallVecIterator<'a,T> {
+impl<'a,T> Iterator for SmallVecIterator<'a,T> {
+ type Item = &'a T;
+
#[inline]
fn next(&mut self) -> Option<&'a T> {
unsafe {
@@ -273,7 +276,9 @@ pub struct SmallVecMutIterator<'a,T> {
lifetime: ContravariantLifetime<'a>,
}
-impl<'a,T> Iterator<&'a mut T> for SmallVecMutIterator<'a,T> {
+impl<'a,T> Iterator for SmallVecMutIterator<'a,T> {
+ type Item = &'a mut T;
+
#[inline]
fn next(&mut self) -> Option<&'a mut T> {
unsafe {
@@ -298,7 +303,9 @@ pub struct SmallVecMoveIterator<'a,T> {
lifetime: ContravariantLifetime<'a>,
}
-impl<'a, T: 'a> Iterator<T> for SmallVecMoveIterator<'a,T> {
+impl<'a, T: 'a> Iterator for SmallVecMoveIterator<'a,T> {
+ type Item = T;
+
#[inline]
fn next(&mut self) -> Option<T> {
unsafe {
@@ -341,7 +348,7 @@ macro_rules! def_small_vector(
len: uint,
cap: uint,
ptr: *const T,
- data: [T, ..$size],
+ data: [T; $size],
}
impl<T> SmallVecPrivate<T> for $name<T> {
@@ -403,7 +410,7 @@ macro_rules! def_small_vector(
}
impl<T> FromIterator<T> for $name<T> {
- fn from_iter<I: Iterator<T>>(mut iter: I) -> $name<T> {
+ fn from_iter<I: Iterator<Item=T>>(mut iter: I) -> $name<T> {
let mut v = $name::new();
let (lower_size_bound, _) = iter.size_hint();
@@ -421,7 +428,7 @@ macro_rules! def_small_vector(
}
impl<T> $name<T> {
- pub fn extend<I: Iterator<T>>(&mut self, mut iter: I) {
+ pub fn extend<I: Iterator<Item=T>>(&mut self, mut iter: I) {
let (lower_size_bound, _) = iter.size_hint();
let target_len = self.len() + lower_size_bound;
@@ -438,7 +445,7 @@ macro_rules! def_small_vector(
impl<T: fmt::Show> fmt::Show for $name<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}", self.as_slice())
+ write!(f, "{:?}", self.as_slice())
}
}
@@ -456,15 +463,15 @@ macro_rules! def_small_vector(
}
}
)
-)
+);
-def_small_vector!(SmallVec1, 1)
-def_small_vector!(SmallVec2, 2)
-def_small_vector!(SmallVec4, 4)
-def_small_vector!(SmallVec8, 8)
-def_small_vector!(SmallVec16, 16)
-def_small_vector!(SmallVec24, 24)
-def_small_vector!(SmallVec32, 32)
+def_small_vector!(SmallVec1, 1);
+def_small_vector!(SmallVec2, 2);
+def_small_vector!(SmallVec4, 4);
+def_small_vector!(SmallVec8, 8);
+def_small_vector!(SmallVec16, 16);
+def_small_vector!(SmallVec24, 24);
+def_small_vector!(SmallVec32, 32);
macro_rules! def_small_vector_drop_impl(
($name:ident, $size:expr) => (
@@ -488,15 +495,15 @@ macro_rules! def_small_vector_drop_impl(
}
}
)
-)
+);
-def_small_vector_drop_impl!(SmallVec1, 1)
-def_small_vector_drop_impl!(SmallVec2, 2)
-def_small_vector_drop_impl!(SmallVec4, 4)
-def_small_vector_drop_impl!(SmallVec8, 8)
-def_small_vector_drop_impl!(SmallVec16, 16)
-def_small_vector_drop_impl!(SmallVec24, 24)
-def_small_vector_drop_impl!(SmallVec32, 32)
+def_small_vector_drop_impl!(SmallVec1, 1);
+def_small_vector_drop_impl!(SmallVec2, 2);
+def_small_vector_drop_impl!(SmallVec4, 4);
+def_small_vector_drop_impl!(SmallVec8, 8);
+def_small_vector_drop_impl!(SmallVec16, 16);
+def_small_vector_drop_impl!(SmallVec24, 24);
+def_small_vector_drop_impl!(SmallVec32, 32);
macro_rules! def_small_vector_clone_impl(
($name:ident) => (
@@ -510,68 +517,69 @@ macro_rules! def_small_vector_clone_impl(
}
}
)
-)
+);
-def_small_vector_clone_impl!(SmallVec1)
-def_small_vector_clone_impl!(SmallVec2)
-def_small_vector_clone_impl!(SmallVec4)
-def_small_vector_clone_impl!(SmallVec8)
-def_small_vector_clone_impl!(SmallVec16)
-def_small_vector_clone_impl!(SmallVec24)
-def_small_vector_clone_impl!(SmallVec32)
+def_small_vector_clone_impl!(SmallVec1);
+def_small_vector_clone_impl!(SmallVec2);
+def_small_vector_clone_impl!(SmallVec4);
+def_small_vector_clone_impl!(SmallVec8);
+def_small_vector_clone_impl!(SmallVec16);
+def_small_vector_clone_impl!(SmallVec24);
+def_small_vector_clone_impl!(SmallVec32);
#[cfg(test)]
pub mod tests {
use smallvec::{SmallVec, SmallVec2, SmallVec16};
+ use std::borrow::ToOwned;
// We heap allocate all these strings so that double frees will show up under valgrind.
#[test]
pub fn test_inline() {
let mut v = SmallVec16::new();
- v.push("hello".into_string());
- v.push("there".into_string());
+ v.push("hello".to_owned());
+ v.push("there".to_owned());
assert_eq!(v.as_slice(), vec![
- "hello".into_string(),
- "there".into_string(),
+ "hello".to_owned(),
+ "there".to_owned(),
].as_slice());
}
#[test]
pub fn test_spill() {
let mut v = SmallVec2::new();
- v.push("hello".into_string());
- v.push("there".into_string());
- v.push("burma".into_string());
- v.push("shave".into_string());
+ v.push("hello".to_owned());
+ v.push("there".to_owned());
+ v.push("burma".to_owned());
+ v.push("shave".to_owned());
assert_eq!(v.as_slice(), vec![
- "hello".into_string(),
- "there".into_string(),
- "burma".into_string(),
- "shave".into_string(),
+ "hello".to_owned(),
+ "there".to_owned(),
+ "burma".to_owned(),
+ "shave".to_owned(),
].as_slice());
}
#[test]
pub fn test_double_spill() {
let mut v = SmallVec2::new();
- v.push("hello".into_string());
- v.push("there".into_string());
- v.push("burma".into_string());
- v.push("shave".into_string());
- v.push("hello".into_string());
- v.push("there".into_string());
- v.push("burma".into_string());
- v.push("shave".into_string());
+ v.push("hello".to_owned());
+ v.push("there".to_owned());
+ v.push("burma".to_owned());
+ v.push("shave".to_owned());
+ v.push("hello".to_owned());
+ v.push("there".to_owned());
+ v.push("burma".to_owned());
+ v.push("shave".to_owned());
assert_eq!(v.as_slice(), vec![
- "hello".into_string(),
- "there".into_string(),
- "burma".into_string(),
- "shave".into_string(),
- "hello".into_string(),
- "there".into_string(),
- "burma".into_string(),
- "shave".into_string(),
+ "hello".to_owned(),
+ "there".to_owned(),
+ "burma".to_owned(),
+ "shave".to_owned(),
+ "hello".to_owned(),
+ "there".to_owned(),
+ "burma".to_owned(),
+ "shave".to_owned(),
].as_slice());
}
}
diff --git a/components/util/sort.rs b/components/util/sort.rs
index 73a244f713f..ce7ab4d86c9 100644
--- a/components/util/sort.rs
+++ b/components/util/sort.rs
@@ -4,6 +4,8 @@
//! In-place sorting.
+use std::cmp::Ordering;
+
fn quicksort_helper<T>(arr: &mut [T], left: int, right: int, compare: fn(&T, &T) -> Ordering) {
if right <= left {
return
@@ -17,11 +19,11 @@ fn quicksort_helper<T>(arr: &mut [T], left: int, right: int, compare: fn(&T, &T)
let v: *mut T = &mut arr[right as uint];
loop {
i += 1;
- while compare(&arr[i as uint], &*v) == Less {
+ while compare(&arr[i as uint], &*v) == Ordering::Less {
i += 1
}
j -= 1;
- while compare(&*v, &arr[j as uint]) == Less {
+ while compare(&*v, &arr[j as uint]) == Ordering::Less {
if j == left {
break
}
@@ -31,11 +33,11 @@ fn quicksort_helper<T>(arr: &mut [T], left: int, right: int, compare: fn(&T, &T)
break
}
arr.swap(i as uint, j as uint);
- if compare(&arr[i as uint], &*v) == Equal {
+ if compare(&arr[i as uint], &*v) == Ordering::Equal {
p += 1;
arr.swap(p as uint, i as uint)
}
- if compare(&*v, &arr[j as uint]) == Equal {
+ if compare(&*v, &arr[j as uint]) == Ordering::Equal {
q -= 1;
arr.swap(j as uint, q as uint)
}
@@ -79,6 +81,7 @@ pub fn quicksort_by<T>(arr: &mut [T], compare: fn(&T, &T) -> Ordering) {
#[cfg(test)]
pub mod test {
+ use std::cmp::Ordering;
use std::rand;
use std::rand::Rng;
@@ -86,7 +89,7 @@ pub mod test {
#[test]
pub fn random() {
- let mut rng = rand::task_rng();
+ let mut rng = rand::thread_rng();
for _ in range(0u32, 50000u32) {
let len: uint = rng.gen();
let mut v: Vec<int> = rng.gen_iter::<int>().take((len % 32) + 1).collect();
diff --git a/components/util/str.rs b/components/util/str.rs
index 4cf5a5cc3f4..e0642abdffe 100644
--- a/components/util/str.rs
+++ b/components/util/str.rs
@@ -4,23 +4,26 @@
use geometry::Au;
-use cssparser::{mod, RGBA, Color};
+use cssparser::{self, RGBA, Color};
+
+use libc::c_char;
use std::ascii::AsciiExt;
+use std::borrow::ToOwned;
+use std::ffi::c_str_to_bytes;
use std::iter::Filter;
-use std::num::Int;
-use std::str::{CharEq, CharSplits, FromStr};
-use unicode::char::UnicodeChar;
+use std::num::{Int, ToPrimitive};
+use std::str::{from_utf8, CharEq, FromStr, Split};
pub type DOMString = String;
pub type StaticCharVec = &'static [char];
pub type StaticStringVec = &'static [&'static str];
pub fn null_str_as_empty(s: &Option<DOMString>) -> DOMString {
- // We don't use map_default because it would allocate "".into_string() even
+ // We don't use map_default because it would allocate "".to_owned() even
// for Some.
match *s {
Some(ref s) => s.clone(),
- None => "".into_string()
+ None => "".to_owned()
}
}
@@ -64,15 +67,16 @@ pub static HTML_SPACE_CHARACTERS: StaticCharVec = &[
'\u{000d}',
];
-pub fn split_html_space_chars<'a>(s: &'a str)
- -> Filter<'a, &'a str, CharSplits<'a, StaticCharVec>> {
- s.split(HTML_SPACE_CHARACTERS).filter(|&split| !split.is_empty())
+pub fn split_html_space_chars<'a>(s: &'a str) ->
+ Filter<&'a str, Split<'a, StaticCharVec>, fn(&&str) -> bool> {
+ fn not_empty(&split: &&str) -> bool { !split.is_empty() }
+ s.split(HTML_SPACE_CHARACTERS).filter(not_empty as fn(&&str) -> bool)
}
/// Shared implementation to parse an integer according to
/// <http://www.whatwg.org/html/#rules-for-parsing-integers> or
/// <http://www.whatwg.org/html/#rules-for-parsing-non-negative-integers>.
-fn do_parse_integer<T: Iterator<char>>(input: T) -> Option<i64> {
+fn do_parse_integer<T: Iterator<Item=char>>(input: T) -> Option<i64> {
fn is_ascii_digit(c: &char) -> bool {
match *c {
'0'...'9' => true,
@@ -117,7 +121,7 @@ fn do_parse_integer<T: Iterator<char>>(input: T) -> Option<i64> {
/// Parse an integer according to
/// <http://www.whatwg.org/html/#rules-for-parsing-integers>.
-pub fn parse_integer<T: Iterator<char>>(input: T) -> Option<i32> {
+pub fn parse_integer<T: Iterator<Item=char>>(input: T) -> Option<i32> {
do_parse_integer(input).and_then(|result| {
result.to_i32()
})
@@ -125,13 +129,13 @@ pub fn parse_integer<T: Iterator<char>>(input: T) -> Option<i32> {
/// Parse an integer according to
/// <http://www.whatwg.org/html/#rules-for-parsing-non-negative-integers>.
-pub fn parse_unsigned_integer<T: Iterator<char>>(input: T) -> Option<u32> {
+pub fn parse_unsigned_integer<T: Iterator<Item=char>>(input: T) -> Option<u32> {
do_parse_integer(input).and_then(|result| {
result.to_u32()
})
}
-#[deriving(Copy)]
+#[derive(Copy)]
pub enum LengthOrPercentageOrAuto {
Auto,
Percentage(f64),
@@ -140,14 +144,14 @@ pub enum LengthOrPercentageOrAuto {
/// Parses a length per HTML5 § 2.4.4.4. If unparseable, `Auto` is returned.
pub fn parse_length(mut value: &str) -> LengthOrPercentageOrAuto {
- value = value.trim_left_chars(Whitespace);
+ value = value.trim_left_matches(Whitespace);
if value.len() == 0 {
return LengthOrPercentageOrAuto::Auto
}
if value.starts_with("+") {
value = value.slice_from(1)
}
- value = value.trim_left_chars('0');
+ value = value.trim_left_matches('0');
if value.len() == 0 {
return LengthOrPercentageOrAuto::Auto
}
@@ -196,7 +200,7 @@ pub fn parse_legacy_color(mut input: &str) -> Result<RGBA,()> {
}
// Step 3.
- input = input.trim_left_chars(Whitespace).trim_right_chars(Whitespace);
+ input = input.trim_left_matches(Whitespace).trim_right_matches(Whitespace);
// Step 4.
if input.eq_ignore_ascii_case("transparent") {
@@ -320,7 +324,7 @@ pub fn parse_legacy_color(mut input: &str) -> Result<RGBA,()> {
}
-#[deriving(Clone, Eq, PartialEq, Hash, Show)]
+#[derive(Clone, Eq, PartialEq, Hash, Show)]
pub struct LowercaseString {
inner: String,
}
@@ -339,3 +343,9 @@ impl Str for LowercaseString {
self.inner.as_slice()
}
}
+
+/// Creates a String from the given null-terminated buffer.
+/// Panics if the buffer does not contain UTF-8.
+pub unsafe fn c_str_to_string(s: *const c_char) -> String {
+ from_utf8(c_str_to_bytes(&s)).unwrap().to_owned()
+}
diff --git a/components/util/task.rs b/components/util/task.rs
index 2d07be08da3..2045d0c3e83 100644
--- a/components/util/task.rs
+++ b/components/util/task.rs
@@ -2,44 +2,50 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use std::task;
-use std::comm::Sender;
-use std::task::TaskBuilder;
-// use rtinstrument;
+use std::borrow::ToOwned;
use task_state;
+use std::thread;
+use std::sync::mpsc::Sender;
+use std::thread::Builder;
-pub fn spawn_named<S: IntoCow<'static, String, str>>(name: S, f: proc():Send) {
- let builder = task::TaskBuilder::new().named(name);
- builder.spawn(proc() {
- // rtinstrument::instrument(f);
- f();
+pub fn spawn_named<F>(name: String, f: F)
+ where F: FnOnce() + Send
+{
+ let builder = thread::Builder::new().name(name);
+ builder.spawn(move || {
+ f()
});
}
/// Arrange to send a particular message to a channel if the task fails.
-pub fn spawn_named_with_send_on_failure<T: Send>(name: &'static str,
- state: task_state::TaskState,
- f: proc(): Send,
- msg: T,
- dest: Sender<T>) {
- let future_result = TaskBuilder::new().named(name).try_future(proc() {
+pub fn spawn_named_with_send_on_failure<F, T>(name: &'static str,
+ state: task_state::TaskState,
+ f: F,
+ msg: T,
+ dest: Sender<T>)
+ where F: FnOnce() + Send,
+ T: Send
+{
+ let future_handle = thread::Builder::new().name(name.to_owned()).scoped(move || {
task_state::initialize(state);
- // FIXME: Find replacement for this post-runtime removal
- // rtinstrument::instrument(f);
- f();
+ f()
});
- let watched_name = name.into_string();
- let watcher_name = format!("{}Watcher", watched_name);
- TaskBuilder::new().named(watcher_name).spawn(proc() {
- //rtinstrument::instrument(proc() {
- match future_result.into_inner() {
- Ok(()) => (),
- Err(..) => {
- debug!("{} failed, notifying constellation", name);
- dest.send(msg);
- }
+ let watcher_name = format!("{}Watcher", name);
+ Builder::new().name(watcher_name).spawn(move || {
+ match future_handle.join() {
+ Ok(()) => (),
+ Err(..) => {
+ debug!("{} failed, notifying constellation", name);
+ dest.send(msg);
}
- //});
+ }
+ });
+}
+
+#[test]
+fn spawn_named_test() {
+ spawn_named("Test".to_owned(), move || {
+ debug!("I can run!");
});
}
diff --git a/components/util/task_state.rs b/components/util/task_state.rs
index 3915eeb3059..ef1dbb2ed3e 100644
--- a/components/util/task_state.rs
+++ b/components/util/task_state.rs
@@ -11,7 +11,7 @@
pub use self::imp::{initialize, get, enter, exit};
bitflags! {
- #[deriving(Show, Copy)]
+ #[derive(Show)]
flags TaskState: u32 {
const SCRIPT = 0x01,
const LAYOUT = 0x02,
@@ -35,7 +35,7 @@ macro_rules! task_types ( ( $( $fun:ident = $flag:ident ; )* ) => (
#[cfg(not(ndebug))]
static TYPES: &'static [TaskState]
= &[ $( $flag ),* ];
-))
+));
task_types! {
is_script = SCRIPT;
@@ -48,12 +48,12 @@ mod imp {
use super::{TaskState, TYPES};
use std::cell::RefCell;
- thread_local!(static STATE: RefCell<Option<TaskState>> = RefCell::new(None))
+ thread_local!(static STATE: RefCell<Option<TaskState>> = RefCell::new(None));
pub fn initialize(x: TaskState) {
STATE.with(|ref k| {
match *k.borrow() {
- Some(s) => panic!("Task state already initialized as {}", s),
+ Some(s) => panic!("Task state already initialized as {:?}", s),
None => ()
};
*k.borrow_mut() = Some(x);
diff --git a/components/util/taskpool.rs b/components/util/taskpool.rs
index 8521ef9dc93..7f2d36be936 100644
--- a/components/util/taskpool.rs
+++ b/components/util/taskpool.rs
@@ -17,9 +17,11 @@
use task::spawn_named;
use std::sync::{Arc, Mutex};
+use std::sync::mpsc::{channel, Sender, Receiver};
+use std::thunk::Thunk;
pub struct TaskPool {
- tx: Sender<proc():Send>,
+ tx: Sender<Thunk<()>>,
}
impl TaskPool {
@@ -33,23 +35,25 @@ impl TaskPool {
let state = state.clone();
spawn_named(
format!("TaskPoolWorker {}/{}", i+1, tasks),
- proc() worker(&*state));
+ move || worker(&*state));
}
return TaskPool { tx: tx };
- fn worker(rx: &Mutex<Receiver<proc():Send>>) {
+ fn worker(rx: &Mutex<Receiver<Thunk<()>>>) {
loop {
- let job = rx.lock().recv_opt();
+ let job = rx.lock().unwrap().recv();
match job {
- Ok(job) => job(),
+ Ok(job) => job.invoke(()),
Err(..) => break,
}
}
}
}
- pub fn execute(&self, job: proc():Send) {
- self.tx.send(job);
+ pub fn execute<F>(&self, job: F)
+ where F: FnOnce() + Send
+ {
+ self.tx.send(Thunk::new(job));
}
}
diff --git a/components/util/tid.rs b/components/util/tid.rs
index 5cea4fe0d43..e52dbf7fd61 100644
--- a/components/util/tid.rs
+++ b/components/util/tid.rs
@@ -2,20 +2,20 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use std::sync::atomic::{AtomicUint, INIT_ATOMIC_UINT, SeqCst};
+use std::sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering};
use std::rc::Rc;
use std::cell::RefCell;
-static mut next_tid: AtomicUint = INIT_ATOMIC_UINT;
+static mut next_tid: AtomicUint = ATOMIC_UINT_INIT;
-thread_local!(static TASK_LOCAL_TID: Rc<RefCell<Option<uint>>> = Rc::new(RefCell::new(None)))
+thread_local!(static TASK_LOCAL_TID: Rc<RefCell<Option<uint>>> = Rc::new(RefCell::new(None)));
/// Every task gets one, that's unique.
pub fn tid() -> uint {
TASK_LOCAL_TID.with(|ref k| {
let ret =
match *k.borrow() {
- None => unsafe { next_tid.fetch_add(1, SeqCst) },
+ None => unsafe { next_tid.fetch_add(1, Ordering::SeqCst) },
Some(x) => x,
};
diff --git a/components/util/time.rs b/components/util/time.rs
index 96d037c520a..b5805dfa092 100644
--- a/components/util/time.rs
+++ b/components/util/time.rs
@@ -4,19 +4,21 @@
//! Timing functions.
-use collections::TreeMap;
-use std::comm::{Sender, channel, Receiver};
+use collections::BTreeMap;
+use std::borrow::ToOwned;
+use std::cmp::Ordering;
use std::f64;
use std::io::timer::sleep;
use std::iter::AdditiveIterator;
-use std::num::FloatMath;
+use std::num::Float;
+use std::sync::mpsc::{Sender, channel, Receiver};
use std::time::duration::Duration;
use std_time::precise_time_ns;
use task::{spawn_named};
use url::Url;
// front-end representation of the profiler used to communicate with the profiler
-#[deriving(Clone)]
+#[derive(Clone)]
pub struct TimeProfilerChan(pub Sender<TimeProfilerMsg>);
impl TimeProfilerChan {
@@ -26,7 +28,7 @@ impl TimeProfilerChan {
}
}
-#[deriving(PartialEq, Clone, PartialOrd, Eq, Ord)]
+#[derive(PartialEq, Clone, PartialOrd, Eq, Ord)]
pub struct TimerMetadata {
url: String,
iframe: bool,
@@ -58,7 +60,7 @@ impl Formatable for Option<TimerMetadata> {
}
}
-#[deriving(Clone)]
+#[derive(Clone)]
pub enum TimeProfilerMsg {
/// Normal message used for reporting time
Time((TimeProfilerCategory, Option<TimerMetadata>), f64),
@@ -69,7 +71,7 @@ pub enum TimeProfilerMsg {
}
#[repr(u32)]
-#[deriving(PartialEq, Clone, PartialOrd, Eq, Ord)]
+#[derive(PartialEq, Clone, PartialOrd, Eq, Ord)]
pub enum TimeProfilerCategory {
Compositing,
LayoutPerform,
@@ -128,7 +130,7 @@ impl Formatable for TimeProfilerCategory {
}
}
-type TimeProfilerBuckets = TreeMap<(TimeProfilerCategory, Option<TimerMetadata>), Vec<f64>>;
+type TimeProfilerBuckets = BTreeMap<(TimeProfilerCategory, Option<TimerMetadata>), Vec<f64>>;
// back end of the profiler that handles data aggregation and performance metrics
pub struct TimeProfiler {
@@ -144,25 +146,25 @@ impl TimeProfiler {
Some(period) => {
let period = Duration::milliseconds((period * 1000f64) as i64);
let chan = chan.clone();
- spawn_named("Time profiler timer", proc() {
+ spawn_named("Time profiler timer".to_owned(), move || {
loop {
sleep(period);
- if chan.send_opt(TimeProfilerMsg::Print).is_err() {
+ if chan.send(TimeProfilerMsg::Print).is_err() {
break;
}
}
});
// Spawn the time profiler.
- spawn_named("Time profiler", proc() {
+ spawn_named("Time profiler".to_owned(), move || {
let mut profiler = TimeProfiler::new(port);
profiler.start();
});
}
None => {
// No-op to handle messages when the time profiler is inactive.
- spawn_named("Time profiler", proc() {
+ spawn_named("Time profiler".to_owned(), move || {
loop {
- match port.recv_opt() {
+ match port.recv() {
Err(_) | Ok(TimeProfilerMsg::Exit) => break,
_ => {}
}
@@ -177,14 +179,14 @@ impl TimeProfiler {
pub fn new(port: Receiver<TimeProfilerMsg>) -> TimeProfiler {
TimeProfiler {
port: port,
- buckets: TreeMap::new(),
+ buckets: BTreeMap::new(),
last_msg: None,
}
}
pub fn start(&mut self) {
loop {
- let msg = self.port.recv_opt();
+ let msg = self.port.recv();
match msg {
Ok(msg) => {
if !self.handle_msg(msg) {
@@ -227,9 +229,9 @@ impl TimeProfiler {
for (&(ref category, ref meta), ref mut data) in self.buckets.iter_mut() {
data.sort_by(|a, b| {
if a < b {
- Less
+ Ordering::Less
} else {
- Greater
+ Ordering::Greater
}
});
let data_len = data.len();
@@ -247,13 +249,13 @@ impl TimeProfiler {
}
}
-#[deriving(Eq, PartialEq)]
+#[derive(Eq, PartialEq)]
pub enum TimerMetadataFrameType {
RootWindow,
IFrame,
}
-#[deriving(Eq, PartialEq)]
+#[derive(Eq, PartialEq)]
pub enum TimerMetadataReflowType {
Incremental,
FirstReflow,
@@ -261,11 +263,13 @@ pub enum TimerMetadataReflowType {
pub type ProfilerMetadata<'a> = Option<(&'a Url, TimerMetadataFrameType, TimerMetadataReflowType)>;
-pub fn profile<T>(category: TimeProfilerCategory,
- meta: ProfilerMetadata,
- time_profiler_chan: TimeProfilerChan,
- callback: || -> T)
- -> T {
+pub fn profile<T, F>(category: TimeProfilerCategory,
+ meta: ProfilerMetadata,
+ time_profiler_chan: TimeProfilerChan,
+ callback: F)
+ -> T
+ where F: FnOnce() -> T
+{
let start_time = precise_time_ns();
let val = callback();
let end_time = precise_time_ns();
@@ -280,7 +284,9 @@ pub fn profile<T>(category: TimeProfilerCategory,
return val;
}
-pub fn time<T>(msg: &str, callback: || -> T) -> T{
+pub fn time<T, F>(msg: &str, callback: F) -> T
+ where F: Fn() -> T
+{
let start_time = precise_time_ns();
let val = callback();
let end_time = precise_time_ns();
diff --git a/components/util/vec.rs b/components/util/vec.rs
index b9a67b6760b..a902a3133df 100644
--- a/components/util/vec.rs
+++ b/components/util/vec.rs
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use std::cmp::{PartialOrd, PartialEq};
+use std::cmp::{PartialOrd, PartialEq, Ordering};
#[cfg(test)]
use std::fmt::Show;
@@ -47,9 +47,9 @@ impl<'a, T> FullBinarySearchMethods<T> for &'a [T] {
let midv = &self[mid];
match cmp.compare(key, midv) {
- Greater => low = (mid as int) + 1,
- Less => high = (mid as int) - 1,
- Equal => return Some(mid),
+ Ordering::Greater => low = (mid as int) + 1,
+ Ordering::Less => high = (mid as int) - 1,
+ Ordering::Equal => return Some(mid),
}
}
return None;
@@ -78,7 +78,7 @@ fn test_miss_all_elems<T: PartialEq + PartialOrd + Eq + Ord + Show>(arr: &[T], m
let mut i = 0;
while i < misses.len() {
let res = arr.binary_search_(&misses[i]);
- debug!("{} == {} ?", misses[i], res);
+ debug!("{:?} == {:?} ?", misses[i], res);
assert!(!test_match(&misses[i], arr.binary_search_(&misses[i])));
i += 1;
}
diff --git a/components/util/workqueue.rs b/components/util/workqueue.rs
index 9fef7ac2a81..c83902526fd 100644
--- a/components/util/workqueue.rs
+++ b/components/util/workqueue.rs
@@ -14,7 +14,8 @@ use libc::funcs::posix88::unistd::usleep;
use rand::{Rng, XorShiftRng};
use std::mem;
use std::rand::weak_rng;
-use std::sync::atomic::{AtomicUint, SeqCst};
+use std::sync::atomic::{AtomicUint, Ordering};
+use std::sync::mpsc::{channel, Sender, Receiver};
use deque::{Abort, BufferPool, Data, Empty, Stealer, Worker};
/// A unit of work.
@@ -31,7 +32,7 @@ pub struct WorkUnit<QueueData, WorkData> {
}
/// Messages from the supervisor to the worker.
-enum WorkerMsg<QueueData, WorkData> {
+enum WorkerMsg<QueueData: 'static, WorkData: 'static> {
/// Tells the worker to start work.
Start(Worker<WorkUnit<QueueData, WorkData>>, *mut AtomicUint, *const QueueData),
/// Tells the worker to stop. It can be restarted again with a `WorkerMsg::Start`.
@@ -40,14 +41,18 @@ enum WorkerMsg<QueueData, WorkData> {
Exit,
}
+unsafe impl<QueueData: 'static, WorkData: 'static> Send for WorkerMsg<QueueData, WorkData> {}
+
/// Messages to the supervisor.
-enum SupervisorMsg<QueueData, WorkData> {
+enum SupervisorMsg<QueueData: 'static, WorkData: 'static> {
Finished,
ReturnDeque(uint, Worker<WorkUnit<QueueData, WorkData>>),
}
+unsafe impl<QueueData: 'static, WorkData: 'static> Send for SupervisorMsg<QueueData, WorkData> {}
+
/// Information that the supervisor thread keeps about the worker threads.
-struct WorkerInfo<QueueData, WorkData> {
+struct WorkerInfo<QueueData: 'static, WorkData: 'static> {
/// The communication channel to the workers.
chan: Sender<WorkerMsg<QueueData, WorkData>>,
/// The worker end of the deque, if we have it.
@@ -57,7 +62,7 @@ struct WorkerInfo<QueueData, WorkData> {
}
/// Information specific to each worker thread that the thread keeps.
-struct WorkerThread<QueueData, WorkData> {
+struct WorkerThread<QueueData: 'static, WorkData: 'static> {
/// The index of this worker.
index: uint,
/// The communication port from the supervisor.
@@ -70,6 +75,8 @@ struct WorkerThread<QueueData, WorkData> {
rng: XorShiftRng,
}
+unsafe impl<QueueData: 'static, WorkData: 'static> Send for WorkerThread<QueueData, WorkData> {}
+
static SPIN_COUNT: u32 = 128;
static SPINS_UNTIL_BACKOFF: u32 = 100;
static BACKOFF_INCREMENT_IN_US: u32 = 5;
@@ -80,7 +87,7 @@ impl<QueueData: Send, WorkData: Send> WorkerThread<QueueData, WorkData> {
fn start(&mut self) {
loop {
// Wait for a start message.
- let (mut deque, ref_count, queue_data) = match self.port.recv() {
+ let (mut deque, ref_count, queue_data) = match self.port.recv().unwrap() {
WorkerMsg::Start(deque, ref_count, queue_data) => (deque, ref_count, queue_data),
WorkerMsg::Stop => panic!("unexpected stop message"),
WorkerMsg::Exit => return,
@@ -157,14 +164,14 @@ impl<QueueData: Send, WorkData: Send> WorkerThread<QueueData, WorkData> {
// The work is done. Now decrement the count of outstanding work items. If this was
// the last work unit in the queue, then send a message on the channel.
unsafe {
- if (*ref_count).fetch_sub(1, SeqCst) == 1 {
- self.chan.send(SupervisorMsg::Finished)
+ if (*ref_count).fetch_sub(1, Ordering::SeqCst) == 1 {
+ self.chan.send(SupervisorMsg::Finished).unwrap()
}
}
}
// Give the deque back to the supervisor.
- self.chan.send(SupervisorMsg::ReturnDeque(self.index, deque))
+ self.chan.send(SupervisorMsg::ReturnDeque(self.index, deque)).unwrap()
}
}
}
@@ -181,7 +188,7 @@ impl<'a, QueueData: 'static, WorkData: Send> WorkerProxy<'a, QueueData, WorkData
#[inline]
pub fn push(&mut self, work_unit: WorkUnit<QueueData, WorkData>) {
unsafe {
- drop((*self.ref_count).fetch_add(1, SeqCst));
+ drop((*self.ref_count).fetch_add(1, Ordering::SeqCst));
}
self.worker.push(work_unit);
}
@@ -196,7 +203,7 @@ impl<'a, QueueData: 'static, WorkData: Send> WorkerProxy<'a, QueueData, WorkData
}
/// A work queue on which units of work can be submitted.
-pub struct WorkQueue<QueueData, WorkData> {
+pub struct WorkQueue<QueueData: 'static, WorkData: 'static> {
/// Information about each of the workers.
workers: Vec<WorkerInfo<QueueData, WorkData>>,
/// A port on which deques can be received from the workers.
@@ -250,7 +257,7 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> {
spawn_named(
format!("{} worker {}/{}", task_name, i+1, thread_count),
- proc() {
+ move || {
task_state::initialize(state | task_state::IN_WORKER);
let mut thread = thread;
thread.start()
@@ -283,7 +290,7 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> {
// Tell the workers to start.
let mut work_count = AtomicUint::new(self.work_count);
for worker in self.workers.iter_mut() {
- worker.chan.send(WorkerMsg::Start(worker.deque.take().unwrap(), &mut work_count, &self.data))
+ worker.chan.send(WorkerMsg::Start(worker.deque.take().unwrap(), &mut work_count, &self.data)).unwrap()
}
// Wait for the work to finish.
@@ -292,12 +299,12 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> {
// Tell everyone to stop.
for worker in self.workers.iter() {
- worker.chan.send(WorkerMsg::Stop)
+ worker.chan.send(WorkerMsg::Stop).unwrap()
}
// Get our deques back.
for _ in range(0, self.workers.len()) {
- match self.port.recv() {
+ match self.port.recv().unwrap() {
SupervisorMsg::ReturnDeque(index, deque) => self.workers[index].deque = Some(deque),
SupervisorMsg::Finished => panic!("unexpected finished message!"),
}
@@ -306,7 +313,7 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> {
pub fn shutdown(&mut self) {
for worker in self.workers.iter() {
- worker.chan.send(WorkerMsg::Exit)
+ worker.chan.send(WorkerMsg::Exit).unwrap()
}
}
}