<commit_before>#![feature(plugin, inclusive_range_syntax)]
#![plugin(clippy)]

#![allow(dead_code, no_effect, unnecessary_operation)]
#![allow(let_and_return)]
#![allow(needless_return)]
#![allow(unused_variables)]
#![allow(cyclomatic_complexity)]
#![allow(blacklisted_name)]
#![allow(collapsible_if)]
#![allow(zero_divided_by_zero, eq_op)]
#![allow(path_statements)]

fn bar<T>(_: T) {}
fn foo() -> bool { unimplemented!() }

struct Foo {
    bar: u8,
}

pub enum Abc {
    A,
    B,
    C,
}

#[deny(if_same_then_else)]
#[deny(match_same_arms)]
fn if_same_then_else() -> Result<&'static str, ()> {
    if true {
        //~^NOTE same as this
        Foo { bar: 42 };
        0..10;
        ..;
        0..;
        ..10;
        0...10;
        foo();
    }
    else { //~ERROR this `if` has identical blocks
        Foo { bar: 42 };
        0..10;
        ..;
        0..;
        ..10;
        0...10;
        foo();
    }

    if true {
        Foo { bar: 42 };
    }
    else {
        Foo { bar: 43 };
    }

    if true {
        ();
    }
    else {
        ()
    }

    if true {
        0..10;
    }
    else {
        0...10;
    }

    if true {
        foo();
        foo();
    }
    else {
        foo();
    }

    let _ = match 42 {
        42 => {
            //~^ NOTE same as this
            //~| NOTE removing
            foo();
            let mut a = 42 + [23].len() as i32;
            if true {
                a += 7;
            }
            a = -31-a;
            a
        }
        _ => { //~ERROR this `match` has identical arm bodies
            foo();
            let mut a = 42 + [23].len() as i32;
            if true {
                a += 7;
            }
            a = -31-a;
            a
        }
    };

    let _ = match Abc::A {
        Abc::A => 0,
        //~^ NOTE same as this
        //~| NOTE removing
        Abc::B => 1,
        _ => 0, //~ERROR this `match` has identical arm bodies
    };

    if true {
        foo();
    }

    let _ = if true {
        //~^NOTE same as this
        42
    }
    else { //~ERROR this `if` has identical blocks
        42
    };

    if true {
        //~^NOTE same as this
        for _ in &[42] {
            // let foo: &Option<_> = &Some::<u8>(42);
            // if true {
            //     break;
            // } else {
            //     continue;
            // }
        }
    }
    else { //~ERROR this `if` has identical blocks
        for _ in &[42] {
            // let foo: &Option<_> = &Some::<u8>(42);
            // if true {
            //     break;
            // } else {
            //     continue;
            // }
        }
    }

    if true {
        //~^NOTE same as this
        let bar = if true {
            42
        }
        else {
            43
        };

        while foo() { break; }
        bar + 1;
    }
    else { //~ERROR this `if` has identical blocks
        let bar = if true {
            42
        }
        else {
            43
        };

        while foo() { break; }
        bar + 1;
    }

    if true {
        //~^NOTE same as this
        let _ = match 42 {
            42 => 1,
            a if a > 0 => 2,
            10...15 => 3,
            _ => 4,
        };
    }
    else if false {
        foo();
    }
    else if foo() { //~ERROR this `if` has identical blocks
        let _ = match 42 {
            42 => 1,
            a if a > 0 => 2,
            10...15 => 3,
            _ => 4,
        };
    }

    if true {
        //~^NOTE same as this
        if let Some(a) = Some(42) {}
    }
    else { //~ERROR this `if` has identical blocks
        if let Some(a) = Some(42) {}
    }

    if true {
        //~^NOTE same as this
        if let (1, .., 3) = (1, 2, 3) {}
    }
    else { //~ERROR this `if` has identical blocks
        if let (1, .., 3) = (1, 2, 3) {}
    }

    if true {
        if let (1, .., 3) = (1, 2, 3) {}
    }
    else {
        if let (.., 3) = (1, 2, 3) {}
    }

    if true {
        if let (1, .., 3) = (1, 2, 3) {}
    }
    else {
        if let (.., 4) = (1, 2, 3) {}
    }

    if true {
        if let (1, .., 3) = (1, 2, 3) {}
    }
    else {
        if let (.., 1, 3) = (1, 2, 3) {}
    }

    if true {
        if let Some(42) = None {}
    }
    else {
        if let Option::Some(42) = None {}
    }

    if true {
        if let Some(42) = None::<u8> {}
    }
    else {
        if let Some(42) = None {}
    }

    if true {
        if let Some(42) = None::<u8> {}
    }
    else {
        if let Some(42) = None::<u32> {}
    }

    if true {
        if let Some(a) = Some(42) {}
    }
    else {
        if let Some(a) = Some(43) {}
    }

    let _ = match 42 {
        42 => foo(),
        //~^NOTE same as this
        //~|NOTE `42 | 51`
        51 => foo(), //~ERROR this `match` has identical arm bodies
        _ => true,
    };

    let _ = match Some(42) {
        Some(_) => 24,
        //~^NOTE same as this
        //~|NOTE `Some(_) | None`
        None => 24, //~ERROR this `match` has identical arm bodies
    };

    let _ = match Some(42) {
        Some(foo) => 24,
        None => 24,
    };

    let _ = match Some(42) {
        Some(42) => 24,
        Some(a) => 24, // bindings are different
        None => 0,
    };

    let _ = match Some(42) {
        Some(a) if a > 0 => 24,
        Some(a) => 24, // one arm has a guard
        None => 0,
    };

    match (Some(42), Some(42)) {
        (Some(a), None) => bar(a),
        //~^NOTE same as this
        //~|NOTE `(Some(a), None) | (None, Some(a))`
        (None, Some(a)) => bar(a), //~ERROR this `match` has identical arm bodies
        _ => (),
    }

    match (Some(42), Some(42)) {
        (Some(a), ..) => bar(a),
        //~^NOTE same as this
        //~|NOTE `(Some(a), ..) | (.., Some(a))`
        (.., Some(a)) => bar(a), //~ERROR this `match` has identical arm bodies
        _ => (),
    }

    match (1, 2, 3) {
        (1, .., 3) => 42,
        //~^NOTE same as this
        //~|NOTE `(1, .., 3) | (.., 3)`
        (.., 3) => 42, //~ERROR this `match` has identical arm bodies
        _ => 0,
    };

    let _ = if true {
        //~^NOTE same as this
        0.0
    } else { //~ERROR this `if` has identical blocks
        0.0
    };

    let _ = if true {
        //~^NOTE same as this
        -0.0
    } else { //~ERROR this `if` has identical blocks
        -0.0
    };

    let _ = if true {
        0.0
    } else {
        -0.0
    };

    // Different NaNs
    let _ = if true {
        0.0 / 0.0
    } else {
        std::f32::NAN
    };

    // Same NaNs
    let _ = if true {
        //~^NOTE same as this
        std::f32::NAN
    } else { //~ERROR this `if` has identical blocks
        std::f32::NAN
    };

    let _ = match Some(()) {
        Some(()) => 0.0,
        None => -0.0
    };

    match (Some(42), Some("")) {
        (Some(a), None) => bar(a),
        (None, Some(a)) => bar(a), // bindings have different types
        _ => (),
    }

    if true {
        //~^NOTE same as this
        try!(Ok("foo"));
    }
    else { //~ERROR this `if` has identical blocks
        try!(Ok("foo"));
    }

    if true {
        //~^NOTE same as this
        let foo = "";
        return Ok(&foo[0..]);
    }
    else if false {
        let foo = "bar";
        return Ok(&foo[0..]);
    }
    else { //~ERROR this `if` has identical blocks
        let foo = "";
        return Ok(&foo[0..]);
    }
}

#[deny(ifs_same_cond)]
#[allow(if_same_then_else)] // all empty blocks
fn ifs_same_cond() {
    let a = 0;
    let b = false;

    if b {
        //~^NOTE same as this
    }
    else if b { //~ERROR this `if` has the same condition as a previous if
    }

    if a == 1 {
        //~^NOTE same as this
    }
    else if a == 1 { //~ERROR this `if` has the same condition as a previous if
    }

    if 2*a == 1 {
        //~^NOTE same as this
    }
    else if 2*a == 2 {
    }
    else if 2*a == 1 { //~ERROR this `if` has the same condition as a previous if
    }
    else if a == 1 {
    }

    // See #659
    if cfg!(feature = "feature1-659") {
        1
    } else if cfg!(feature = "feature2-659") {
        2
    } else {
        3
    };

    let mut v = vec![1];
    if v.pop() == None { // ok, functions
    }
    else if v.pop() == None {
    }

    if v.len() == 42 { // ok, functions
    }
    else if v.len() == 42 {
    }
}

fn main() {}
<commit_msg>uncomment code that was commented out for testing<commit_after>#![feature(plugin, inclusive_range_syntax)]
#![plugin(clippy)]

#![allow(dead_code, no_effect, unnecessary_operation)]
#![allow(let_and_return)]
#![allow(needless_return)]
#![allow(unused_variables)]
#![allow(cyclomatic_complexity)]
#![allow(blacklisted_name)]
#![allow(collapsible_if)]
#![allow(zero_divided_by_zero, eq_op)]
#![allow(path_statements)]

fn bar<T>(_: T) {}
fn foo() -> bool { unimplemented!() }

struct Foo {
    bar: u8,
}

pub enum Abc {
    A,
    B,
    C,
}

#[deny(if_same_then_else)]
#[deny(match_same_arms)]
fn if_same_then_else() -> Result<&'static str, ()> {
    if true {
        //~^NOTE same as this
        Foo { bar: 42 };
        0..10;
        ..;
        0..;
        ..10;
        0...10;
        foo();
    }
    else { //~ERROR this `if` has identical blocks
        Foo { bar: 42 };
        0..10;
        ..;
        0..;
        ..10;
        0...10;
        foo();
    }

    if true {
        Foo { bar: 42 };
    }
    else {
        Foo { bar: 43 };
    }

    if true {
        ();
    }
    else {
        ()
    }

    if true {
        0..10;
    }
    else {
        0...10;
    }

    if true {
        foo();
        foo();
    }
    else {
        foo();
    }

    let _ = match 42 {
        42 => {
            //~^ NOTE same as this
            //~| NOTE removing
            foo();
            let mut a = 42 + [23].len() as i32;
            if true {
                a += 7;
            }
            a = -31-a;
            a
        }
        _ => { //~ERROR this `match` has identical arm bodies
            foo();
            let mut a = 42 + [23].len() as i32;
            if true {
                a += 7;
            }
            a = -31-a;
            a
        }
    };

    let _ = match Abc::A {
        Abc::A => 0,
        //~^ NOTE same as this
        //~| NOTE removing
        Abc::B => 1,
        _ => 0, //~ERROR this `match` has identical arm bodies
    };

    if true {
        foo();
    }

    let _ = if true {
        //~^NOTE same as this
        42
    }
    else { //~ERROR this `if` has identical blocks
        42
    };

    if true {
        //~^NOTE same as this
        for _ in &[42] {
            let foo: &Option<_> = &Some::<u8>(42);
            if true {
                break;
            } else {
                continue;
            }
        }
    }
    else { //~ERROR this `if` has identical blocks
        for _ in &[42] {
            let foo: &Option<_> = &Some::<u8>(42);
            if true {
                break;
            } else {
                continue;
            }
        }
    }

    if true {
        //~^NOTE same as this
        let bar = if true {
            42
        }
        else {
            43
        };

        while foo() { break; }
        bar + 1;
    }
    else { //~ERROR this `if` has identical blocks
        let bar = if true {
            42
        }
        else {
            43
        };

        while foo() { break; }
        bar + 1;
    }

    if true {
        //~^NOTE same as this
        let _ = match 42 {
            42 => 1,
            a if a > 0 => 2,
            10...15 => 3,
            _ => 4,
        };
    }
    else if false {
        foo();
    }
    else if foo() { //~ERROR this `if` has identical blocks
        let _ = match 42 {
            42 => 1,
            a if a > 0 => 2,
            10...15 => 3,
            _ => 4,
        };
    }

    if true {
        //~^NOTE same as this
        if let Some(a) = Some(42) {}
    }
    else { //~ERROR this `if` has identical blocks
        if let Some(a) = Some(42) {}
    }

    if true {
        //~^NOTE same as this
        if let (1, .., 3) = (1, 2, 3) {}
    }
    else { //~ERROR this `if` has identical blocks
        if let (1, .., 3) = (1, 2, 3) {}
    }

    if true {
        if let (1, .., 3) = (1, 2, 3) {}
    }
    else {
        if let (.., 3) = (1, 2, 3) {}
    }

    if true {
        if let (1, .., 3) = (1, 2, 3) {}
    }
    else {
        if let (.., 4) = (1, 2, 3) {}
    }

    if true {
        if let (1, .., 3) = (1, 2, 3) {}
    }
    else {
        if let (.., 1, 3) = (1, 2, 3) {}
    }

    if true {
        if let Some(42) = None {}
    }
    else {
        if let Option::Some(42) = None {}
    }

    if true {
        if let Some(42) = None::<u8> {}
    }
    else {
        if let Some(42) = None {}
    }

    if true {
        if let Some(42) = None::<u8> {}
    }
    else {
        if let Some(42) = None::<u32> {}
    }

    if true {
        if let Some(a) = Some(42) {}
    }
    else {
        if let Some(a) = Some(43) {}
    }

    let _ = match 42 {
        42 => foo(),
        //~^NOTE same as this
        //~|NOTE `42 | 51`
        51 => foo(), //~ERROR this `match` has identical arm bodies
        _ => true,
    };

    let _ = match Some(42) {
        Some(_) => 24,
        //~^NOTE same as this
        //~|NOTE `Some(_) | None`
        None => 24, //~ERROR this `match` has identical arm bodies
    };

    let _ = match Some(42) {
        Some(foo) => 24,
        None => 24,
    };

    let _ = match Some(42) {
        Some(42) => 24,
        Some(a) => 24, // bindings are different
        None => 0,
    };

    let _ = match Some(42) {
        Some(a) if a > 0 => 24,
        Some(a) => 24, // one arm has a guard
        None => 0,
    };

    match (Some(42), Some(42)) {
        (Some(a), None) => bar(a),
        //~^NOTE same as this
        //~|NOTE `(Some(a), None) | (None, Some(a))`
        (None, Some(a)) => bar(a), //~ERROR this `match` has identical arm bodies
        _ => (),
    }

    match (Some(42), Some(42)) {
        (Some(a), ..) => bar(a),
        //~^NOTE same as this
        //~|NOTE `(Some(a), ..) | (.., Some(a))`
        (.., Some(a)) => bar(a), //~ERROR this `match` has identical arm bodies
        _ => (),
    }

    match (1, 2, 3) {
        (1, .., 3) => 42,
        //~^NOTE same as this
        //~|NOTE `(1, .., 3) | (.., 3)`
        (.., 3) => 42, //~ERROR this `match` has identical arm bodies
        _ => 0,
    };

    let _ = if true {
        //~^NOTE same as this
        0.0
    } else { //~ERROR this `if` has identical blocks
        0.0
    };

    let _ = if true {
        //~^NOTE same as this
        -0.0
    } else { //~ERROR this `if` has identical blocks
        -0.0
    };

    let _ = if true {
        0.0
    } else {
        -0.0
    };

    // Different NaNs
    let _ = if true {
        0.0 / 0.0
    } else {
        std::f32::NAN
    };

    // Same NaNs
    let _ = if true {
        //~^NOTE same as this
        std::f32::NAN
    } else { //~ERROR this `if` has identical blocks
        std::f32::NAN
    };

    let _ = match Some(()) {
        Some(()) => 0.0,
        None => -0.0
    };

    match (Some(42), Some("")) {
        (Some(a), None) => bar(a),
        (None, Some(a)) => bar(a), // bindings have different types
        _ => (),
    }

    if true {
        //~^NOTE same as this
        try!(Ok("foo"));
    }
    else { //~ERROR this `if` has identical blocks
        try!(Ok("foo"));
    }

    if true {
        //~^NOTE same as this
        let foo = "";
        return Ok(&foo[0..]);
    }
    else if false {
        let foo = "bar";
        return Ok(&foo[0..]);
    }
    else { //~ERROR this `if` has identical blocks
        let foo = "";
        return Ok(&foo[0..]);
    }
}

#[deny(ifs_same_cond)]
#[allow(if_same_then_else)] // all empty blocks
fn ifs_same_cond() {
    let a = 0;
    let b = false;

    if b {
        //~^NOTE same as this
    }
    else if b { //~ERROR this `if` has the same condition as a previous if
    }

    if a == 1 {
        //~^NOTE same as this
    }
    else if a == 1 { //~ERROR this `if` has the same condition as a previous if
    }

    if 2*a == 1 {
        //~^NOTE same as this
    }
    else if 2*a == 2 {
    }
    else if 2*a == 1 { //~ERROR this `if` has the same condition as a previous if
    }
    else if a == 1 {
    }

    // See #659
    if cfg!(feature = "feature1-659") {
        1
    } else if cfg!(feature = "feature2-659") {
        2
    } else {
        3
    };

    let mut v = vec![1];
    if v.pop() == None { // ok, functions
    }
    else if v.pop() == None {
    }

    if v.len() == 42 { // ok, functions
    }
    else if v.len() == 42 {
    }
}

fn main() {}
<|endoftext|>


<commit_before>extern crate zookeeper;

use std::time::Duration;
use std::thread::Thread;
use zookeeper::{Acl, CreateMode, Watcher, WatchedEvent, ZkResult, ZooKeeper};
use zookeeper::perms;

struct LoggingWatcher;
impl Watcher for LoggingWatcher {
    fn handle(&self, e: &WatchedEvent) {
        println!("{:?}", e)
    }
}

fn zk_example() -> ZkResult<()> {
    let zk = try!(ZooKeeper::connect("127.0.0.1:2181", Duration::seconds(5), LoggingWatcher));

    let acl1 = vec![Acl{perms: perms::ALL, scheme: "world".to_string(), id: "anyone".to_string()}];
    let acl2 = vec![Acl{perms: perms::ALL, scheme: "world".to_string(), id: "anyone".to_string()}];

    let auth = zk.add_auth("digest", vec![1,2,3,4]);

    println!("authenticated -> {:?}", auth);

    let path = zk.create("/test", vec![1,2], acl1, CreateMode::Ephemeral);

    println!("created -> {:?}", path);

    let exists = zk.exists("/test", true);

    println!("exists -> {:?}", exists);

    let dont_exists = zk.exists("/blabla", true);

    println!("don't exists path -> {:?}", dont_exists);

    let get_acl = zk.get_acl("/test");

    println!("get_acl -> {:?}", get_acl);

    let set_acl = zk.set_acl("/test", acl2, -1);

    println!("set_acl -> {:?}", set_acl);

    let children = zk.get_children("/", true);

    println!("children of / -> {:?}", children);

    let set_data = zk.set_data("/test", vec![6,5,4,3], -1);

    println!("set_data -> {:?}", set_data);

    let get_data = zk.get_data("/test", true);

    println!("get_data -> {:?}", get_data);

    let delete = zk.delete("/test", -1);

    println!("deleted /test -> {:?}", delete);

    println!("press enter to close client");
    std::io::stdin().read_line();

    // The client can be shared between tasks
    let zk2 = zk.clone();
    Thread::spawn(move || {
        zk2.close();
    });

    println!("press enter to exit example");
    std::io::stdin().read_line();

    Ok(())
}

fn main() {
    zk_example().unwrap();
}
<commit_msg>get rid of unstable warnings in example<commit_after>#![allow(unstable)]
extern crate zookeeper;

use std::time::Duration;
use std::thread::Thread;
use zookeeper::{Acl, CreateMode, Watcher, WatchedEvent, ZkResult, ZooKeeper};
use zookeeper::perms;

struct LoggingWatcher;
impl Watcher for LoggingWatcher {
    fn handle(&self, e: &WatchedEvent) {
        println!("{:?}", e)
    }
}

fn zk_example() -> ZkResult<()> {
    let zk = try!(ZooKeeper::connect("127.0.0.1:2181", Duration::seconds(5), LoggingWatcher));

    let acl1 = vec![Acl{perms: perms::ALL, scheme: "world".to_string(), id: "anyone".to_string()}];
    let acl2 = vec![Acl{perms: perms::ALL, scheme: "world".to_string(), id: "anyone".to_string()}];

    let auth = zk.add_auth("digest", vec![1,2,3,4]);

    println!("authenticated -> {:?}", auth);

    let path = zk.create("/test", vec![1,2], acl1, CreateMode::Ephemeral);

    println!("created -> {:?}", path);

    let exists = zk.exists("/test", true);

    println!("exists -> {:?}", exists);

    let dont_exists = zk.exists("/blabla", true);

    println!("don't exists path -> {:?}", dont_exists);

    let get_acl = zk.get_acl("/test");

    println!("get_acl -> {:?}", get_acl);

    let set_acl = zk.set_acl("/test", acl2, -1);

    println!("set_acl -> {:?}", set_acl);

    let children = zk.get_children("/", true);

    println!("children of / -> {:?}", children);

    let set_data = zk.set_data("/test", vec![6,5,4,3], -1);

    println!("set_data -> {:?}", set_data);

    let get_data = zk.get_data("/test", true);

    println!("get_data -> {:?}", get_data);

    let delete = zk.delete("/test", -1);

    println!("deleted /test -> {:?}", delete);

    println!("press enter to close client");
    std::io::stdin().read_line();

    // The client can be shared between tasks
    let zk2 = zk.clone();
    Thread::spawn(move || {
        zk2.close();
    });

    println!("press enter to exit example");
    std::io::stdin().read_line();

    Ok(())
}

fn main() {
    zk_example().unwrap();
}
<|endoftext|>


<commit_before>#[macro_export]
macro_rules! storage_value {
    ($name:ident {
        const SIZE = $body:expr;

        $($field_name:ident : $field_type:ty [$from:expr => $to:expr])*
    }) => (
        #[derive(Clone, PartialEq)]
        pub struct $name {
            raw: Vec<u8>
        }

        impl $crate::storage::StorageValue for $name {
            fn serialize(self) -> Vec<u8> {
                self.raw
            }

            fn deserialize(v: Vec<u8>) -> Self {
                $name {
                    raw: v
                }
            }

            fn hash(&self) -> Hash {
                $name::hash(self)
            }
        }

        impl $name {
            pub fn new($($field_name: $field_type,)*) -> $name {
                use $crate::messages::{Field};
                let mut buf = vec![0; $body];
                $($field_name.write(&mut buf, $from, $to);)*
                $name { raw: buf }
            }

            pub fn from_raw(raw: Vec<u8>) -> $name {
                debug_assert_eq!(raw.len(), $body);
                $ name { raw: raw }
            }

            pub fn hash(&self) -> Hash {
                hash(self.raw.as_ref())
            }

            $(pub fn $field_name(&self) -> $field_type {
                use $crate::messages::Field;
                Field::read(&self.raw, $from, $to)
            })*
        }

        impl ::std::fmt::Debug for $name {
            fn fmt(&self, fmt: &mut ::std::fmt::Formatter)
                -> Result<(), ::std::fmt::Error> {
                fmt.debug_struct(stringify!($name))
                 $(.field(stringify!($field_name), &self.$field_name()))*
                   .finish()
            }
        }
    )
}<commit_msg>Update todos<commit_after>#[macro_export]
macro_rules! storage_value {
    ($name:ident {
        const SIZE = $body:expr;

        $($field_name:ident : $field_type:ty [$from:expr => $to:expr])*
    }) => (
        #[derive(Clone, PartialEq)]
        pub struct $name {
            raw: Vec<u8>
        }

        impl $crate::storage::StorageValue for $name {
            fn serialize(self) -> Vec<u8> {
                self.raw
            }

            fn deserialize(v: Vec<u8>) -> Self {
                $name {
                    raw: v
                }
            }

            fn hash(&self) -> Hash {
                $name::hash(self)
            }
        }

        // TODO extract some fields like hash and from_raw into trait
        impl $name {
            pub fn new($($field_name: $field_type,)*) -> $name {
                use $crate::messages::{Field};
                let mut buf = vec![0; $body];
                $($field_name.write(&mut buf, $from, $to);)*
                $name { raw: buf }
            }

            pub fn from_raw(raw: Vec<u8>) -> $name {
                debug_assert_eq!(raw.len(), $body);
                $ name { raw: raw }
            }

            pub fn hash(&self) -> Hash {
                hash(self.raw.as_ref())
            }

            $(pub fn $field_name(&self) -> $field_type {
                use $crate::messages::Field;
                Field::read(&self.raw, $from, $to)
            })*
        }

        impl ::std::fmt::Debug for $name {
            fn fmt(&self, fmt: &mut ::std::fmt::Formatter)
                -> Result<(), ::std::fmt::Error> {
                fmt.debug_struct(stringify!($name))
                 $(.field(stringify!($field_name), &self.$field_name()))*
                   .finish()
            }
        }
    )
}<|endoftext|>


<commit_before>use crate::runtime::handle::Handle;
use crate::runtime::shell::Shell;
use crate::runtime::{blocking, io, time, Callback, Runtime, Spawner};

use std::fmt;
#[cfg(not(loom))]
use std::sync::Arc;

/// Builds Tokio Runtime with custom configuration values.
///
/// Methods can be chained in order to set the configuration values. The
/// Runtime is constructed by calling [`build`].
///
/// New instances of `Builder` are obtained via [`Builder::new`].
///
/// See function level documentation for details on the various configuration
/// settings.
///
/// [`build`]: #method.build
/// [`Builder::new`]: #method.new
///
/// # Examples
///
/// ```
/// use tokio::runtime::Builder;
///
/// fn main() {
///     // build Runtime
///     let runtime = Builder::new()
///         .num_threads(4)
///         .thread_name("my-custom-name")
///         .thread_stack_size(3 * 1024 * 1024)
///         .build()
///         .unwrap();
///
///     // use runtime ...
/// }
/// ```
pub struct Builder {
    /// The task execution model to use.
    kind: Kind,

    /// Whether or not to enable the I/O driver
    enable_io: bool,

    /// Whether or not to enable the time driver
    enable_time: bool,

    /// The number of worker threads.
    ///
    /// Only used when not using the current-thread executor.
    num_threads: usize,

    /// Name used for threads spawned by the runtime.
    pub(super) thread_name: String,

    /// Stack size used for threads spawned by the runtime.
    pub(super) thread_stack_size: Option<usize>,

    /// Callback to run after each thread starts.
    pub(super) after_start: Option<Callback>,

    /// To run before each worker thread stops
    pub(super) before_stop: Option<Callback>,
}

#[derive(Debug, Clone, Copy)]
enum Kind {
    Shell,
    #[cfg(feature = "rt-core")]
    Basic,
    #[cfg(feature = "rt-threaded")]
    ThreadPool,
}

impl Builder {
    /// Returns a new runtime builder initialized with default configuration
    /// values.
    ///
    /// Configuration methods can be chained on the return value.
    pub fn new() -> Builder {
        Builder {
            // No task execution by default
            kind: Kind::Shell,

            // I/O defaults to "off"
            enable_io: false,

            // Time defaults to "off"
            enable_time: false,

            // Default to use an equal number of threads to number of CPU cores
            num_threads: crate::loom::sys::num_cpus(),

            // Default thread name
            thread_name: "tokio-runtime-worker".into(),

            // Do not set a stack size by default
            thread_stack_size: None,

            // No worker thread callbacks
            after_start: None,
            before_stop: None,
        }
    }

    /// Enable both I/O and time drivers.
    ///
    /// Doing this is a shorthand for calling `enable_io` and `enable_time`
    /// individually. If additional components are added to Tokio in the future,
    /// `enable_all` will include these future components.
    ///
    /// # Examples
    ///
    /// ```
    /// use tokio::runtime;
    ///
    /// let rt = runtime::Builder::new()
    ///     .enable_all()
    ///     .build()
    ///     .unwrap();
    /// ```
    pub fn enable_all(&mut self) -> &mut Self {
        #[cfg(feature = "io-driver")]
        self.enable_io();
        #[cfg(feature = "time")]
        self.enable_time();

        self
    }

    /// Set the maximum number of worker threads for the `Runtime`'s thread pool.
    ///
    /// This must be a number between 1 and 32,768 though it is advised to keep
    /// this value on the smaller side.
    ///
    /// The default value is the number of cores available to the system.
    ///
    /// # Examples
    ///
    /// ```
    /// use tokio::runtime;
    ///
    /// let rt = runtime::Builder::new()
    ///     .num_threads(4)
    ///     .build()
    ///     .unwrap();
    /// ```
    pub fn num_threads(&mut self, val: usize) -> &mut Self {
        self.num_threads = val;
        self
    }

    /// Use a simpler scheduler that runs all tasks on the current-thread.
    ///
    /// The executor and all necessary drivers will all be run on the current
    /// thread during `block_on` calls.
    #[cfg(feature = "rt-core")]
    pub fn basic_scheduler(&mut self) -> &mut Self {
        self.kind = Kind::Basic;
        self
    }

    /// Use a multi-threaded scheduler for executing tasks.
    #[cfg(feature = "rt-threaded")]
    pub fn threaded_scheduler(&mut self) -> &mut Self {
        self.kind = Kind::ThreadPool;
        self
    }

    /// Set name of threads spawned by the `Runtime`'s thread pool.
    ///
    /// The default name is "tokio-runtime-worker".
    ///
    /// # Examples
    ///
    /// ```
    /// # use tokio::runtime;
    ///
    /// # pub fn main() {
    /// let rt = runtime::Builder::new()
    ///     .thread_name("my-pool")
    ///     .build();
    /// # }
    /// ```
    pub fn thread_name(&mut self, val: impl Into<String>) -> &mut Self {
        self.thread_name = val.into();
        self
    }

    /// Set the stack size (in bytes) for worker threads.
    ///
    /// The actual stack size may be greater than this value if the platform
    /// specifies minimal stack size.
    ///
    /// The default stack size for spawned threads is 2 MiB, though this
    /// particular stack size is subject to change in the future.
    ///
    /// # Examples
    ///
    /// ```
    /// # use tokio::runtime;
    ///
    /// # pub fn main() {
    /// let rt = runtime::Builder::new()
    ///     .thread_stack_size(32 * 1024)
    ///     .build();
    /// # }
    /// ```
    pub fn thread_stack_size(&mut self, val: usize) -> &mut Self {
        self.thread_stack_size = Some(val);
        self
    }

    /// Execute function `f` after each thread is started but before it starts
    /// doing work.
    ///
    /// This is intended for bookkeeping and monitoring use cases.
    ///
    /// # Examples
    ///
    /// ```
    /// # use tokio::runtime;
    ///
    /// # pub fn main() {
    /// let runtime = runtime::Builder::new()
    ///     .on_thread_start(|| {
    ///         println!("thread started");
    ///     })
    ///     .build();
    /// # }
    /// ```
    #[cfg(not(loom))]
    pub fn on_thread_start<F>(&mut self, f: F) -> &mut Self
    where
        F: Fn() + Send + Sync + 'static,
    {
        self.after_start = Some(Arc::new(f));
        self
    }

    /// Execute function `f` before each thread stops.
    ///
    /// This is intended for bookkeeping and monitoring use cases.
    ///
    /// # Examples
    ///
    /// ```
    /// # use tokio::runtime;
    ///
    /// # pub fn main() {
    /// let runtime = runtime::Builder::new()
    ///     .on_thread_stop(|| {
    ///         println!("thread stopping");
    ///     })
    ///     .build();
    /// # }
    /// ```
    #[cfg(not(loom))]
    pub fn on_thread_stop<F>(&mut self, f: F) -> &mut Self
    where
        F: Fn() + Send + Sync + 'static,
    {
        self.before_stop = Some(Arc::new(f));
        self
    }

    /// Create the configured `Runtime`.
    ///
    /// The returned `ThreadPool` instance is ready to spawn tasks.
    ///
    /// # Examples
    ///
    /// ```
    /// use tokio::runtime::Builder;
    ///
    /// let mut rt = Builder::new().build().unwrap();
    ///
    /// rt.block_on(async {
    ///     println!("Hello from the Tokio runtime");
    /// });
    /// ```
    pub fn build(&mut self) -> io::Result<Runtime> {
        match self.kind {
            Kind::Shell => self.build_shell_runtime(),
            #[cfg(feature = "rt-core")]
            Kind::Basic => self.build_basic_runtime(),
            #[cfg(feature = "rt-threaded")]
            Kind::ThreadPool => self.build_threaded_runtime(),
        }
    }

    fn build_shell_runtime(&mut self) -> io::Result<Runtime> {
        use crate::runtime::Kind;

        let clock = time::create_clock();

        // Create I/O driver
        let (io_driver, io_handle) = io::create_driver(self.enable_io)?;
        let (driver, time_handle) = time::create_driver(self.enable_time, io_driver, clock.clone());

        let spawner = Spawner::Shell;

        let blocking_pool =
            blocking::create_blocking_pool(self, &spawner, &io_handle, &time_handle, &clock);
        let blocking_spawner = blocking_pool.spawner().clone();

        Ok(Runtime {
            kind: Kind::Shell(Shell::new(driver)),
            handle: Handle {
                spawner,
                io_handle,
                time_handle,
                clock,
                blocking_spawner,
            },
            blocking_pool,
        })
    }
}

cfg_io_driver! {
    impl Builder {
        /// Enable the I/O driver.
        ///
        /// Doing this enables using net, process, signal, and some I/O types on
        /// the runtime.
        ///
        /// # Examples
        ///
        /// ```
        /// use tokio::runtime;
        ///
        /// let rt = runtime::Builder::new()
        ///     .enable_io()
        ///     .build()
        ///     .unwrap();
        /// ```
        pub fn enable_io(&mut self) -> &mut Self {
            self.enable_io = true;
            self
        }
    }
}

cfg_time! {
    impl Builder {
        /// Enable the time driver.
        ///
        /// Doing this enables using `tokio::time` on the runtime.
        ///
        /// # Examples
        ///
        /// ```
        /// use tokio::runtime;
        ///
        /// let rt = runtime::Builder::new()
        ///     .enable_time()
        ///     .build()
        ///     .unwrap();
        /// ```
        pub fn enable_time(&mut self) -> &mut Self {
            self.enable_time = true;
            self
        }
    }
}

cfg_rt_core! {
    impl Builder {
        fn build_basic_runtime(&mut self) -> io::Result<Runtime> {
            use crate::runtime::{BasicScheduler, Kind};

            let clock = time::create_clock();

            // Create I/O driver
            let (io_driver, io_handle) = io::create_driver(self.enable_io)?;

            let (driver, time_handle) = time::create_driver(self.enable_time, io_driver, clock.clone());

            // And now put a single-threaded scheduler on top of the timer. When
            // there are no futures ready to do something, it'll let the timer or
            // the reactor to generate some new stimuli for the futures to continue
            // in their life.
            let scheduler = BasicScheduler::new(driver);
            let spawner = Spawner::Basic(scheduler.spawner());

            // Blocking pool
            let blocking_pool = blocking::create_blocking_pool(self, &spawner, &io_handle, &time_handle, &clock);
            let blocking_spawner = blocking_pool.spawner().clone();

            Ok(Runtime {
                kind: Kind::Basic(scheduler),
                handle: Handle {
                    spawner,
                    io_handle,
                    time_handle,
                    clock,
                    blocking_spawner,
                },
                blocking_pool,
            })
        }
    }
}

cfg_rt_threaded! {
    impl Builder {
        fn build_threaded_runtime(&mut self) -> io::Result<Runtime> {
            use crate::runtime::{Kind, ThreadPool};
            use crate::runtime::park::Parker;

            let clock = time::create_clock();

            let (io_driver, io_handle) = io::create_driver(self.enable_io)?;
            let (driver, time_handle) = time::create_driver(self.enable_time, io_driver, clock.clone());
            let (scheduler, workers) = ThreadPool::new(self.num_threads, Parker::new(driver));
            let spawner = Spawner::ThreadPool(scheduler.spawner().clone());

            // Create the blocking pool
            let blocking_pool = blocking::create_blocking_pool(self, &spawner, &io_handle, &time_handle, &clock);
            let blocking_spawner = blocking_pool.spawner().clone();

            // Spawn the thread pool workers
            workers.spawn(&blocking_spawner);

            Ok(Runtime {
                kind: Kind::ThreadPool(scheduler),
                handle: Handle {
                    spawner,
                    io_handle,
                    time_handle,
                    clock,
                    blocking_spawner: blocking_spawner.clone(),
                },
                blocking_pool,
            })
        }
    }
}

impl Default for Builder {
    fn default() -> Self {
        Self::new()
    }
}

impl fmt::Debug for Builder {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt.debug_struct("Builder")
            .field("kind", &self.kind)
            .field("num_threads", &self.num_threads)
            .field("thread_name", &self.thread_name)
            .field("thread_stack_size", &self.thread_stack_size)
            .field("after_start", &self.after_start.as_ref().map(|_| "..."))
            .field("before_stop", &self.after_start.as_ref().map(|_| "..."))
            .finish()
    }
}
<commit_msg>doc: fix `runtime::Builder` example (#1841)<commit_after>use crate::runtime::handle::Handle;
use crate::runtime::shell::Shell;
use crate::runtime::{blocking, io, time, Callback, Runtime, Spawner};

use std::fmt;
#[cfg(not(loom))]
use std::sync::Arc;

/// Builds Tokio Runtime with custom configuration values.
///
/// Methods can be chained in order to set the configuration values. The
/// Runtime is constructed by calling [`build`].
///
/// New instances of `Builder` are obtained via [`Builder::new`].
///
/// See function level documentation for details on the various configuration
/// settings.
///
/// [`build`]: #method.build
/// [`Builder::new`]: #method.new
///
/// # Examples
///
/// ```
/// use tokio::runtime::Builder;
///
/// fn main() {
///     // build runtime
///     let runtime = Builder::new()
///         .threaded_scheduler()
///         .num_threads(4)
///         .thread_name("my-custom-name")
///         .thread_stack_size(3 * 1024 * 1024)
///         .build()
///         .unwrap();
///
///     // use runtime ...
/// }
/// ```
pub struct Builder {
    /// The task execution model to use.
    kind: Kind,

    /// Whether or not to enable the I/O driver
    enable_io: bool,

    /// Whether or not to enable the time driver
    enable_time: bool,

    /// The number of worker threads.
    ///
    /// Only used when not using the current-thread executor.
    num_threads: usize,

    /// Name used for threads spawned by the runtime.
    pub(super) thread_name: String,

    /// Stack size used for threads spawned by the runtime.
    pub(super) thread_stack_size: Option<usize>,

    /// Callback to run after each thread starts.
    pub(super) after_start: Option<Callback>,

    /// To run before each worker thread stops
    pub(super) before_stop: Option<Callback>,
}

#[derive(Debug, Clone, Copy)]
enum Kind {
    Shell,
    #[cfg(feature = "rt-core")]
    Basic,
    #[cfg(feature = "rt-threaded")]
    ThreadPool,
}

impl Builder {
    /// Returns a new runtime builder initialized with default configuration
    /// values.
    ///
    /// Configuration methods can be chained on the return value.
    pub fn new() -> Builder {
        Builder {
            // No task execution by default
            kind: Kind::Shell,

            // I/O defaults to "off"
            enable_io: false,

            // Time defaults to "off"
            enable_time: false,

            // Default to use an equal number of threads to number of CPU cores
            num_threads: crate::loom::sys::num_cpus(),

            // Default thread name
            thread_name: "tokio-runtime-worker".into(),

            // Do not set a stack size by default
            thread_stack_size: None,

            // No worker thread callbacks
            after_start: None,
            before_stop: None,
        }
    }

    /// Enable both I/O and time drivers.
    ///
    /// Doing this is a shorthand for calling `enable_io` and `enable_time`
    /// individually. If additional components are added to Tokio in the future,
    /// `enable_all` will include these future components.
    ///
    /// # Examples
    ///
    /// ```
    /// use tokio::runtime;
    ///
    /// let rt = runtime::Builder::new()
    ///     .enable_all()
    ///     .build()
    ///     .unwrap();
    /// ```
    pub fn enable_all(&mut self) -> &mut Self {
        #[cfg(feature = "io-driver")]
        self.enable_io();
        #[cfg(feature = "time")]
        self.enable_time();

        self
    }

    /// Set the maximum number of worker threads for the `Runtime`'s thread pool.
    ///
    /// This must be a number between 1 and 32,768 though it is advised to keep
    /// this value on the smaller side.
    ///
    /// The default value is the number of cores available to the system.
    ///
    /// # Examples
    ///
    /// ```
    /// use tokio::runtime;
    ///
    /// let rt = runtime::Builder::new()
    ///     .num_threads(4)
    ///     .build()
    ///     .unwrap();
    /// ```
    pub fn num_threads(&mut self, val: usize) -> &mut Self {
        self.num_threads = val;
        self
    }

    /// Use a simpler scheduler that runs all tasks on the current-thread.
    ///
    /// The executor and all necessary drivers will all be run on the current
    /// thread during `block_on` calls.
    #[cfg(feature = "rt-core")]
    pub fn basic_scheduler(&mut self) -> &mut Self {
        self.kind = Kind::Basic;
        self
    }

    /// Use a multi-threaded scheduler for executing tasks.
    #[cfg(feature = "rt-threaded")]
    pub fn threaded_scheduler(&mut self) -> &mut Self {
        self.kind = Kind::ThreadPool;
        self
    }

    /// Set name of threads spawned by the `Runtime`'s thread pool.
    ///
    /// The default name is "tokio-runtime-worker".
    ///
    /// # Examples
    ///
    /// ```
    /// # use tokio::runtime;
    ///
    /// # pub fn main() {
    /// let rt = runtime::Builder::new()
    ///     .thread_name("my-pool")
    ///     .build();
    /// # }
    /// ```
    pub fn thread_name(&mut self, val: impl Into<String>) -> &mut Self {
        self.thread_name = val.into();
        self
    }

    /// Set the stack size (in bytes) for worker threads.
    ///
    /// The actual stack size may be greater than this value if the platform
    /// specifies minimal stack size.
    ///
    /// The default stack size for spawned threads is 2 MiB, though this
    /// particular stack size is subject to change in the future.
    ///
    /// # Examples
    ///
    /// ```
    /// # use tokio::runtime;
    ///
    /// # pub fn main() {
    /// let rt = runtime::Builder::new()
    ///     .thread_stack_size(32 * 1024)
    ///     .build();
    /// # }
    /// ```
    pub fn thread_stack_size(&mut self, val: usize) -> &mut Self {
        self.thread_stack_size = Some(val);
        self
    }

    /// Execute function `f` after each thread is started but before it starts
    /// doing work.
    ///
    /// This is intended for bookkeeping and monitoring use cases.
    ///
    /// # Examples
    ///
    /// ```
    /// # use tokio::runtime;
    ///
    /// # pub fn main() {
    /// let runtime = runtime::Builder::new()
    ///     .on_thread_start(|| {
    ///         println!("thread started");
    ///     })
    ///     .build();
    /// # }
    /// ```
    #[cfg(not(loom))]
    pub fn on_thread_start<F>(&mut self, f: F) -> &mut Self
    where
        F: Fn() + Send + Sync + 'static,
    {
        self.after_start = Some(Arc::new(f));
        self
    }

    /// Execute function `f` before each thread stops.
    ///
    /// This is intended for bookkeeping and monitoring use cases.
    ///
    /// # Examples
    ///
    /// ```
    /// # use tokio::runtime;
    ///
    /// # pub fn main() {
    /// let runtime = runtime::Builder::new()
    ///     .on_thread_stop(|| {
    ///         println!("thread stopping");
    ///     })
    ///     .build();
    /// # }
    /// ```
    #[cfg(not(loom))]
    pub fn on_thread_stop<F>(&mut self, f: F) -> &mut Self
    where
        F: Fn() + Send + Sync + 'static,
    {
        self.before_stop = Some(Arc::new(f));
        self
    }

    /// Create the configured `Runtime`.
    ///
    /// The returned `ThreadPool` instance is ready to spawn tasks.
    ///
    /// # Examples
    ///
    /// ```
    /// use tokio::runtime::Builder;
    ///
    /// let mut rt = Builder::new().build().unwrap();
    ///
    /// rt.block_on(async {
    ///     println!("Hello from the Tokio runtime");
    /// });
    /// ```
    pub fn build(&mut self) -> io::Result<Runtime> {
        match self.kind {
            Kind::Shell => self.build_shell_runtime(),
            #[cfg(feature = "rt-core")]
            Kind::Basic => self.build_basic_runtime(),
            #[cfg(feature = "rt-threaded")]
            Kind::ThreadPool => self.build_threaded_runtime(),
        }
    }

    fn build_shell_runtime(&mut self) -> io::Result<Runtime> {
        use crate::runtime::Kind;

        let clock = time::create_clock();

        // Create I/O driver
        let (io_driver, io_handle) = io::create_driver(self.enable_io)?;
        let (driver, time_handle) = time::create_driver(self.enable_time, io_driver, clock.clone());

        let spawner = Spawner::Shell;

        let blocking_pool =
            blocking::create_blocking_pool(self, &spawner, &io_handle, &time_handle, &clock);
        let blocking_spawner = blocking_pool.spawner().clone();

        Ok(Runtime {
            kind: Kind::Shell(Shell::new(driver)),
            handle: Handle {
                spawner,
                io_handle,
                time_handle,
                clock,
                blocking_spawner,
            },
            blocking_pool,
        })
    }
}

cfg_io_driver! {
    impl Builder {
        /// Enable the I/O driver.
        ///
        /// Doing this enables using net, process, signal, and some I/O types on
        /// the runtime.
        ///
        /// # Examples
        ///
        /// ```
        /// use tokio::runtime;
        ///
        /// let rt = runtime::Builder::new()
        ///     .enable_io()
        ///     .build()
        ///     .unwrap();
        /// ```
        pub fn enable_io(&mut self) -> &mut Self {
            self.enable_io = true;
            self
        }
    }
}

cfg_time! {
    impl Builder {
        /// Enable the time driver.
        ///
        /// Doing this enables using `tokio::time` on the runtime.
        ///
        /// # Examples
        ///
        /// ```
        /// use tokio::runtime;
        ///
        /// let rt = runtime::Builder::new()
        ///     .enable_time()
        ///     .build()
        ///     .unwrap();
        /// ```
        pub fn enable_time(&mut self) -> &mut Self {
            self.enable_time = true;
            self
        }
    }
}

cfg_rt_core! {
    impl Builder {
        fn build_basic_runtime(&mut self) -> io::Result<Runtime> {
            use crate::runtime::{BasicScheduler, Kind};

            let clock = time::create_clock();

            // Create I/O driver
            let (io_driver, io_handle) = io::create_driver(self.enable_io)?;

            let (driver, time_handle) = time::create_driver(self.enable_time, io_driver, clock.clone());

            // And now put a single-threaded scheduler on top of the timer. When
            // there are no futures ready to do something, it'll let the timer or
            // the reactor to generate some new stimuli for the futures to continue
            // in their life.
            let scheduler = BasicScheduler::new(driver);
            let spawner = Spawner::Basic(scheduler.spawner());

            // Blocking pool
            let blocking_pool = blocking::create_blocking_pool(self, &spawner, &io_handle, &time_handle, &clock);
            let blocking_spawner = blocking_pool.spawner().clone();

            Ok(Runtime {
                kind: Kind::Basic(scheduler),
                handle: Handle {
                    spawner,
                    io_handle,
                    time_handle,
                    clock,
                    blocking_spawner,
                },
                blocking_pool,
            })
        }
    }
}

cfg_rt_threaded! {
    impl Builder {
        fn build_threaded_runtime(&mut self) -> io::Result<Runtime> {
            use crate::runtime::{Kind, ThreadPool};
            use crate::runtime::park::Parker;

            let clock = time::create_clock();

            let (io_driver, io_handle) = io::create_driver(self.enable_io)?;
            let (driver, time_handle) = time::create_driver(self.enable_time, io_driver, clock.clone());
            let (scheduler, workers) = ThreadPool::new(self.num_threads, Parker::new(driver));
            let spawner = Spawner::ThreadPool(scheduler.spawner().clone());

            // Create the blocking pool
            let blocking_pool = blocking::create_blocking_pool(self, &spawner, &io_handle, &time_handle, &clock);
            let blocking_spawner = blocking_pool.spawner().clone();

            // Spawn the thread pool workers
            workers.spawn(&blocking_spawner);

            Ok(Runtime {
                kind: Kind::ThreadPool(scheduler),
                handle: Handle {
                    spawner,
                    io_handle,
                    time_handle,
                    clock,
                    blocking_spawner: blocking_spawner.clone(),
                },
                blocking_pool,
            })
        }
    }
}

impl Default for Builder {
    fn default() -> Self {
        Self::new()
    }
}

impl fmt::Debug for Builder {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt.debug_struct("Builder")
            .field("kind", &self.kind)
            .field("num_threads", &self.num_threads)
            .field("thread_name", &self.thread_name)
            .field("thread_stack_size", &self.thread_stack_size)
            .field("after_start", &self.after_start.as_ref().map(|_| "..."))
            .field("before_stop", &self.after_start.as_ref().map(|_| "..."))
            .finish()
    }
}
<|endoftext|>


<commit_before>/* 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/. */

//! The `servo` test application.
//!
//! Creates a `Browser` instance with a simple implementation of
//! the compositor's `WindowMethods` to create a working web browser.
//!
//! This browser's implementation of `WindowMethods` is built on top
//! of [glutin], the cross-platform OpenGL utility and windowing
//! library.
//!
//! For the engine itself look next door in lib.rs.
//!
//! [glutin]: https://github.com/tomaka/glutin

#![feature(start)]

// The Servo engine
extern crate servo;
// Window graphics compositing and message dispatch
extern crate compositing;
// Servo networking
extern crate net;
// Servo common utilitiess
extern crate util;
// The window backed by glutin
extern crate glutin_app as app;
extern crate time;

#[cfg(target_os="android")]
#[macro_use]
extern crate android_glue;

use std::rc::Rc;
use util::opts;
use net::resource_task;
use servo::Browser;
use compositing::windowing::WindowEvent;

#[cfg(target_os="android")]
use std::borrow::ToOwned;

fn main() {
    // Parse the command line options and store them globally
    if opts::from_cmdline_args(&*get_args()) {
        setup_logging();

        // Possibly interpret the `HOST_FILE` environment variable
        resource_task::global_init();

        let window = if opts::get().headless {
            None
        } else {
            Some(app::create_window(std::ptr::null_mut()))
        };

        // Our wrapper around `Browser` that also implements some
        // callbacks required by the glutin window implementation.
        let mut browser = BrowserWrapper {
            browser: Browser::new(window.clone()),
        };

        maybe_register_glutin_resize_handler(&window, &mut browser);

        browser.browser.handle_event(WindowEvent::InitializeCompositing);

        // Feed events from the window to the browser until the browser
        // says to stop.
        loop {
            let should_continue = match window {
                None => browser.browser.handle_event(WindowEvent::Idle),
                Some(ref window) => {
                    let event = window.wait_events();
                    browser.browser.handle_event(event)
                }
            };
            if !should_continue {
                break
            }
        };

        maybe_unregister_glutin_resize_handler(&window);

        let BrowserWrapper {
            browser
        } = browser;
        browser.shutdown();
    }
}

fn maybe_register_glutin_resize_handler(window: &Option<Rc<app::window::Window>>,
                                        browser: &mut BrowserWrapper) {
    match *window {
        None => {}
        Some(ref window) => {
            unsafe {
                window.set_nested_event_loop_listener(browser);
            }
        }
    }
}

fn maybe_unregister_glutin_resize_handler(window: &Option<Rc<app::window::Window>>) {
    match *window {
        None => {}
        Some(ref window) => {
            unsafe {
                window.remove_nested_event_loop_listener();
            }
        }
    }
}

struct BrowserWrapper {
    browser: Browser,
}

impl app::NestedEventLoopListener for BrowserWrapper {
    fn handle_event_from_nested_event_loop(&mut self, event: WindowEvent) -> bool {
        let is_resize = match event {
            WindowEvent::Resize(..) => true,
            _ => false,
        };
        if !self.browser.handle_event(event) {
            return false
        }
        if is_resize {
            self.browser.repaint_synchronously()
        }
        true
    }
}

#[cfg(target_os="android")]
fn setup_logging() {
    android::setup_logging();
}

#[cfg(not(target_os="android"))]
fn setup_logging() {
}

#[cfg(target_os="android")]
fn get_args() -> Vec<String> {
    vec![
        "servo".to_owned(),
        "http://en.wikipedia.org/wiki/Rust".to_owned()
    ]
}

#[cfg(not(target_os="android"))]
fn get_args() -> Vec<String> {
    use std::env;
    env::args().collect()
}

// This macro must be used at toplevel because it defines a nested
// module, but macros can only accept identifiers - not paths -
// preventing the expansion of this macro within the android module
// without use of an additionl stub method or other hackery.
#[cfg(target_os = "android")]
android_start!(main);

#[cfg(target_os = "android")]
mod android {
    extern crate libc;
    extern crate android_glue;

    use self::libc::c_int;
    use std::borrow::ToOwned;

    pub fn setup_logging() {
        use self::libc::consts::os::posix88::{STDERR_FILENO, STDOUT_FILENO};
        //os::setenv("RUST_LOG", "servo,gfx,msg,util,layers,js,std,rt,extra");
        redirect_output(STDERR_FILENO);
        redirect_output(STDOUT_FILENO);
    }

    struct FilePtr(*mut self::libc::types::common::c95::FILE);

    unsafe impl Send for FilePtr {}

    fn redirect_output(file_no: c_int) {
        use self::libc::funcs::posix88::unistd::{pipe, dup2};
        use self::libc::funcs::posix88::stdio::fdopen;
        use self::libc::funcs::c95::stdio::fgets;
        use util::task::spawn_named;
        use std::ffi::CString;
        use std::str::from_utf8;

        unsafe {
            let mut pipes: [c_int; 2] = [ 0, 0 ];
            pipe(pipes.as_mut_ptr());
            dup2(pipes[1], file_no);
            let mode = CString::new("r").unwrap();
            let input_file = FilePtr(fdopen(pipes[0], mode.as_ptr()));
            spawn_named("android-logger".to_owned(), move || {
                loop {
                    let mut read_buffer: Vec<u8> = vec!();
                    read_buffer.reserve(1024);
                    let FilePtr(input_file) = input_file;
                    fgets(read_buffer.as_mut_ptr() as *mut i8, read_buffer.len() as i32, input_file);
                    let cs = CString::new(read_buffer).unwrap();
                    match from_utf8(cs.as_bytes()) {
                        Ok(s) => android_glue::write_log(s),
                        _ => {}
                    }
                }
            });
        }
    }

}
<commit_msg>Update the environment variable debug code for new Rust<commit_after>/* 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/. */

//! The `servo` test application.
//!
//! Creates a `Browser` instance with a simple implementation of
//! the compositor's `WindowMethods` to create a working web browser.
//!
//! This browser's implementation of `WindowMethods` is built on top
//! of [glutin], the cross-platform OpenGL utility and windowing
//! library.
//!
//! For the engine itself look next door in lib.rs.
//!
//! [glutin]: https://github.com/tomaka/glutin

#![feature(start)]

// The Servo engine
extern crate servo;
// Window graphics compositing and message dispatch
extern crate compositing;
// Servo networking
extern crate net;
// Servo common utilitiess
extern crate util;
// The window backed by glutin
extern crate glutin_app as app;
extern crate time;

#[cfg(target_os="android")]
#[macro_use]
extern crate android_glue;

use std::rc::Rc;
use util::opts;
use net::resource_task;
use servo::Browser;
use compositing::windowing::WindowEvent;

#[cfg(target_os="android")]
use std::borrow::ToOwned;

fn main() {
    // Parse the command line options and store them globally
    if opts::from_cmdline_args(&*get_args()) {
        setup_logging();

        // Possibly interpret the `HOST_FILE` environment variable
        resource_task::global_init();

        let window = if opts::get().headless {
            None
        } else {
            Some(app::create_window(std::ptr::null_mut()))
        };

        // Our wrapper around `Browser` that also implements some
        // callbacks required by the glutin window implementation.
        let mut browser = BrowserWrapper {
            browser: Browser::new(window.clone()),
        };

        maybe_register_glutin_resize_handler(&window, &mut browser);

        browser.browser.handle_event(WindowEvent::InitializeCompositing);

        // Feed events from the window to the browser until the browser
        // says to stop.
        loop {
            let should_continue = match window {
                None => browser.browser.handle_event(WindowEvent::Idle),
                Some(ref window) => {
                    let event = window.wait_events();
                    browser.browser.handle_event(event)
                }
            };
            if !should_continue {
                break
            }
        };

        maybe_unregister_glutin_resize_handler(&window);

        let BrowserWrapper {
            browser
        } = browser;
        browser.shutdown();
    }
}

fn maybe_register_glutin_resize_handler(window: &Option<Rc<app::window::Window>>,
                                        browser: &mut BrowserWrapper) {
    match *window {
        None => {}
        Some(ref window) => {
            unsafe {
                window.set_nested_event_loop_listener(browser);
            }
        }
    }
}

fn maybe_unregister_glutin_resize_handler(window: &Option<Rc<app::window::Window>>) {
    match *window {
        None => {}
        Some(ref window) => {
            unsafe {
                window.remove_nested_event_loop_listener();
            }
        }
    }
}

struct BrowserWrapper {
    browser: Browser,
}

impl app::NestedEventLoopListener for BrowserWrapper {
    fn handle_event_from_nested_event_loop(&mut self, event: WindowEvent) -> bool {
        let is_resize = match event {
            WindowEvent::Resize(..) => true,
            _ => false,
        };
        if !self.browser.handle_event(event) {
            return false
        }
        if is_resize {
            self.browser.repaint_synchronously()
        }
        true
    }
}

#[cfg(target_os="android")]
fn setup_logging() {
    android::setup_logging();
}

#[cfg(not(target_os="android"))]
fn setup_logging() {
}

#[cfg(target_os="android")]
fn get_args() -> Vec<String> {
    vec![
        "servo".to_owned(),
        "http://en.wikipedia.org/wiki/Rust".to_owned()
    ]
}

#[cfg(not(target_os="android"))]
fn get_args() -> Vec<String> {
    use std::env;
    env::args().collect()
}

// This macro must be used at toplevel because it defines a nested
// module, but macros can only accept identifiers - not paths -
// preventing the expansion of this macro within the android module
// without use of an additionl stub method or other hackery.
#[cfg(target_os = "android")]
android_start!(main);

#[cfg(target_os = "android")]
mod android {
    extern crate libc;
    extern crate android_glue;

    use self::libc::c_int;
    use std::borrow::ToOwned;

    pub fn setup_logging() {
        use self::libc::consts::os::posix88::{STDERR_FILENO, STDOUT_FILENO};
        //use std::env;

        //env::set_var("RUST_LOG", "servo,gfx,msg,util,layers,js,std,rt,extra");
        redirect_output(STDERR_FILENO);
        redirect_output(STDOUT_FILENO);
    }

    struct FilePtr(*mut self::libc::types::common::c95::FILE);

    unsafe impl Send for FilePtr {}

    fn redirect_output(file_no: c_int) {
        use self::libc::funcs::posix88::unistd::{pipe, dup2};
        use self::libc::funcs::posix88::stdio::fdopen;
        use self::libc::funcs::c95::stdio::fgets;
        use util::task::spawn_named;
        use std::ffi::CString;
        use std::str::from_utf8;

        unsafe {
            let mut pipes: [c_int; 2] = [ 0, 0 ];
            pipe(pipes.as_mut_ptr());
            dup2(pipes[1], file_no);
            let mode = CString::new("r").unwrap();
            let input_file = FilePtr(fdopen(pipes[0], mode.as_ptr()));
            spawn_named("android-logger".to_owned(), move || {
                loop {
                    let mut read_buffer: Vec<u8> = vec!();
                    read_buffer.reserve(1024);
                    let FilePtr(input_file) = input_file;
                    fgets(read_buffer.as_mut_ptr() as *mut i8, read_buffer.len() as i32, input_file);
                    let cs = CString::new(read_buffer).unwrap();
                    match from_utf8(cs.as_bytes()) {
                        Ok(s) => android_glue::write_log(s),
                        _ => {}
                    }
                }
            });
        }
    }

}
<|endoftext|>


<commit_before>//! Treiber stacks.

use std::sync::atomic;
use std::ptr;
use {Atomic, Guard};

/// A Treiber stack.
///
/// Treiber stacks are one way to implement concurrent LIFO stack.
///
/// Treiber stacks builds on linked lists. They are lock-free and non-blocking. It can be compared
/// to transactional memory in that it repeats operations, if another thread changes it while.
///
/// The ABA problem is of course addressed through the API of this crate.
pub struct Treiber<T> {
    /// The head node.
    head: Atomic<Node<T>>,
}

impl<T> Drop for Treiber<T> {
    fn drop(&mut self) {
        // Due to the nature of Treiber stacks, there are no active guards of things within the
        // structure. They're all gone, thus we can safely mess with the inner structure.

        unsafe {
            let ptr = self.head.get_inner_mut().get_mut();

            if !ptr.is_null() {
                // Call destructors on the stack.
                (**ptr).destroy();
                // Finally deallocate the pointer itself.
                drop(Box::from_raw(*ptr));
                // Set it to null to prevent `Atomic`'s destructor from running.
                *ptr = ptr::null_mut();
            }
        }
    }
}

impl<T> Treiber<T> {
    /// Create a new, empty Treiber stack.
    pub fn new() -> Treiber<T> {
        Treiber {
            head: Atomic::default(),
        }
    }

    /// Get the top item of the stack without popping it.
    ///
    /// This is several times faster than `pop`.
    ///
    /// # Memory usage
    ///
    /// This keeps alive what corresponds to the whole stack at the time of the call, such that it
    /// won't be dropped until the guard is dead.
    pub fn top(&self) -> Option<Guard<T>> {
        // Just load the head and map it.
        self.head.load(atomic::Ordering::Acquire).map(|guard| guard.map(|node| &node.item))
    }

    /// Pop an item from the stack.
    pub fn pop(&self) -> Option<Guard<T>> {
        // TODO: Use `catch {}` here when it lands.
        // Read the head snapshot.
        let mut snapshot = self.head.load(atomic::Ordering::Acquire);

        // Unless the head snapshot is `None`, try to replace it with the tail.
        while let Some(node) = snapshot {
            // Attempt to replace the head with the tail of the head.
            match unsafe {
                self.head.compare_and_swap_raw(
                    node.as_raw(),
                    node.next as *mut Node<T>,
                    atomic::Ordering::Release,
                )
            } {
                // It succeeded; return the item.
                Ok(_) => return Some(node.map(|x| &x.item)),
                // It failed, update the head snapshot and continue.
                Err(new) => snapshot = new,
            }
        }

        // As the head was empty, there is nothing to pop.
        None
    }

    /// Push an item to the stack.
    pub fn push(&self, item: T)
    where T: 'static {
        // Load the head snapshot.
        let mut snapshot = self.head.load(atomic::Ordering::Relaxed);
        let mut snapshot_ptr: Option<*const Node<T>>;

        // TODO: Use `catch {}` here when it lands.
        // Construct a node, which will be the new head.
        let mut node = Box::new(Node {
            item: item,
            // Placeholder; we will replace it with an actual value in the loop.
            next: ptr::null(),
        });

        loop {
            // Derive the nullable snapshot pointer from the head snapshot.
            snapshot_ptr = snapshot.as_ref().map(Guard::as_raw);
            // Construct the next-pointer of the new node from the head snapshot.
            node.next = snapshot_ptr.unwrap_or(ptr::null());

            // TODO: This should be something that ignores the guard creation when the CAS
            //       succeeds, because it's expensive to do and not used anyway. It should be easy
            //       enough to implement, but I am struggling to come up with a good name for the
            //       method.

            // CAS from the read pointer to the new head.
            match self.head.compare_and_swap(snapshot_ptr, Some(node), atomic::Ordering::Release) {
                // If it succeeds, the item has been pushed.
                Ok(_) => break,
                // If it fails, we will retry the CAS with updated values.
                Err((new_head, Some(node2))) => {
                    // Update the head snapshot.
                    snapshot = new_head;
                    // Put the box we gave back to the variable where it belongs.
                    node = node2;
                },
                // This should never be reached as we gave an argument which was unconditionally
                // `Some`.
                _ => unreachable!(),
            }
        }
    }
}

/// A node in the stack.
struct Node<T> {
    /// The data this node holds.
    item: T,
    /// The next node.
    next: *const Node<T>,
}

impl<T> Node<T> {
    /// Destroy the node and its precessors.
    ///
    /// This doesn't call the destructor on `T`.
    ///
    /// The reason this isn't replaced by a recursive destructor through `Drop` is that such thing
    /// would cause double drop, as the earlier top element getting dropped would cause the whole
    /// list to be dropped.
    ///
    /// # Safety
    ///
    /// As this can be called multiple times, it is marked unsafe.
    unsafe fn destroy(&mut self) {
        // FIXME: Since this is recursive (and although it is likely optimized out), there might be
        //        cases where this leads to stack overflow, given correct compilation flags and
        //        sufficiently many elements.

        // Recursively drop the next node, if it exists.
        if !self.next.is_null() {
            drop(Box::from_raw(self.next as *mut Node<T>));
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::thread;
    use std::sync::Arc;
    use std::sync::atomic::AtomicUsize;

    #[derive(Clone)]
    struct Dropper {
        d: Arc<AtomicUsize>,
    }

    impl Drop for Dropper {
        fn drop(&mut self) {
            self.d.fetch_add(1, atomic::Ordering::Relaxed);
        }
    }

    #[test]
    fn simple1() {
        let stack = Treiber::new();
        assert!(stack.top().is_none());

        stack.push(1);
        assert_eq!(*stack.top().unwrap(), 1);
        stack.push(200);
        assert_eq!(*stack.top().unwrap(), 200);
        stack.push(44);
        assert_eq!(*stack.top().unwrap(), 44);

        assert_eq!(*stack.pop().unwrap(), 44);
        assert_eq!(*stack.pop().unwrap(), 200);
        assert_eq!(*stack.pop().unwrap(), 1);
        assert!(stack.pop().is_none());

        ::gc();
    }

    #[test]
    fn simple2() {
        let stack = Treiber::new();
        assert!(stack.top().is_none());

        for _ in 0..16 {
            stack.push(1);
            stack.push(200);
            stack.push(44);

            assert_eq!(*stack.top().unwrap(), 44);
            assert_eq!(*stack.pop().unwrap(), 44);
            assert_eq!(*stack.top().unwrap(), 200);
            assert_eq!(*stack.pop().unwrap(), 200);
            assert_eq!(*stack.top().unwrap(), 44);
            stack.push(20000);

            assert_eq!(*stack.top().unwrap(), 20000);
            assert_eq!(*stack.pop().unwrap(), 20000);
            assert_eq!(*stack.top().unwrap(), 1);
            assert_eq!(*stack.pop().unwrap(), 1);

            assert!(stack.top().is_none());

            assert!(stack.pop().is_none());
            assert!(stack.pop().is_none());
            assert!(stack.pop().is_none());
            assert!(stack.pop().is_none());
        }

        ::gc();
    }

    #[test]
    fn simple3() {
        let stack = Treiber::new();
        assert!(stack.top().is_none());

        for i in 0..10000 {
            stack.push(i);
        }

        for i in (0..10000).rev() {
            assert_eq!(*stack.top().unwrap(), i);
            assert_eq!(*stack.pop().unwrap(), i);
        }

        for i in 0..10000 {
            stack.push(i);
        }

        for i in (0..10000).rev() {
            assert_eq!(*stack.top().unwrap(), i);
            assert_eq!(*stack.pop().unwrap(), i);
        }

        assert!(stack.top().is_none());
        assert!(stack.pop().is_none());
        assert!(stack.pop().is_none());
        assert!(stack.pop().is_none());
        assert!(stack.pop().is_none());
    }

    #[test]
    fn push_pop() {
        let stack = Arc::new(Treiber::new());
        let mut j = Vec::new();
        for _ in 0..16 {
            let s = stack.clone();
            j.push(thread::spawn(move || {
                for _ in 0..10_000_000 {
                    s.push(23);
                    assert_eq!(*s.top().unwrap(), 23);
                    assert_eq!(*s.pop().unwrap(), 23);
                }
            }));
        }

        for i in j {
            i.join().unwrap();
        }
    }

    #[test]
    fn increment() {
        let stack = Arc::new(Treiber::<u64>::new());
        stack.push(0);
        let mut j = Vec::new();

        // 16 times, we add the numbers from 0 to 1000 to the only element in the stack.
        for _ in 0..16 {
            let s = stack.clone();
            j.push(thread::spawn(move || {
                for n in 0..1001 {
                    loop {
                        if let Some(x) = s.pop() {
                            s.push(*x + n);
                            break;
                        }
                    }
                }
            }));
        }

        for i in j {
            i.join().unwrap();
        }

        assert_eq!(*stack.pop().unwrap(), 16 * 1000 * 1001 / 2);
    }

    #[test]
    fn sum() {
        let stack = Arc::new(Treiber::<i64>::new());
        let mut j = Vec::new();

        for _ in 0..1000 {
            stack.push(10);
        }

        // We preserve the sum of the stack's elements.
        for _ in 0..16 {
            let s = stack.clone();
            j.push(thread::spawn(move || {
                for _ in 0..100000 {
                    loop {
                        if let Some(a) = s.pop() {
                            loop {
                                if let Some(b) = s.pop() {
                                    s.push(*a + 1);
                                    s.push(*b - 1);

                                    break;
                                }
                            }

                            break;
                        }
                    }
                }
            }));
        }

        for i in j {
            i.join().unwrap();
        }

        let mut sum = 0;
        while let Some(x) = stack.pop() {
            sum += *x;
        }
        assert_eq!(sum, 10000);
    }

    #[test]
    fn drop() {
        let drops = Arc::new(AtomicUsize::default());
        let stack = Arc::new(Treiber::new());

        let d = Dropper {
            d: drops.clone(),
        };

        let mut j = Vec::new();
        for _ in 0..16 {
            let d = d.clone();
            let stack = stack.clone();

            j.push(thread::spawn(move || {
                for _ in 0..20 {
                    stack.push(d.clone());
                }

                stack.pop();
                stack.pop();
            }))
        }

        for i in j {
            i.join().unwrap();
        }

        ::gc();
        // The 16 are for the `d` variable in the loop above.
        assert_eq!(drops.load(atomic::Ordering::Relaxed), 32 + 16);

        // Drop the last arc.
        let _ = stack;
        ::gc();

        assert_eq!(drops.load(atomic::Ordering::Relaxed), 200 + 16);
    }
}
<commit_msg>Revert last commit as `conc::sync::Treiber::top()` is unsound as it can cause double drop.<commit_after>//! Treiber stacks.

use std::sync::atomic;
use std::ptr;
use {Atomic, Guard};

/// A Treiber stack.
///
/// Treiber stacks are one way to implement concurrent LIFO stack.
///
/// Treiber stacks builds on linked lists. They are lock-free and non-blocking. It can be compared
/// to transactional memory in that it repeats operations, if another thread changes it while.
///
/// The ABA problem is of course addressed through the API of this crate.
pub struct Treiber<T> {
    /// The head node.
    head: Atomic<Node<T>>,
}

impl<T> Drop for Treiber<T> {
    fn drop(&mut self) {
        // Due to the nature of Treiber stacks, there are no active guards of things within the
        // structure. They're all gone, thus we can safely mess with the inner structure.

        unsafe {
            let ptr = self.head.get_inner_mut().get_mut();

            if !ptr.is_null() {
                // Call destructors on the stack.
                (**ptr).destroy();
                // Finally deallocate the pointer itself.
                drop(Box::from_raw(*ptr));
                // Set it to null to prevent `Atomic`'s destructor from running.
                *ptr = ptr::null_mut();
            }
        }
    }
}

impl<T> Treiber<T> {
    /// Create a new, empty Treiber stack.
    pub fn new() -> Treiber<T> {
        Treiber {
            head: Atomic::default(),
        }
    }

    /// Pop an item from the stack.
    // TODO: Change this return type.
    pub fn pop(&self) -> Option<Guard<T>> {
        // TODO: Use `catch {}` here when it lands.
        // Read the head snapshot.
        let mut snapshot = self.head.load(atomic::Ordering::Acquire);

        // Unless the head snapshot is `None`, try to replace it with the tail.
        while let Some(node) = snapshot {
            // Attempt to replace the head with the tail of the head.
            match unsafe {
                self.head.compare_and_swap_raw(
                    node.as_raw(),
                    node.next as *mut Node<T>,
                    atomic::Ordering::Release,
                )
            } {
                // It succeeded; return the item.
                Ok(_) => return Some(node.map(|x| &x.item)),
                // It failed, update the head snapshot and continue.
                Err(new) => snapshot = new,
            }
        }

        // As the head was empty, there is nothing to pop.
        None
    }

    /// Push an item to the stack.
    pub fn push(&self, item: T)
    where T: 'static {
        // Load the head snapshot.
        let mut snapshot = self.head.load(atomic::Ordering::Relaxed);
        let mut snapshot_ptr: Option<*const Node<T>>;

        // TODO: Use `catch {}` here when it lands.
        // Construct a node, which will be the new head.
        let mut node = Box::new(Node {
            item: item,
            // Placeholder; we will replace it with an actual value in the loop.
            next: ptr::null(),
        });

        loop {
            // Derive the nullable snapshot pointer from the head snapshot.
            snapshot_ptr = snapshot.as_ref().map(Guard::as_raw);
            // Construct the next-pointer of the new node from the head snapshot.
            node.next = snapshot_ptr.unwrap_or(ptr::null());

            // TODO: This should be something that ignores the guard creation when the CAS
            //       succeeds, because it's expensive to do and not used anyway. It should be easy
            //       enough to implement, but I am struggling to come up with a good name for the
            //       method.

            // CAS from the read pointer to the new head.
            match self.head.compare_and_swap(snapshot_ptr, Some(node), atomic::Ordering::Release) {
                // If it succeeds, the item has been pushed.
                Ok(_) => break,
                // If it fails, we will retry the CAS with updated values.
                Err((new_head, Some(node2))) => {
                    // Update the head snapshot.
                    snapshot = new_head;
                    // Put the box we gave back to the variable where it belongs.
                    node = node2;
                },
                // This should never be reached as we gave an argument which was unconditionally
                // `Some`.
                _ => unreachable!(),
            }
        }
    }
}

/// A node in the stack.
struct Node<T> {
    /// The data this node holds.
    item: T,
    /// The next node.
    next: *const Node<T>,
}

impl<T> Node<T> {
    /// Destroy the node and its precessors.
    ///
    /// This doesn't call the destructor on `T`.
    ///
    /// # Safety
    ///
    /// As this can be called multiple times, it is marked unsafe.
    unsafe fn destroy(&mut self) {
        // FIXME: Since this is recursive (and although it is likely optimized out), there might be
        //        cases where this leads to stack overflow, given correct compilation flags and
        //        sufficiently many elements.

        // Recursively drop the next node, if it exists.
        if !self.next.is_null() {
            drop(Box::from_raw(self.next as *mut Node<T>));
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::thread;
    use std::sync::Arc;
    use std::sync::atomic::AtomicUsize;

    #[derive(Clone)]
    struct Dropper {
        d: Arc<AtomicUsize>,
    }

    impl Drop for Dropper {
        fn drop(&mut self) {
            self.d.fetch_add(1, atomic::Ordering::Relaxed);
        }
    }

    #[test]
    fn simple1() {
        let stack = Treiber::new();

        stack.push(1);
        stack.push(200);
        stack.push(44);

        assert_eq!(*stack.pop().unwrap(), 44);
        assert_eq!(*stack.pop().unwrap(), 200);
        assert_eq!(*stack.pop().unwrap(), 1);
        assert!(stack.pop().is_none());

        ::gc();
    }

    #[test]
    fn simple2() {
        let stack = Treiber::new();

        for _ in 0..16 {
            stack.push(1);
            stack.push(200);
            stack.push(44);

            assert_eq!(*stack.pop().unwrap(), 44);
            assert_eq!(*stack.pop().unwrap(), 200);
            stack.push(20000);

            assert_eq!(*stack.pop().unwrap(), 20000);
            assert_eq!(*stack.pop().unwrap(), 1);

            assert!(stack.pop().is_none());
            assert!(stack.pop().is_none());
            assert!(stack.pop().is_none());
            assert!(stack.pop().is_none());
        }

        ::gc();
    }

    #[test]
    fn simple3() {
        let stack = Treiber::new();

        for i in 0..10000 {
            stack.push(i);
        }

        for i in (0..10000).rev() {
            assert_eq!(*stack.pop().unwrap(), i);
        }

        for i in 0..10000 {
            stack.push(i);
        }

        for i in (0..10000).rev() {
            assert_eq!(*stack.pop().unwrap(), i);
        }

        assert!(stack.pop().is_none());
        assert!(stack.pop().is_none());
        assert!(stack.pop().is_none());
        assert!(stack.pop().is_none());
    }

    #[test]
    fn push_pop() {
        let stack = Arc::new(Treiber::new());
        let mut j = Vec::new();
        for _ in 0..16 {
            let s = stack.clone();
            j.push(thread::spawn(move || {
                for _ in 0..10_000_000 {
                    s.push(23);
                    assert_eq!(*s.pop().unwrap(), 23);
                }
            }));
        }

        for i in j {
            i.join().unwrap();
        }
    }

    #[test]
    fn increment() {
        let stack = Arc::new(Treiber::<u64>::new());
        stack.push(0);
        let mut j = Vec::new();

        // 16 times, we add the numbers from 0 to 1000 to the only element in the stack.
        for _ in 0..16 {
            let s = stack.clone();
            j.push(thread::spawn(move || {
                for n in 0..1001 {
                    loop {
                        if let Some(x) = s.pop() {
                            s.push(*x + n);
                            break;
                        }
                    }
                }
            }));
        }

        for i in j {
            i.join().unwrap();
        }

        assert_eq!(*stack.pop().unwrap(), 16 * 1000 * 1001 / 2);
    }

    #[test]
    fn sum() {
        let stack = Arc::new(Treiber::<i64>::new());
        let mut j = Vec::new();

        for _ in 0..1000 {
            stack.push(10);
        }

        // We preserve the sum of the stack's elements.
        for _ in 0..16 {
            let s = stack.clone();
            j.push(thread::spawn(move || {
                for _ in 0..100000 {
                    loop {
                        if let Some(a) = s.pop() {
                            loop {
                                if let Some(b) = s.pop() {
                                    s.push(*a + 1);
                                    s.push(*b - 1);

                                    break;
                                }
                            }

                            break;
                        }
                    }
                }
            }));
        }

        for i in j {
            i.join().unwrap();
        }

        let mut sum = 0;
        while let Some(x) = stack.pop() {
            sum += *x;
        }
        assert_eq!(sum, 10000);
    }

    #[test]
    fn drop() {
        let drops = Arc::new(AtomicUsize::default());
        let stack = Arc::new(Treiber::new());

        let d = Dropper {
            d: drops.clone(),
        };

        let mut j = Vec::new();
        for _ in 0..16 {
            let d = d.clone();
            let stack = stack.clone();

            j.push(thread::spawn(move || {
                for _ in 0..20 {
                    stack.push(d.clone());
                }

                stack.pop();
                stack.pop();
            }))
        }

        for i in j {
            i.join().unwrap();
        }

        ::gc();
        // The 16 are for the `d` variable in the loop above.
        assert_eq!(drops.load(atomic::Ordering::Relaxed), 32 + 16);

        // Drop the last arc.
        let _ = stack;
        ::gc();

        assert_eq!(drops.load(atomic::Ordering::Relaxed), 200 + 16);
    }
}
<|endoftext|>


<commit_before>use std::ops::Not;

use types::*;
use requests::*;

/// Use this method to forward messages of any kind.
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize)]
pub struct ForwardMessage<'c, 'f> {
    chat_id: ChatRef<'c>,
    from_chat_id: ChatRef<'f>,
    #[serde(skip_serializing_if = "Not::not")]
    disable_notification: bool,
    message_id: MessageId,
}

impl<'c, 'f> Request for ForwardMessage<'c, 'f> {
    type Response = Message;
    type RawResponse = Message;

    fn map(raw: Self::RawResponse) -> Self::Response {
        raw
    }

    fn name() -> &'static str {
        "forwardMessage"
    }
}

impl<'c, 'f> ForwardMessage<'c, 'f> {
    pub fn new<M, F, T>(message: M, from: F, to: T) -> Self
        where M: ToMessageId, F: ToChatRef<'f>, T: ToChatRef<'c> {

        ForwardMessage {
            chat_id: to.to_chat_ref(),
            from_chat_id: from.to_chat_ref(),
            disable_notification: false,
            message_id: message.to_message_id(),
        }
    }

    pub fn disable_notification(mut self) -> Self {
        self.disable_notification = true;
        self
    }
}

pub trait CanForwardMessage {
    fn forward<'c, 'f, T>(&self, to: T) -> ForwardMessage<'c, 'f> where T: ToChatRef<'c>;
}

impl CanForwardMessage for Message {
    fn forward<'c, 'f, T>(&self, to: T) -> ForwardMessage<'c, 'f> where T: ToChatRef<'c> {
        ForwardMessage::new(self, &self.chat, to)
    }
}
<commit_msg>refactor: implement CanForwardMessage for ToMessageId + ToSourceChat<commit_after>use std::ops::Not;

use types::*;
use requests::*;

/// Use this method to forward messages of any kind.
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize)]
pub struct ForwardMessage<'c, 'f> {
    chat_id: ChatRef<'c>,
    from_chat_id: ChatRef<'f>,
    #[serde(skip_serializing_if = "Not::not")]
    disable_notification: bool,
    message_id: MessageId,
}

impl<'c, 'f> Request for ForwardMessage<'c, 'f> {
    type Response = Message;
    type RawResponse = Message;

    fn map(raw: Self::RawResponse) -> Self::Response {
        raw
    }

    fn name() -> &'static str {
        "forwardMessage"
    }
}

impl<'c, 'f> ForwardMessage<'c, 'f> {
    pub fn new<M, F, T>(message: M, from: F, to: T) -> Self
        where M: ToMessageId, F: ToChatRef<'f>, T: ToChatRef<'c> {

        ForwardMessage {
            chat_id: to.to_chat_ref(),
            from_chat_id: from.to_chat_ref(),
            disable_notification: false,
            message_id: message.to_message_id(),
        }
    }

    pub fn disable_notification(mut self) -> Self {
        self.disable_notification = true;
        self
    }
}

pub trait CanForwardMessage {
    fn forward<'c, 'f, T>(&self, to: T) -> ForwardMessage<'c, 'f> where T: ToChatRef<'c>;
}

impl<M> CanForwardMessage for M where M: ToMessageId + ToSourceChat {
    fn forward<'c, 'f, T>(&self, to: T) -> ForwardMessage<'c, 'f> where T: ToChatRef<'c> {
        ForwardMessage::new(self.to_message_id(), self.to_source_chat(), to)
    }
}
<|endoftext|>