<commit_before>use crate::Value;

impl PartialEq<str> for Value {
    /// Compare `str` with YAML value
    ///
    /// # Examples
    ///
    /// ```
    /// # use serde_yaml::Value;
    /// assert!(Value::String("lorem".into()) == *"lorem");
    /// ```
    fn eq(&self, other: &str) -> bool {
        self.as_str().map_or(false, |s| s == other)
    }
}

impl<'a> PartialEq<&'a str> for Value {
    /// Compare `&str` with YAML value
    ///
    /// # Examples
    ///
    /// ```
    /// # use serde_yaml::Value;
    /// assert!(Value::String("lorem".into()) == "lorem");
    /// ```
    fn eq(&self, other: &&str) -> bool {
        self.as_str().map_or(false, |s| s == *other)
    }
}

impl PartialEq<Value> for str {
    /// Compare YAML value with `str`
    ///
    /// # Examples
    ///
    /// ```
    /// # use serde_yaml::Value;
    /// assert!(*"lorem" == Value::String("lorem".into()));
    /// ```
    fn eq(&self, other: &Value) -> bool {
        other.as_str().map_or(false, |s| s == self)
    }
}

impl<'a> PartialEq<Value> for &'a str {
    /// Compare `&str` with YAML value
    ///
    /// # Examples
    ///
    /// ```
    /// # use serde_yaml::Value;
    /// assert!("lorem" == Value::String("lorem".into()));
    /// ```
    fn eq(&self, other: &Value) -> bool {
        other.as_str().map_or(false, |s| s == *self)
    }
}

impl PartialEq<String> for Value {
    /// Compare YAML value with String
    ///
    /// # Examples
    ///
    /// ```
    /// # use serde_yaml::Value;
    /// assert!(Value::String("lorem".into()) == "lorem".to_string());
    /// ```
    fn eq(&self, other: &String) -> bool {
        self.as_str().map_or(false, |s| s == other)
    }
}

impl PartialEq<Value> for String {
    /// Compare `String` with YAML value
    ///
    /// # Examples
    ///
    /// ```
    /// # use serde_yaml::Value;
    /// assert!("lorem".to_string() == Value::String("lorem".into()));
    /// ```
    fn eq(&self, other: &Value) -> bool {
        other.as_str().map_or(false, |s| s == self)
    }
}

impl PartialEq<bool> for Value {
    /// Compare YAML value with bool
    ///
    /// # Examples
    ///
    /// ```
    /// # use serde_yaml::Value;
    /// assert!(Value::Bool(true) == true);
    /// ```
    fn eq(&self, other: &bool) -> bool {
        self.as_bool().map_or(false, |b| b == *other)
    }
}

macro_rules! partialeq_numeric {
    ($([$($ty:ty)*], $conversion:ident, $base:ty)*) => {
        $($(
            impl PartialEq<$ty> for Value {
                fn eq(&self, other: &$ty) -> bool {
                    self.$conversion().map_or(false, |i| i == (*other as $base))
                }
            }

            impl PartialEq<Value> for $ty {
                fn eq(&self, other: &Value) -> bool {
                    other.$conversion().map_or(false, |i| i == (*self as $base))
                }
            }

            impl<'a> PartialEq<$ty> for &'a Value {
                fn eq(&self, other: &$ty) -> bool {
                    self.$conversion().map_or(false, |i| i == (*other as $base))
                }
            }

            impl<'a> PartialEq<$ty> for &'a mut Value {
                fn eq(&self, other: &$ty) -> bool {
                    self.$conversion().map_or(false, |i| i == (*other as $base))
                }
            }
        )*)*
    }
}

partialeq_numeric! {
    [i8 i16 i32 i64 isize], as_i64, i64
    [u8 u16 u32 u64 usize], as_u64, u64
    [f32 f64], as_f64, f64
}
<commit_msg>Remove wrong direction PartialEq impls<commit_after>use crate::Value;

impl PartialEq<str> for Value {
    /// Compare `str` with YAML value
    ///
    /// # Examples
    ///
    /// ```
    /// # use serde_yaml::Value;
    /// assert!(Value::String("lorem".into()) == *"lorem");
    /// ```
    fn eq(&self, other: &str) -> bool {
        self.as_str().map_or(false, |s| s == other)
    }
}

impl<'a> PartialEq<&'a str> for Value {
    /// Compare `&str` with YAML value
    ///
    /// # Examples
    ///
    /// ```
    /// # use serde_yaml::Value;
    /// assert!(Value::String("lorem".into()) == "lorem");
    /// ```
    fn eq(&self, other: &&str) -> bool {
        self.as_str().map_or(false, |s| s == *other)
    }
}

impl PartialEq<String> for Value {
    /// Compare YAML value with String
    ///
    /// # Examples
    ///
    /// ```
    /// # use serde_yaml::Value;
    /// assert!(Value::String("lorem".into()) == "lorem".to_string());
    /// ```
    fn eq(&self, other: &String) -> bool {
        self.as_str().map_or(false, |s| s == other)
    }
}

impl PartialEq<bool> for Value {
    /// Compare YAML value with bool
    ///
    /// # Examples
    ///
    /// ```
    /// # use serde_yaml::Value;
    /// assert!(Value::Bool(true) == true);
    /// ```
    fn eq(&self, other: &bool) -> bool {
        self.as_bool().map_or(false, |b| b == *other)
    }
}

macro_rules! partialeq_numeric {
    ($([$($ty:ty)*], $conversion:ident, $base:ty)*) => {
        $($(
            impl PartialEq<$ty> for Value {
                fn eq(&self, other: &$ty) -> bool {
                    self.$conversion().map_or(false, |i| i == (*other as $base))
                }
            }

            impl<'a> PartialEq<$ty> for &'a Value {
                fn eq(&self, other: &$ty) -> bool {
                    self.$conversion().map_or(false, |i| i == (*other as $base))
                }
            }

            impl<'a> PartialEq<$ty> for &'a mut Value {
                fn eq(&self, other: &$ty) -> bool {
                    self.$conversion().map_or(false, |i| i == (*other as $base))
                }
            }
        )*)*
    }
}

partialeq_numeric! {
    [i8 i16 i32 i64 isize], as_i64, i64
    [u8 u16 u32 u64 usize], as_u64, u64
    [f32 f64], as_f64, f64
}
<|endoftext|>


<commit_before>use std::io::Write;
use std::path::PathBuf;

use unshare::{Command, Stdio, Namespace};

use process_util::env_path_find;
use super::graphs::{Graph, NodeLinks};
use super::graphs::NodeLinks::{Full, Isolate, DropSome};
use super::super::container::nsutil::set_namespace;

fn _rule<W: Write, S:AsRef<str>>(out: &mut W, data: S) -> Result<(), String> {
    debug!("Rule: {}", data.as_ref());
    (writeln!(out, "{}", data.as_ref()))
    .map_err(|e| format!("Error piping firewall rule {:?}: {}",
        data.as_ref(), e))
}

pub fn apply_graph(graph: Graph) -> Result<(), String> {
    for (ip, node) in graph.nodes.iter() {
        try!(apply_node(ip, node));
    }
    Ok(())
}

fn apply_node(ip: &String, node: &NodeLinks) -> Result<(), String> {
    try!(set_namespace(
        format!("/tmp/vagga/namespaces/net.{}", ip), Namespace::Net)
        .map_err(|e| format!("Can't set namespace: {}", e)));
    let mut cmd = Command::new(env_path_find("iptables-restore")
        .unwrap_or(PathBuf::from("/sbin/iptables-restore")));
    cmd.stdin(Stdio::piped());
    debug!("Running {:?} for {}", cmd, ip);
    let mut prc = try!(cmd.spawn()
        .map_err(|e| format!("Can't run iptables-restore {:?}: {}", cmd, e)));
    {
        let ref mut pipe = prc.stdin.take().unwrap();

        try!(_rule(pipe, "*filter"));
        match *node {
            Full => {
                // Empty chains with ACCEPT default (except FORWARD, we expect
                // user doesn't use FORWARD, i.e. nested networks)
                try!(_rule(pipe, ":INPUT ACCEPT [0:0]"));
                try!(_rule(pipe, ":FORWARD DROP [0:0]"));
                try!(_rule(pipe, ":OUTPUT ACCEPT [0:0]"));
            }
            Isolate => {
                // The DROP default and accept packets to/from bridge as an
                // exception
                try!(_rule(pipe, ":INPUT DROP [0:0]"));
                try!(_rule(pipe, ":FORWARD DROP [0:0]"));
                try!(_rule(pipe, ":OUTPUT DROP [0:0]"));
                try!(_rule(pipe,
                    format!("-A INPUT -s 172.18.0.254/32 -j ACCEPT")));
                try!(_rule(pipe,
                    format!("-A OUTPUT -d 172.18.0.254/32 -j ACCEPT")));
            }
            DropSome(ref peers) => {
                // Empty chains with ACCEPT default (except FORWARD, we expect
                // user doesn't use FORWARD, i.e. nested networks)
                try!(_rule(pipe, ":INPUT ACCEPT [0:0]"));
                try!(_rule(pipe, ":FORWARD DROP [0:0]"));
                try!(_rule(pipe, ":OUTPUT ACCEPT [0:0]"));
                for peer in peers.iter() {
                    try!(_rule(pipe,
                        format!("-A INPUT -s {}/32 -d {}/32 -j DROP",
                        ip, peer)));
                }
            }
        }
        try!(_rule(pipe, "COMMIT"));
    }
    match prc.wait() {
        Ok(status) if status.success() => Ok(()),
        e => Err(format!("Error running iptables-restore: {:?}", e)),
    }
}
<commit_msg>Fix `split` and `disjoint` network commands<commit_after>use std::io::Write;
use std::path::PathBuf;

use unshare::{Command, Stdio, Namespace};

use process_util::env_path_find;
use super::graphs::{Graph, NodeLinks};
use super::graphs::NodeLinks::{Full, Isolate, DropSome};
use super::super::container::nsutil::set_namespace;

fn _rule<W: Write, S:AsRef<str>>(out: &mut W, data: S) -> Result<(), String> {
    debug!("Rule: {}", data.as_ref());
    (writeln!(out, "{}", data.as_ref()))
    .map_err(|e| format!("Error piping firewall rule {:?}: {}",
        data.as_ref(), e))
}

pub fn apply_graph(graph: Graph) -> Result<(), String> {
    for (ip, node) in graph.nodes.iter() {
        try!(apply_node(ip, node));
    }
    Ok(())
}

fn apply_node(ip: &String, node: &NodeLinks) -> Result<(), String> {
    try!(set_namespace(
        format!("/tmp/vagga/namespaces/net.{}", ip), Namespace::Net)
        .map_err(|e| format!("Can't set namespace: {}", e)));
    let mut cmd = Command::new(env_path_find("iptables-restore")
        .unwrap_or(PathBuf::from("/sbin/iptables-restore")));
    cmd.stdin(Stdio::piped());
    debug!("Running {:?} for {}", cmd, ip);
    let mut prc = try!(cmd.spawn()
        .map_err(|e| format!("Can't run iptables-restore {:?}: {}", cmd, e)));
    {
        let ref mut pipe = prc.stdin.take().unwrap();

        try!(_rule(pipe, "*filter"));
        match *node {
            Full => {
                // Empty chains with ACCEPT default (except FORWARD, we expect
                // user doesn't use FORWARD, i.e. nested networks)
                try!(_rule(pipe, ":INPUT ACCEPT [0:0]"));
                try!(_rule(pipe, ":FORWARD DROP [0:0]"));
                try!(_rule(pipe, ":OUTPUT ACCEPT [0:0]"));
            }
            Isolate => {
                // The DROP default and accept packets to/from bridge as an
                // exception
                try!(_rule(pipe, ":INPUT DROP [0:0]"));
                try!(_rule(pipe, ":FORWARD DROP [0:0]"));
                try!(_rule(pipe, ":OUTPUT DROP [0:0]"));
                try!(_rule(pipe,
                    format!("-A INPUT -s 172.18.0.254/32 -j ACCEPT")));
                try!(_rule(pipe,
                    format!("-A OUTPUT -d 172.18.0.254/32 -j ACCEPT")));
            }
            DropSome(ref peers) => {
                // Empty chains with ACCEPT default (except FORWARD, we expect
                // user doesn't use FORWARD, i.e. nested networks)
                try!(_rule(pipe, ":INPUT ACCEPT [0:0]"));
                try!(_rule(pipe, ":FORWARD DROP [0:0]"));
                try!(_rule(pipe, ":OUTPUT ACCEPT [0:0]"));
                for peer in peers.iter() {
                    try!(_rule(pipe,
                        format!("-A INPUT -s {}/32 -d {}/32 -j DROP",
                        peer, ip)));
                }
            }
        }
        try!(_rule(pipe, "COMMIT"));
    }
    match prc.wait() {
        Ok(status) if status.success() => Ok(()),
        e => Err(format!("Error running iptables-restore: {:?}", e)),
    }
}
<|endoftext|>


<commit_before>//! The tags.

#![allow(non_upper_case_globals)]

macro_rules! implement {
    ($($const_name:ident: $tag_name:expr,)*) => (
        $(pub const $const_name: &'static str = $tag_name;)*
    );
}

implement! {
    Animate: "animate",
    AnimateColor: "animateColor",
    AnimateMotion: "animateMotion",
    AnimateTransform: "animateTransform",
    Circle: "circle",
    ClipPath: "clipPath",
    Definitions: "defs",
    Description: "desc",
    Ellipse: "ellipse",
    Filter: "filter",
    Group: "g",
    Image: "image",
    Line: "line",
    LinearGradient: "linearGradient",
    Link: "a",
    Marker: "marker",
    Mask: "mask",
    MotionPath: "mpath",
    Path: "path",
    Polygon: "polygon",
    Polyline: "polyline",
    RadialGradient: "radialGradient",
    Rectangle: "rect",
    Script: "script",
    Stop: "stop",
    Style: "style",
    SVG: "svg",
    Symbol: "symbol",
    Text: "text",
    TextPath: "textPath",
    Title: "title",
    Use: "use",
}
<commit_msg>Add documentation to the tags<commit_after>//! The tags.

#![allow(non_upper_case_globals)]

macro_rules! implement {
    ($($const_name:ident: $tag_name:expr,)*) => ($(
        #[doc = $tag_name]
        pub const $const_name: &'static str = $tag_name;
    )*);
}

implement! {
    Animate: "animate",
    AnimateColor: "animateColor",
    AnimateMotion: "animateMotion",
    AnimateTransform: "animateTransform",
    Circle: "circle",
    ClipPath: "clipPath",
    Definitions: "defs",
    Description: "desc",
    Ellipse: "ellipse",
    Filter: "filter",
    Group: "g",
    Image: "image",
    Line: "line",
    LinearGradient: "linearGradient",
    Link: "a",
    Marker: "marker",
    Mask: "mask",
    MotionPath: "mpath",
    Path: "path",
    Polygon: "polygon",
    Polyline: "polyline",
    RadialGradient: "radialGradient",
    Rectangle: "rect",
    Script: "script",
    Stop: "stop",
    Style: "style",
    SVG: "svg",
    Symbol: "symbol",
    Text: "text",
    TextPath: "textPath",
    Title: "title",
    Use: "use",
}
<|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/. */

use dom::bindings::utils::{Reflector, Reflectable};
use dom::window::Window;
use js::jsapi::JSContext;
use layout_interface::TrustedNodeAddress;

use std::cast;
use std::cell::RefCell;

pub struct JS<T> {
    priv ptr: RefCell<*mut T>
}

impl<T> Eq for JS<T> {
    fn eq(&self, other: &JS<T>) -> bool {
        self.ptr == other.ptr
    }
}

impl <T> Clone for JS<T> {
    fn clone(&self) -> JS<T> {
        JS {
            ptr: self.ptr.clone()
        }
    }
}

impl<T: Reflectable> JS<T> {
    pub fn new(obj: ~T,
               window:  &JS<Window>,
               wrap_fn: extern "Rust" fn(*JSContext, &JS<Window>, ~T) -> JS<T>) -> JS<T> {
        wrap_fn(window.get().get_cx(), window, obj)
    }

    pub unsafe fn from_raw(raw: *mut T) -> JS<T> {
        JS {
            ptr: RefCell::new(raw)
        }
    }

    pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> JS<T> {
        JS {
            ptr: RefCell::new(inner as *mut T)
        }
    }
}

impl<T: Reflectable> Reflectable for JS<T> {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        self.get().reflector()
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        self.get_mut().mut_reflector()
    }
}

impl<T> JS<T> {
    pub fn get<'a>(&'a self) -> &'a T {
        let borrowed = self.ptr.borrow();
        unsafe {
            &(**borrowed.get())
        }
    }

    pub fn get_mut<'a>(&'a mut self) -> &'a mut T {
        let mut borrowed = self.ptr.borrow_mut();
        unsafe {
            &mut (**borrowed.get())
        }
    }

    /// Returns an unsafe pointer to the interior of this JS object without touching the borrow
    /// flags. This is the only method that be safely accessed from layout. (The fact that this
    /// is unsafe is what necessitates the layout wrappers.)
    pub unsafe fn unsafe_get(&self) -> *mut T {
        cast::transmute_copy(&self.ptr)
    }
}

impl<From, To> JS<From> {
    //XXXjdm It would be lovely if this could be private.
    pub unsafe fn transmute(self) -> JS<To> {
        cast::transmute(self)
    }

    pub unsafe fn transmute_copy(&self) -> JS<To> {
        cast::transmute_copy(self)
    }
}
<commit_msg>Make JS<T>::clone inline.(fixes #1955)<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/. */

use dom::bindings::utils::{Reflector, Reflectable};
use dom::window::Window;
use js::jsapi::JSContext;
use layout_interface::TrustedNodeAddress;

use std::cast;
use std::cell::RefCell;

pub struct JS<T> {
    priv ptr: RefCell<*mut T>
}

impl<T> Eq for JS<T> {
    fn eq(&self, other: &JS<T>) -> bool {
        self.ptr == other.ptr
    }
}

impl <T> Clone for JS<T> {
    #[inline]
    fn clone(&self) -> JS<T> {
        JS {
            ptr: self.ptr.clone()
        }
    }
}

impl<T: Reflectable> JS<T> {
    pub fn new(obj: ~T,
               window:  &JS<Window>,
               wrap_fn: extern "Rust" fn(*JSContext, &JS<Window>, ~T) -> JS<T>) -> JS<T> {
        wrap_fn(window.get().get_cx(), window, obj)
    }

    pub unsafe fn from_raw(raw: *mut T) -> JS<T> {
        JS {
            ptr: RefCell::new(raw)
        }
    }

    pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> JS<T> {
        JS {
            ptr: RefCell::new(inner as *mut T)
        }
    }
}

impl<T: Reflectable> Reflectable for JS<T> {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        self.get().reflector()
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        self.get_mut().mut_reflector()
    }
}

impl<T> JS<T> {
    pub fn get<'a>(&'a self) -> &'a T {
        let borrowed = self.ptr.borrow();
        unsafe {
            &(**borrowed.get())
        }
    }

    pub fn get_mut<'a>(&'a mut self) -> &'a mut T {
        let mut borrowed = self.ptr.borrow_mut();
        unsafe {
            &mut (**borrowed.get())
        }
    }

    /// Returns an unsafe pointer to the interior of this JS object without touching the borrow
    /// flags. This is the only method that be safely accessed from layout. (The fact that this
    /// is unsafe is what necessitates the layout wrappers.)
    pub unsafe fn unsafe_get(&self) -> *mut T {
        cast::transmute_copy(&self.ptr)
    }
}

impl<From, To> JS<From> {
    //XXXjdm It would be lovely if this could be private.
    pub unsafe fn transmute(self) -> JS<To> {
        cast::transmute(self)
    }

    pub unsafe fn transmute_copy(&self) -> JS<To> {
        cast::transmute_copy(self)
    }
}
<|endoftext|>


<commit_before>#![allow(non_fmt_panic)]

macro_rules! assert_const {
    ($len:expr) => {
        assert!($len > 0);
        debug_assert!($len < 0);
    };
}

fn main() {
    assert!(true);
    assert!(false);
    assert!(true, "true message");
    assert!(false, "false message");

    let msg = "panic message";
    assert!(false, msg.to_uppercase());

    const B: bool = true;
    assert!(B);

    const C: bool = false;
    assert!(C);
    assert!(C, "C message");

    debug_assert!(true);
    // Don't lint this, since there is no better way for expressing "Only panic in debug mode".
    debug_assert!(false); // #3948
    assert_const!(3);
    assert_const!(-1);
}
<commit_msg>Add test for not linting on assert!(cfg!(..)).<commit_after>#![allow(non_fmt_panic)]

macro_rules! assert_const {
    ($len:expr) => {
        assert!($len > 0);
        debug_assert!($len < 0);
    };
}

fn main() {
    assert!(true);
    assert!(false);
    assert!(true, "true message");
    assert!(false, "false message");

    let msg = "panic message";
    assert!(false, msg.to_uppercase());

    const B: bool = true;
    assert!(B);

    const C: bool = false;
    assert!(C);
    assert!(C, "C message");

    debug_assert!(true);
    // Don't lint this, since there is no better way for expressing "Only panic in debug mode".
    debug_assert!(false); // #3948
    assert_const!(3);
    assert_const!(-1);

    // Don't lint on this:
    assert!(cfg!(feature = "hey") || cfg!(not(feature = "asdf")));
}
<|endoftext|>


<commit_before>//pub use r3d::landscape::*;
//pub use r3d::mesh::*;

#[feature(globs)];
#[feature(macro_rules)];
#[feature(default_type_params)];
#[allow(unused_imports)];
#[allow(unused_variable)];
#[allow(dead_code)];
#[allow(unreachable_code)];
#[allow(unused_unsafe)];
#[allow(unused_mut)];
#[allow(non_camel_case_types)];
#[macro_escape];

extern crate collections;
pub use std::str::raw::*;
pub use r3d::vecmath::*;
pub use std::vec;
pub use std::libc;
pub use std::libc::{c_int,c_char};
use shadertest::c_str;
use std::io;
use shadertest::*;
use r3d::gl::*;
use r3d::glut::*;

pub mod macros;	// must preceed others for macro visibility.
pub mod r3d;
pub mod shadertest;

// framework can be: Android, Glut, (iOS,..)

#[cfg(target_os = "android")]
extern { fn android_log_print(lvl:c_int,  s:*c_char);}

#[cfg(target_os = "android")]
fn log_print(level:int, s:&str) {
	unsafe {
		android_log_print(level as c_int, c_str(s));
	}
}

#[cfg(not(target_os = "android"))]
fn log_print(level:int, s:&str) {
	io::println(s);
}

static MAX_TOUCH_POINTERS:u32=12;

// TODO: These can be renamed away from android
// Its' really to be a superset of Android,iOS,Windows8,game-consoles,PC
struct AndroidInputSub {
	pointers:[((f32,f32,f32),u32),..12],
	accelerometer:(f32,f32,f32),
}

struct AndroidInput {
	// TODO: gamepad, keyboard... they do exist
	curr:AndroidInputSub,
	prev:AndroidInputSub
}
extern { fn android_get_inputs()->AndroidInput; }

// Desktop glut main loop, uses the app_create/display_create/render/display_destroy/destroy hooks; on android (iOS..) these same functions are just called by platform specific app loops
// It might be nice to make a rust trait object for all this,
// however this is language independant. One can glue any other framework specifics ontop.

#[cfg(not(target_os = "android"))]
pub fn main()
{
	unsafe {
		let mut argc:c_int=0;
		glutInit((&mut argc) as *mut std::libc::c_int,0 as **libc::c_char );

		glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
		glutInitWindowSize(1280,800);
		let win=verify!(glutCreateWindow(c_str("Rust ShaderTest")) isnt 0);

		let mut app = app_create(0,0 as **std::libc::c_char,1280,800);
		app_display_create(app);
		glDrawBuffer(GL_BACK);
		glutReshapeWindow(1024,1024);
		glEnable(GL_DEPTH_TEST);

		while true {
			glutMainLoopEvent();
			app_render(app);
			glFlush();
			glutSwapBuffers();
		}
		app_display_destroy(app);
		app_destroy(app);
	}
}

<commit_msg>added directory iteration<commit_after>//pub use r3d::landscape::*;
//pub use r3d::mesh::*;

#[feature(globs)];
#[feature(macro_rules)];
#[feature(default_type_params)];
#[allow(unused_imports)];
#[allow(unused_variable)];
#[allow(dead_code)];
#[allow(unreachable_code)];
#[allow(unused_unsafe)];
#[allow(unused_mut)];
#[allow(non_camel_case_types)];
#[macro_escape];

extern crate collections;
pub use std::str::raw::*;
pub use r3d::vecmath::*;
pub use std::vec;
pub use std::libc;
pub use std::libc::{c_int,c_char};
use shadertest::c_str;
use std::io;
use shadertest::*;
use r3d::gl::*;
use r3d::glut::*;

pub mod macros;	// must preceed others for macro visibility.
pub mod r3d;
pub mod shadertest;

// framework can be: Android, Glut, (iOS,..)

#[cfg(target_os = "android")]
extern { fn android_log_print(lvl:c_int,  s:*c_char);}

#[cfg(target_os = "android")]
fn log_print(level:int, s:&str) {
	unsafe {
		android_log_print(level as c_int, c_str(s));
	}
}

#[cfg(not(target_os = "android"))]
fn log_print(level:int, s:&str) {
	io::println(s);
}

static MAX_TOUCH_POINTERS:u32=12;

// TODO: These can be renamed away from android
// Its' really to be a superset of Android,iOS,Windows8,game-consoles,PC
struct AndroidInputSub {
	pointers:[((f32,f32,f32),u32),..12],
	accelerometer:(f32,f32,f32),
}

struct AndroidInput {
	// TODO: gamepad, keyboard... they do exist
	curr:AndroidInputSub,
	prev:AndroidInputSub
}
extern { fn android_get_inputs()->AndroidInput; }

//(add-to-list 'ac-sources 'ac-source-etags)

//(print ac-sources)
//(set 'ac-sources nil)
//(setq ac-sources '(ac-source-words-in-same-mode-buffers ac-source-etags))
//
//(ac-define-source mysource '((candidates . (list "FooBar" "AppleBar" "BazBanana"))))

//(add-to-list 'ac-sources 'mysource)

// (setq auto-complete-mode t)

// Desktop glut main loop, uses the app_create/display_create/render/display_destroy/destroy hooks; on android (iOS..) these same functions are just called by platform specific app loops
// It might be nice to make a rust trait object for all this,
// however this is language independant. One can glue any other framework specifics ontop.

#[cfg(not(target_os = "android"))]
pub fn main()
{
	unsafe {
		let mut argc:c_int=0;
		glutInit((&mut argc) as *mut std::libc::c_int,0 as **libc::c_char );

		glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
		glutInitWindowSize(1280,800);
		let win=verify!(glutCreateWindow(c_str("Rust ShaderTest")) isnt 0);

		let mut app = app_create(0,0 as **std::libc::c_char,1280,800);
		app_display_create(app);
		glDrawBuffer(GL_BACK);
		glutReshapeWindow(1024,1024);
		glEnable(GL_DEPTH_TEST);

		while true {
			glutMainLoopEvent();
			app_render(app);
			glFlush();
			glutSwapBuffers();
		}
		app_display_destroy(app);
		app_destroy(app);
	}
}

<|endoftext|>


<commit_before>//! # gpio module
//!
//! This module provides access to the GPIO of the stm32f0 board.
//! You can:
//!
//! * configure a PIN in Input or Output
//! * read or write the PIN depending on its configuration
//!
//! ## Examples
//!
//! ```
//! extern crate stm32f0_hal;
//!
//! use stm32f0_hal::gpio;
//!
// ! let p_in = gpio::Input::setup(gpio::Pin::PA1);
// ! let b = p_in.read();
// !
// ! let p_out = gpio::Output::setup(gpio::Pin::PA5);
// ! p_out.write(true);
//! ```

use cortex_m;

use stm32f0x2::{EXTI, GPIOA, GPIOB, GPIOC, NVIC, RCC};
use stm32f0x2::interrupt::Interrupt;

enum Mode {
    Input = 0b00,
    Output = 0b01,
}

/// GPIO Pin available
pub enum Pin {
    PA0,
    PA1,
    PA5,
    PB0,
    PB1,
    PB3,
    PB4,
    PB5,
    PB10,
    PB11,
    PC6,
    PC7,
    PC8,
    PC9,
}

/// Input Mode Pin
pub struct Input {
    pin: Pin,
}

impl Input {
    /// Setup a PIN in Input Mode
    pub fn setup(pin: Pin) -> Input {
        setup_pin(&pin, Mode::Input);
        Input { pin }
    }

    /// Read the state of a PIN
    pub fn read(&self) -> bool {
        unsafe {
            match self.pin {
                Pin::PA0 => (*GPIOA.get()).idr.read().idr0().bit(),
                Pin::PA1 => (*GPIOA.get()).idr.read().idr1().bit(),
                Pin::PA5 => (*GPIOA.get()).idr.read().idr5().bit(),
                Pin::PB0 => (*GPIOB.get()).idr.read().idr0().bit(),
                Pin::PB1 => (*GPIOB.get()).idr.read().idr1().bit(),
                Pin::PB3 => (*GPIOB.get()).idr.read().idr3().bit(),
                Pin::PB4 => (*GPIOB.get()).idr.read().idr4().bit(),
                Pin::PB5 => (*GPIOB.get()).idr.read().idr5().bit(),
                Pin::PB10 => (*GPIOB.get()).idr.read().idr10().bit(),
                Pin::PB11 => (*GPIOB.get()).idr.read().idr11().bit(),
                Pin::PC6 => (*GPIOC.get()).idr.read().idr6().bit(),
                Pin::PC7 => (*GPIOC.get()).idr.read().idr7().bit(),
                Pin::PC8 => (*GPIOC.get()).idr.read().idr8().bit(),
                Pin::PC9 => (*GPIOC.get()).idr.read().idr9().bit(),
            }
        }
    }

    pub fn init_interrupt(&self) {
        match self.pin {
            Pin::PA0 => cortex_m::interrupt::free(|cs| {
                let exti = EXTI.borrow(cs);
                let nvic = NVIC.borrow(cs);
                exti.rtsr.modify(|_, w| w.tr0().set_bit());
                exti.imr.modify(|_, w| w.mr0().set_bit());
                nvic.enable(Interrupt::EXTI0_1);
            }),
            Pin::PA1 => cortex_m::interrupt::free(|cs| {
                let exti = EXTI.borrow(cs);
                let nvic = NVIC.borrow(cs);
                exti.rtsr.modify(|_, w| w.tr1().set_bit());
                exti.imr.modify(|_, w| w.mr1().set_bit());
                nvic.enable(Interrupt::EXTI0_1);
            }),
            Pin::PA5 => cortex_m::interrupt::free(|cs| {
                let exti = EXTI.borrow(cs);
                let nvic = NVIC.borrow(cs);
                exti.rtsr.modify(|_, w| w.tr5().set_bit());
                exti.imr.modify(|_, w| w.mr5().set_bit());
                nvic.enable(Interrupt::EXTI4_15);
            }),
            Pin::PC7 => cortex_m::interrupt::free(|cs| {
                let exti = EXTI.borrow(cs);
                let nvic = NVIC.borrow(cs);
                exti.rtsr.modify(|_, w| w.tr7().set_bit());
                exti.imr.modify(|_, w| w.mr7().set_bit());
                nvic.enable(Interrupt::EXTI4_15);
            }),
            _ => panic!("Unsupported PIN!"),
        }
    }
}

/// Output Mode Pin
pub struct Output {
    pin: Pin,
}

impl Output {
    /// Setup a PIN in Output Mode
    pub fn setup(pin: Pin) -> Output {
        setup_pin(&pin, Mode::Output);
        Output { pin }
    }
    /// Set the PIN to high
    pub fn high(&mut self) {
        unsafe {
            match self.pin {
                Pin::PA0 => (*GPIOA.get()).bsrr.write(|w| w.bs0().bit(true)),
                Pin::PA1 => (*GPIOA.get()).bsrr.write(|w| w.bs1().bit(true)),
                Pin::PA5 => (*GPIOA.get()).bsrr.write(|w| w.bs5().bit(true)),
                Pin::PB0 => (*GPIOB.get()).bsrr.write(|w| w.bs0().bit(true)),
                Pin::PB1 => (*GPIOB.get()).bsrr.write(|w| w.bs1().bit(true)),
                Pin::PB3 => (*GPIOB.get()).bsrr.write(|w| w.bs3().bit(true)),
                Pin::PB4 => (*GPIOB.get()).bsrr.write(|w| w.bs4().bit(true)),
                Pin::PB5 => (*GPIOB.get()).bsrr.write(|w| w.bs5().bit(true)),
                Pin::PB10 => (*GPIOB.get()).bsrr.write(|w| w.bs10().bit(true)),
                Pin::PB11 => (*GPIOB.get()).bsrr.write(|w| w.bs11().bit(true)),
                Pin::PC6 => (*GPIOC.get()).bsrr.write(|w| w.bs6().bit(true)),
                Pin::PC7 => (*GPIOC.get()).bsrr.write(|w| w.bs7().bit(true)),
                Pin::PC8 => (*GPIOC.get()).bsrr.write(|w| w.bs8().bit(true)),
                Pin::PC9 => (*GPIOC.get()).bsrr.write(|w| w.bs9().bit(true)),
            }
        }
    }
    /// Set the PIN to low
    pub fn low(&mut self) {
        unsafe {
            match self.pin {
                Pin::PA0 => (*GPIOA.get()).bsrr.write(|w| w.br0().bit(true)),
                Pin::PA1 => (*GPIOA.get()).bsrr.write(|w| w.br1().bit(true)),
                Pin::PA5 => (*GPIOA.get()).bsrr.write(|w| w.br5().bit(true)),
                Pin::PB0 => (*GPIOB.get()).bsrr.write(|w| w.br0().bit(true)),
                Pin::PB1 => (*GPIOB.get()).bsrr.write(|w| w.br1().bit(true)),
                Pin::PB3 => (*GPIOB.get()).bsrr.write(|w| w.br3().bit(true)),
                Pin::PB4 => (*GPIOB.get()).bsrr.write(|w| w.br4().bit(true)),
                Pin::PB5 => (*GPIOB.get()).bsrr.write(|w| w.br5().bit(true)),
                Pin::PB10 => (*GPIOB.get()).bsrr.write(|w| w.br10().bit(true)),
                Pin::PB11 => (*GPIOB.get()).bsrr.write(|w| w.br11().bit(true)),
                Pin::PC6 => (*GPIOC.get()).bsrr.write(|w| w.br6().bit(true)),
                Pin::PC7 => (*GPIOC.get()).bsrr.write(|w| w.br7().bit(true)),
                Pin::PC8 => (*GPIOC.get()).bsrr.write(|w| w.br8().bit(true)),
                Pin::PC9 => (*GPIOC.get()).bsrr.write(|w| w.br9().bit(true)),
            }
        }
    }
}

fn setup_pin(pin: &Pin, mode: Mode) {
    cortex_m::interrupt::free(|cs| {
        let rcc = RCC.borrow(cs);

        let gpioa = GPIOA.borrow(cs);
        let gpiob = GPIOB.borrow(cs);
        let gpioc = GPIOC.borrow(cs);
        rcc.ahbenr
            .modify(|_, w| w.iopaen().enabled().iopben().enabled().iopcen().enabled());
        let mode = mode as u8;

        match *pin {
            Pin::PA0 => gpioa.moder.modify(|_, w| w.moder0().bits(mode)),
            Pin::PA1 => gpioa.moder.modify(|_, w| w.moder1().bits(mode)),
            Pin::PA5 => gpioa.moder.modify(|_, w| w.moder5().bits(mode)),
            Pin::PB0 => gpiob.moder.modify(|_, w| w.moder0().bits(mode)),
            Pin::PB1 => gpiob.moder.modify(|_, w| w.moder1().bits(mode)),
            Pin::PB3 => gpiob.moder.modify(|_, w| w.moder3().bits(mode)),
            Pin::PB4 => gpiob.moder.modify(|_, w| w.moder4().bits(mode)),
            Pin::PB5 => gpiob.moder.modify(|_, w| w.moder5().bits(mode)),
            Pin::PB10 => gpiob.moder.modify(|_, w| w.moder10().bits(mode)),
            Pin::PB11 => gpiob.moder.modify(|_, w| w.moder11().bits(mode)),
            Pin::PC6 => gpioc.moder.modify(|_, w| w.moder6().bits(mode)),
            Pin::PC7 => gpioc.moder.modify(|_, w| w.moder7().bits(mode)),
            Pin::PC8 => gpioc.moder.modify(|_, w| w.moder8().bits(mode)),
            Pin::PC9 => gpioc.moder.modify(|_, w| w.moder9().bits(mode)),
        }
    });
}
<commit_msg>set input pin as pull-down by default<commit_after>//! # gpio module
//!
//! This module provides access to the GPIO of the stm32f0 board.
//! You can:
//!
//! * configure a PIN in Input or Output
//! * read or write the PIN depending on its configuration
//!
//! ## Examples
//!
//! ```
//! extern crate stm32f0_hal;
//!
//! use stm32f0_hal::gpio;
//!
// ! let p_in = gpio::Input::setup(gpio::Pin::PA1);
// ! let b = p_in.read();
// !
// ! let p_out = gpio::Output::setup(gpio::Pin::PA5);
// ! p_out.write(true);
//! ```

use cortex_m;

use stm32f0x2::{EXTI, GPIOA, GPIOB, GPIOC, NVIC, RCC};
use stm32f0x2::interrupt::Interrupt;

enum Mode {
    Input = 0b00,
    Output = 0b01,
}

/// GPIO Pin available
pub enum Pin {
    PA0,
    PA1,
    PA5,
    PB0,
    PB1,
    PB3,
    PB4,
    PB5,
    PB10,
    PB11,
    PC6,
    PC7,
    PC8,
    PC9,
}

/// Input Mode Pin
pub struct Input {
    pin: Pin,
}

impl Input {
    /// Setup a PIN in Input Mode
    pub fn setup(pin: Pin) -> Input {
        setup_pin(&pin, Mode::Input);
        Input { pin }
    }

    /// Read the state of a PIN
    pub fn read(&self) -> bool {
        unsafe {
            match self.pin {
                Pin::PA0 => (*GPIOA.get()).idr.read().idr0().bit(),
                Pin::PA1 => (*GPIOA.get()).idr.read().idr1().bit(),
                Pin::PA5 => (*GPIOA.get()).idr.read().idr5().bit(),
                Pin::PB0 => (*GPIOB.get()).idr.read().idr0().bit(),
                Pin::PB1 => (*GPIOB.get()).idr.read().idr1().bit(),
                Pin::PB3 => (*GPIOB.get()).idr.read().idr3().bit(),
                Pin::PB4 => (*GPIOB.get()).idr.read().idr4().bit(),
                Pin::PB5 => (*GPIOB.get()).idr.read().idr5().bit(),
                Pin::PB10 => (*GPIOB.get()).idr.read().idr10().bit(),
                Pin::PB11 => (*GPIOB.get()).idr.read().idr11().bit(),
                Pin::PC6 => (*GPIOC.get()).idr.read().idr6().bit(),
                Pin::PC7 => (*GPIOC.get()).idr.read().idr7().bit(),
                Pin::PC8 => (*GPIOC.get()).idr.read().idr8().bit(),
                Pin::PC9 => (*GPIOC.get()).idr.read().idr9().bit(),
            }
        }
    }

    pub fn init_interrupt(&self) {
        match self.pin {
            Pin::PA0 => cortex_m::interrupt::free(|cs| {
                let exti = EXTI.borrow(cs);
                let nvic = NVIC.borrow(cs);
                exti.rtsr.modify(|_, w| w.tr0().set_bit());
                exti.imr.modify(|_, w| w.mr0().set_bit());
                nvic.enable(Interrupt::EXTI0_1);
            }),
            Pin::PA1 => cortex_m::interrupt::free(|cs| {
                let exti = EXTI.borrow(cs);
                let nvic = NVIC.borrow(cs);
                exti.rtsr.modify(|_, w| w.tr1().set_bit());
                exti.imr.modify(|_, w| w.mr1().set_bit());
                nvic.enable(Interrupt::EXTI0_1);
            }),
            Pin::PA5 => cortex_m::interrupt::free(|cs| {
                let exti = EXTI.borrow(cs);
                let nvic = NVIC.borrow(cs);
                exti.rtsr.modify(|_, w| w.tr5().set_bit());
                exti.imr.modify(|_, w| w.mr5().set_bit());
                nvic.enable(Interrupt::EXTI4_15);
            }),
            Pin::PC7 => cortex_m::interrupt::free(|cs| {
                let exti = EXTI.borrow(cs);
                let nvic = NVIC.borrow(cs);
                exti.rtsr.modify(|_, w| w.tr7().set_bit());
                exti.imr.modify(|_, w| w.mr7().set_bit());
                nvic.enable(Interrupt::EXTI4_15);
            }),
            _ => panic!("Unsupported PIN!"),
        }
    }
}

/// Output Mode Pin
pub struct Output {
    pin: Pin,
}

impl Output {
    /// Setup a PIN in Output Mode
    pub fn setup(pin: Pin) -> Output {
        setup_pin(&pin, Mode::Output);
        Output { pin }
    }
    /// Set the PIN to high
    pub fn high(&mut self) {
        unsafe {
            match self.pin {
                Pin::PA0 => (*GPIOA.get()).bsrr.write(|w| w.bs0().bit(true)),
                Pin::PA1 => (*GPIOA.get()).bsrr.write(|w| w.bs1().bit(true)),
                Pin::PA5 => (*GPIOA.get()).bsrr.write(|w| w.bs5().bit(true)),
                Pin::PB0 => (*GPIOB.get()).bsrr.write(|w| w.bs0().bit(true)),
                Pin::PB1 => (*GPIOB.get()).bsrr.write(|w| w.bs1().bit(true)),
                Pin::PB3 => (*GPIOB.get()).bsrr.write(|w| w.bs3().bit(true)),
                Pin::PB4 => (*GPIOB.get()).bsrr.write(|w| w.bs4().bit(true)),
                Pin::PB5 => (*GPIOB.get()).bsrr.write(|w| w.bs5().bit(true)),
                Pin::PB10 => (*GPIOB.get()).bsrr.write(|w| w.bs10().bit(true)),
                Pin::PB11 => (*GPIOB.get()).bsrr.write(|w| w.bs11().bit(true)),
                Pin::PC6 => (*GPIOC.get()).bsrr.write(|w| w.bs6().bit(true)),
                Pin::PC7 => (*GPIOC.get()).bsrr.write(|w| w.bs7().bit(true)),
                Pin::PC8 => (*GPIOC.get()).bsrr.write(|w| w.bs8().bit(true)),
                Pin::PC9 => (*GPIOC.get()).bsrr.write(|w| w.bs9().bit(true)),
            }
        }
    }
    /// Set the PIN to low
    pub fn low(&mut self) {
        unsafe {
            match self.pin {
                Pin::PA0 => (*GPIOA.get()).bsrr.write(|w| w.br0().bit(true)),
                Pin::PA1 => (*GPIOA.get()).bsrr.write(|w| w.br1().bit(true)),
                Pin::PA5 => (*GPIOA.get()).bsrr.write(|w| w.br5().bit(true)),
                Pin::PB0 => (*GPIOB.get()).bsrr.write(|w| w.br0().bit(true)),
                Pin::PB1 => (*GPIOB.get()).bsrr.write(|w| w.br1().bit(true)),
                Pin::PB3 => (*GPIOB.get()).bsrr.write(|w| w.br3().bit(true)),
                Pin::PB4 => (*GPIOB.get()).bsrr.write(|w| w.br4().bit(true)),
                Pin::PB5 => (*GPIOB.get()).bsrr.write(|w| w.br5().bit(true)),
                Pin::PB10 => (*GPIOB.get()).bsrr.write(|w| w.br10().bit(true)),
                Pin::PB11 => (*GPIOB.get()).bsrr.write(|w| w.br11().bit(true)),
                Pin::PC6 => (*GPIOC.get()).bsrr.write(|w| w.br6().bit(true)),
                Pin::PC7 => (*GPIOC.get()).bsrr.write(|w| w.br7().bit(true)),
                Pin::PC8 => (*GPIOC.get()).bsrr.write(|w| w.br8().bit(true)),
                Pin::PC9 => (*GPIOC.get()).bsrr.write(|w| w.br9().bit(true)),
            }
        }
    }
}

fn setup_pin(pin: &Pin, mode: Mode) {
    cortex_m::interrupt::free(|cs| {
        let rcc = RCC.borrow(cs);

        let gpioa = GPIOA.borrow(cs);
        let gpiob = GPIOB.borrow(cs);
        let gpioc = GPIOC.borrow(cs);
        rcc.ahbenr
            .modify(|_, w| w.iopaen().enabled().iopben().enabled().iopcen().enabled());
        let mode = mode as u8;

        match *pin {
            Pin::PA0 => {
                gpioa.moder.modify(|_, w| w.moder0().bits(mode));
                gpioa.pupdr.modify(|_, w| w.pupdr0().pull_down());
            }
            Pin::PA1 => {
                gpioa.moder.modify(|_, w| w.moder1().bits(mode));
                gpioa.pupdr.modify(|_, w| w.pupdr1().pull_down());
            }
            Pin::PA5 => {
                gpioa.moder.modify(|_, w| w.moder5().bits(mode));
                gpioa.pupdr.modify(|_, w| w.pupdr5().pull_down());
            }
            Pin::PB0 => {
                gpiob.moder.modify(|_, w| w.moder0().bits(mode));
                gpiob.pupdr.modify(|_, w| w.pupdr0().pull_down());
            }
            Pin::PB1 => {
                gpiob.moder.modify(|_, w| w.moder1().bits(mode));
                gpiob.pupdr.modify(|_, w| w.pupdr1().pull_down());
            }
            Pin::PB3 => {
                gpiob.moder.modify(|_, w| w.moder3().bits(mode));
                gpiob.pupdr.modify(|_, w| w.pupdr3().pull_down());
            }
            Pin::PB4 => {
                gpiob.moder.modify(|_, w| w.moder4().bits(mode));
                gpiob.pupdr.modify(|_, w| w.pupdr4().pull_down());
            }
            Pin::PB5 => {
                gpiob.moder.modify(|_, w| w.moder5().bits(mode));
                gpiob.pupdr.modify(|_, w| w.pupdr5().pull_down());
            }
            Pin::PB10 => {
                gpiob.moder.modify(|_, w| w.moder10().bits(mode));
                gpiob.pupdr.modify(|_, w| w.pupdr10().pull_down());
            }
            Pin::PB11 => {
                gpiob.moder.modify(|_, w| w.moder11().bits(mode));
                gpiob.pupdr.modify(|_, w| w.pupdr11().pull_down());
            }
            Pin::PC6 => {
                gpioc.moder.modify(|_, w| w.moder6().bits(mode));
                gpioc.pupdr.modify(|_, w| w.pupdr6().pull_down());
            }
            Pin::PC7 => {
                gpioc.moder.modify(|_, w| w.moder7().bits(mode));
                gpioc.pupdr.modify(|_, w| w.pupdr7().pull_down());
            }
            Pin::PC8 => {
                gpioc.moder.modify(|_, w| w.moder8().bits(mode));
                gpioc.pupdr.modify(|_, w| w.pupdr8().pull_down());
            }
            Pin::PC9 => {
                gpioc.moder.modify(|_, w| w.moder9().bits(mode));
                gpioc.pupdr.modify(|_, w| w.pupdr9().pull_down());
            }
        }
    });
}
<|endoftext|>


<commit_before>#![feature(alloc_system)]

extern crate alloc_system;

#[macro_use]
extern crate rustfbp;
extern crate capnp;

use self::rustfbp::scheduler::{Scheduler, Comp};
use self::rustfbp::ports::{Msg};

use std::collections::HashMap;
use std::env;

fn main() {
    run(&env::args().nth(1).unwrap());
}

mod edge_capnp {
    include!("edge_capnp.rs");
}
use edge_capnp::core_action;

#[allow(unused_must_use)]
fn run(path_fbp: &str) {

    let mut sched = Scheduler::new();
    sched.add_node("open", "fs_file_open.so").expect("cannot add node");
    sched.add_node("lex", "core_parser_lexical.so").expect("cannot add node");
    sched.add_node("sem", "core_parser_semantic.so").expect("cannot add node");
    sched.add_node("vm", "core_vm.so").expect("cannot add node");
    sched.add_node("errors", "core_errors.so").expect("cannot add node");
    sched.add_node("graph_print", "core_parser_graph_print.so").expect("cannot add node");
    sched.add_node("graph_check", "core_parser_graph_check.so").expect("cannot add node");
    sched.add_node("sched", "core_scheduler.so").expect("cannot add node");
    sched.add_node("imsg", "core_capnp_encode.so").expect("cannot add node");
    sched.add_node("core_find_edge", "core_find_edge.so").expect("cannot add node");
    sched.add_node("core_find_node", "core_find_node.so").expect("cannot add node");

    sched.connect("open", "output", "lex", "input").expect("cannot connect");
    sched.connect("lex", "output", "sem", "input").expect("cannot connect");
    sched.connect("sem", "output", "graph_check", "input").expect("cannot connect");
    sched.connect("graph_check", "output", "vm", "input").expect("cannot connect");
    sched.connect("graph_check", "error", "errors", "semantic_error").expect("cannot connect");

    sched.connect("open", "error", "errors", "file_error").expect("cannot connect");
    sched.connect("sem", "error", "errors", "semantic_error").expect("cannot connect");
    sched.connect("errors", "output", "vm", "input").expect("cannot connect");

    // reccursive part
    sched.connect("vm", "ask_graph", "open", "input").expect("cannot connect");

    // With Graph print
    // sched.connect("vm", "output", "graph_print", "input").expect("cannot connect");
    // sched.connect("graph_print", "output", "sched", "graph").expect("cannot connect");

    // Without Graph print
    sched.connect("vm", "output", "sched", "graph").expect("cannot connect");

    sched.connect("sched", "ask_path", "core_find_edge", "input").expect("cannot connect");
    sched.connect("core_find_edge", "output", "sched", "edge_path").expect("cannot connect");

    sched.connect("vm", "ask_path", "core_find_node", "input").expect("cannot connect");
    sched.connect("core_find_node", "output", "vm", "new_path").expect("cannot connect");

    // IMsg part
    sched.connect("sched", "imsg_path", "imsg", "path").expect("cannot connect");
    sched.connect("sched", "imsg_edge", "imsg", "edge").expect("cannot connect");
    sched.connect("sched", "imsg_input", "imsg", "input").expect("cannot connect");
    sched.connect("imsg", "output", "sched", "imsg").expect("cannot connect");

    sched.connect("sched", "ask_graph", "vm", "input").expect("cannot connect ask_graph");

    let add = sched.get_sender("sched", "action").expect("action of sched not found");

    // Send the first Msg to the scheduler
    let mut start_msg = Msg::new();
    {
        let builder: core_action::Builder = start_msg.build_schema();
        let mut add = builder.init_add();
        add.set_name("main");
        add.set_comp(&path_fbp);
    }
    add.send(start_msg).expect("cannot send start_msg");

    // Send the halt msg
    let mut halt_msg = Msg::new();
    {
        let mut builder: core_action::Builder = halt_msg.build_schema();
        builder.set_halt(());
    }
    add.send(halt_msg).expect("cannot send halt_msg");

    // Wait for the end of the execution
    sched.join();
}
<commit_msg>Problem: fvm/src/main.rs is hard to understand flow<commit_after>#![feature(alloc_system)]

extern crate alloc_system;

#[macro_use]
extern crate rustfbp;
extern crate capnp;

use self::rustfbp::scheduler::{Scheduler, Comp};
use self::rustfbp::ports::{Msg};

use std::collections::HashMap;
use std::env;

fn main() {
    run(&env::args().nth(1).unwrap());
}

mod edge_capnp {
    include!("edge_capnp.rs");
}
use edge_capnp::core_action;

#[allow(unused_must_use)]
fn run(path_fbp: &str) {

    let mut sched = Scheduler::new();
    sched.add_node("open", "fs_file_open.so").expect("cannot add node");
    sched.add_node("lex", "core_parser_lexical.so").expect("cannot add node");
    sched.add_node("sem", "core_parser_semantic.so").expect("cannot add node");
    sched.add_node("vm", "core_vm.so").expect("cannot add node");
    sched.add_node("errors", "core_errors.so").expect("cannot add node");
    sched.add_node("graph_print", "core_parser_graph_print.so").expect("cannot add node");
    sched.add_node("graph_check", "core_parser_graph_check.so").expect("cannot add node");
    sched.add_node("sched", "core_scheduler.so").expect("cannot add node");
    sched.add_node("imsg", "core_capnp_encode.so").expect("cannot add node");
    sched.add_node("core_find_edge", "core_find_edge.so").expect("cannot add node");
    sched.add_node("core_find_node", "core_find_node.so").expect("cannot add node");

    // open(fs_file_open) output -> input lex(core_parser_lexical)
    // lex() output -> input sem(core_parser_semantic)
    // sem() output -> input graph_check(core_parser_graph_check)
    // graph_check() output -> input vm(core_vm)
    // graph_check() error -> semantic_error errors(core_errors)
    sched.connect("open", "output", "lex", "input").expect("cannot connect");
    sched.connect("lex", "output", "sem", "input").expect("cannot connect");
    sched.connect("sem", "output", "graph_check", "input").expect("cannot connect");
    sched.connect("graph_check", "output", "vm", "input").expect("cannot connect");
    sched.connect("graph_check", "error", "errors", "semantic_error").expect("cannot connect");

    // open() error -> file_error errors()
    // sem() error -> semantic_error errors()
    // errors() output -> input vm()
    sched.connect("open", "error", "errors", "file_error").expect("cannot connect");
    sched.connect("sem", "error", "errors", "semantic_error").expect("cannot connect");
    sched.connect("errors", "output", "vm", "input").expect("cannot connect");

    // reccursive part
    // vm() ask_graph -> input open()
    sched.connect("vm", "ask_graph", "open", "input").expect("cannot connect");

    // With Graph print
    // sched.connect("vm", "output", "graph_print", "input").expect("cannot connect");
    // sched.connect("graph_print", "output", "sched", "graph").expect("cannot connect");

    // Without Graph print
    // vm() output -> graph sched(core_scheduler)
    // sched() ask_path -> input core_find_edge(core_find_edge)
    // core_find_edge() output -> edge_path sched()
    // vm() ask_path -> input core_find_node()
    // core_find_node() output -> new_path vm()
    sched.connect("vm", "output", "sched", "graph").expect("cannot connect");
    sched.connect("sched", "ask_path", "core_find_edge", "input").expect("cannot connect");
    sched.connect("core_find_edge", "output", "sched", "edge_path").expect("cannot connect");
    sched.connect("vm", "ask_path", "core_find_node", "input").expect("cannot connect");
    sched.connect("core_find_node", "output", "vm", "new_path").expect("cannot connect");

    // IMsg part
    // sched() imsg_path -> path imsg()
    // sched() imsg_edge -> edge imsg()
    // sched() imsg_input -> input imsg()
    // imsg() output -> imsg sched()
    // imsg() ask_graph -> input vm()
    sched.connect("sched", "imsg_path", "imsg", "path").expect("cannot connect");
    sched.connect("sched", "imsg_edge", "imsg", "edge").expect("cannot connect");
    sched.connect("sched", "imsg_input", "imsg", "input").expect("cannot connect");
    sched.connect("imsg", "output", "sched", "imsg").expect("cannot connect");
    sched.connect("sched", "ask_graph", "vm", "input").expect("cannot connect ask_graph");

    let add = sched.get_sender("sched", "action").expect("action of sched not found");

    // Send the first Msg to the scheduler
    let mut start_msg = Msg::new();
    {
        let builder: core_action::Builder = start_msg.build_schema();
        let mut add = builder.init_add();
        add.set_name("main");
        add.set_comp(&path_fbp);
    }
    add.send(start_msg).expect("cannot send start_msg");

    // Send the halt msg
    let mut halt_msg = Msg::new();
    {
        let mut builder: core_action::Builder = halt_msg.build_schema();
        builder.set_halt(());
    }
    add.send(halt_msg).expect("cannot send halt_msg");

    // Wait for the end of the execution
    sched.join();
}
<|endoftext|>


<commit_before>use std::vec;
use common::*;
use monomial::{Monomial};

 /*
  * VectorMonomial type, parameterized by monomial type M.
  * Represents a vector valued function with a monomial in one component and
  * which is constantly 0 in all other components.
  */
#[deriving(Eq, IterBytes, Clone)]
pub struct VectorMonomial<M> {
  mon_dim: Dim,
  mon: M,
}

impl<M:Monomial> VectorMonomial<M> {

  pub fn new(mon_dim: Dim, mon: M) -> VectorMonomial<M> {
    if *mon_dim >= Monomial::domain_space_dims(None::<M>) {
      fail!("Coordinate index too large for passed monomial's domain.");
    }
    VectorMonomial { mon_dim: mon_dim, mon: mon }
  }

  #[inline]
  pub fn mon_dim(&self) -> Dim {
    self.mon_dim
  }

  #[inline]
  pub fn mon(&self) -> M {
    self.mon.clone()
  }

  #[inline]
  pub fn divergence_coef_and_mon(&self) -> (R,M) {
    match self.mon.exp(self.mon_dim) {
      Deg(0) => (0.,self.mon.clone()),
      Deg(e) => (e as R, self.mon.map_exp(self.mon_dim, |e| Deg(*e-1)))
    }
  }

  pub fn vector_mons_of_deg_le(max_deg: Deg) -> ~[VectorMonomial<M>] {
    let dom_dim = Monomial::domain_space_dims(None::<M>);
    let mons: ~[M] = Monomial::mons_of_deg_le(max_deg);
    let mut vmons: ~[VectorMonomial<M>] = vec::with_capacity(mons.len() * dom_dim);
    for r in range(0, dom_dim) {
      for mon in mons.iter() {
        vmons.push(VectorMonomial::new(Dim(r), mon.clone()));
      }
    }
    vmons
  }
}

<commit_msg>Add doc for vector monomials fn regarding ordering of results.<commit_after>use std::vec;
use common::*;
use monomial::{Monomial};

 /*
  * VectorMonomial type, parameterized by monomial type M.
  * Represents a vector valued function with a monomial in one component and
  * which is constantly 0 in all other components.
  */
#[deriving(Eq, IterBytes, Clone)]
pub struct VectorMonomial<M> {
  mon_dim: Dim,
  mon: M,
}

impl<M:Monomial> VectorMonomial<M> {

  pub fn new(mon_dim: Dim, mon: M) -> VectorMonomial<M> {
    if *mon_dim >= Monomial::domain_space_dims(None::<M>) {
      fail!("Coordinate index too large for passed monomial's domain.");
    }
    VectorMonomial { mon_dim: mon_dim, mon: mon }
  }

  #[inline]
  pub fn mon_dim(&self) -> Dim {
    self.mon_dim
  }

  #[inline]
  pub fn mon(&self) -> M {
    self.mon.clone()
  }

  #[inline]
  pub fn divergence_coef_and_mon(&self) -> (R,M) {
    match self.mon.exp(self.mon_dim) {
      Deg(0) => (0.,self.mon.clone()),
      Deg(e) => (e as R, self.mon.map_exp(self.mon_dim, |e| Deg(*e-1)))
    }
  }

  /// Vector monomials of degree not exceeding that indicated, ordered by component dimension in ascending order,
  /// and then by monomial in increasing lexicographical order of exponents.
  pub fn vector_mons_of_deg_le(max_deg: Deg) -> ~[VectorMonomial<M>] {
    let dom_dim = Monomial::domain_space_dims(None::<M>);
    let mons: ~[M] = Monomial::mons_of_deg_le(max_deg);
    let mut vmons: ~[VectorMonomial<M>] = vec::with_capacity(mons.len() * dom_dim);
    for r in range(0, dom_dim) {
      for mon in mons.iter() {
        vmons.push(VectorMonomial::new(Dim(r), mon.clone()));
      }
    }
    vmons
  }
}

<|endoftext|>


<commit_before>extern crate memmap;
extern crate thread_scoped;
extern crate libc;
extern crate memchr;

use std::str;

use self::memmap::{Mmap, Protection};
use self::memchr::memchr;

pub fn count_mmap_parallel_memchr(filepath: &str) -> u64 {
    let fmmap = Mmap::open_path(filepath, Protection::Read).expect("mmap err");
    let bytes: &[u8] = unsafe { fmmap.as_slice() };

    let mut handles: Vec<thread_scoped::JoinGuard<u64>> = Vec::new();

    for chunk in bytes.chunks(bytes.len() / 4) {
        unsafe {
            let t = thread_scoped::scoped(move || count_buf_lines(chunk));
            handles.push(t);
        };
    }

    let mut total_lines = 0;
    for h in handles {
        total_lines += h.join()
    }
    total_lines
}

fn count_buf_lines(buf: &[u8]) -> u64 {
    let mut lines = 0;
    let mut start = 0;
    while let Some(n) = memchr(b'\n', &buf[start..buf.len()]) {
        start = start + n + 1;
        lines += 1;
    }
    lines
}
<commit_msg>remove old lines counting performance experiments<commit_after><|endoftext|>


<commit_before>use neb::ram::schema::Field;
use neb::ram::types::TypeId;
use neb::client::{Client as NebClient};

use server::schema::{MorpheusSchema, SchemaType, SchemaContainer, SchemaError};

use std::sync::Arc;

pub mod vertex;
pub mod edge;

lazy_static! {
    pub static ref ID_LINKED_LIST: Vec<Field> = vec![
            Field::new(&String::from("next"), TypeId::Id as u32, true, false, None),
            Field::new(&String::from("list"), TypeId::Id as u32, false, true, None)
        ];
}

pub struct Graph {
    schema: Arc<SchemaContainer>,
    neb_client: Arc<NebClient>
}

impl Graph {
    pub fn new_vertex_group(&self, schema: &mut MorpheusSchema) -> Result<(), SchemaError> {
        schema.schema_type = SchemaType::Vertex;
        self.schema.new_schema(schema)
    }
    pub fn new_edge_group(&self, schema: &mut MorpheusSchema, edge_type: edge::EdgeType) -> Result<(), SchemaError> {
        schema.schema_type = SchemaType::Edge(edge_type);
        self.schema.new_schema(schema)
    }
}<commit_msg>redudant check for new edge group<commit_after>use neb::ram::schema::Field;
use neb::ram::types::TypeId;
use neb::client::{Client as NebClient};

use server::schema::{MorpheusSchema, SchemaType, SchemaContainer, SchemaError};

use std::sync::Arc;

pub mod vertex;
pub mod edge;

lazy_static! {
    pub static ref ID_LINKED_LIST: Vec<Field> = vec![
            Field::new(&String::from("next"), TypeId::Id as u32, true, false, None),
            Field::new(&String::from("list"), TypeId::Id as u32, false, true, None)
        ];
}

pub struct Graph {
    schema: Arc<SchemaContainer>,
    neb_client: Arc<NebClient>
}

impl Graph {
    pub fn new_vertex_group(&self, schema: &mut MorpheusSchema) -> Result<(), SchemaError> {
        schema.schema_type = SchemaType::Vertex;
        self.schema.new_schema(schema)
    }
    pub fn new_edge_group(&self, schema: &mut MorpheusSchema, edge_type: edge::EdgeType) -> Result<(), SchemaError> {
        if edge_type == edge::EdgeType::Simple {
            return Err(SchemaError::SimpleEdgeShouldNotHaveSchema)
        }
        schema.schema_type = SchemaType::Edge(edge_type);
        self.schema.new_schema(schema)
    }
}<|endoftext|>


<commit_before>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// 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/.
//
// This Source Code Form is "Incompatible
// With Secondary Licenses", as defined by
// the Mozilla Public License, v. 2.0.

use std::thread;
use std::thread::JoinHandle;
use std::net::TcpStream;
use std::ops::{DerefMut, Deref};
use std::os::unix::io::RawFd;
use std::collections::LinkedList;
use std::process::Command;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{
    channel,
    Sender,
    Receiver,
    TryRecvError
};

use super::types::*;
use super::epoll;
use super::epoll::util::*;
use super::epoll::EpollEvent;
use super::num_cpus;
use super::socket::Socket;
use super::simple_stream::SimpleStream;

pub struct EventLoop {
    /// Handle to event loop process
    prox: JoinHandle<()>,
    /// Sender<T> to proc
    prox_tx: Sender<TcpStream>
}

impl EventLoop {

    /// Returns a new EventLoop
    pub fn new(server_tx: Sender<EventTuple>) -> EventLoop {
        let (tx, rx): (Sender<TcpStream>, Receiver<TcpStream>) = channel();
        let prox = thread::Builder::new()
            .name("EventLoop".to_string())
            .spawn(move || {
                EventLoop::start(rx, server_tx);
            }).unwrap();

        EventLoop {
            prox: prox,
            prox_tx: tx
        }
    }

    /// Returns a clone of this EventLoop's Sender<TcpStream> channel
    pub fn sender(&self) -> Sender<TcpStream> {
        self.prox_tx.clone()
    }

    /// Main event loop
    fn start(rx: Receiver<TcpStream>, uspace_tx: Sender<EventTuple>) {
        // Master socket list
        let mut sockets = Arc::new(Mutex::new(LinkedList::<Socket>::new()));

        // Master id list
        // TODO - Figure out if this is needed to ensure collisions aren't made?
        let mut ids = Arc::new(Mutex::new(LinkedList::<u32>::new()));

        // Our error handler for this thread and it's children
        let (err_tx, err_rx): (Sender<()>, Receiver<()>) = channel();

        // Create an epoll instance
        let result = epoll::create1(0);
        if result.is_err() {
            let err = result.unwrap_err();
            panic!("Unable to create epoll instance: {}", err)
        }
        let epoll_instance = result.unwrap();

        println!("efd: {}", epoll_instance);

        // Start the epoll thread
        let c_sockets = sockets.clone();
        let c_epoll_instance = epoll_instance.clone();
        let epoll_prox = thread::Builder::new()
            .name("EpollLoop".to_string())
            .spawn(move || {
                EventLoop::epoll_loop(uspace_tx, c_sockets, c_epoll_instance, err_rx);
            }).unwrap();

        for new_stream in rx.iter() {
            match SimpleStream::new(new_stream) {
                Ok(s_stream) => {
                    // Add to master list
                    let mut socket = Socket::new(s_stream);

                    // TODO - Replace with recoverable version once into_inner() is stable
                    // Unfortunately, this is the only stable way to use mutexes at the moment
                    // Hopefully recovering from poisoning will be in 1.2
                    // let mut s_guard = match sockets.lock() {
                    //     Ok(guard) => guard,
                    //     Err(poisoned) => poisoned.into_inner()
                    // };
                    let mut s_guard = sockets.lock().unwrap();
                    let s_list = s_guard.deref_mut();
                    let s_fd = socket.raw_fd();
                    s_list.push_back(socket);

                    // Add to epoll
                    let event = Box::new(EpollEvent {
                        data: s_fd as u64,
                        events: (event_type::EPOLLIN | event_type::EPOLLET)
                        });
                    match epoll::ctl(epoll_instance, ctl_op::ADD, s_fd, event) {
                        Ok(()) => {},
                        Err(e) => println!("Epoll CtrlError: {}", e)
                    };
                }
                Err(e) => {
                    // TODO - write error to log file
                    println!("Error: {}", e);
                }
            };
        }

        // If we get here, shit is real bad. It means we have lost our
        // channel to the outside world.
        // Kill off event loop, so unwinding can begin
        err_tx.send(());
    }

    ///
    fn epoll_loop(uspace_tx: Sender<EventTuple>,
                  sockets: SocketList,
                  epoll_instance: RawFd,
                  err_rx: Receiver<()>) {

        // This is the maximum number of events we want to be notified of at one time
        let mut events = Vec::<EpollEvent>::with_capacity(100);

        loop {
            // Wait for epoll events
            match epoll::wait(epoll_instance, &mut events[..], -1) {
                Ok(num_events) => {
                    for x in 0..num_events {
                        let tx_clone = uspace_tx.clone();
                        let s_clone = sockets.clone();
                        EventLoop::handle_epoll_event(tx_clone, &events[x as usize], s_clone);
                    }
                }
                Err(e) => {
                    panic!("Error on epoll::wait(): {}", e)
                }
            }

            // If we receive anything on this end or lose communication, we need to halt,
            // because we have no where to send up events, our "user space" channel is
            // gone
            match err_rx.try_recv() {
                Ok(_) => {
                    println!("Error, terminating epoll_loop");
                    break;
                }
                Err(e) => {
                    match e {
                        TryRecvError::Empty => {}
                        _ => {
                            println!("Error, terminating epoll_loo");
                            break;
                        }
                    }
                }
            }
        }
    }

    /// Processes a read on the socket that is ready for reading
    ///
    /// An epoll event is passed to this function, with the fd that is ready to be read
    /// A traversal through the list of sockets is then performed in order to locate the
    /// SimpleStream instance that is wrapping that file descriptor.
    /// After a read is performed on that socket, it's data will be passed back to the
    /// "user-space" section of the Server to process the payload however it needs to.
    ///
    /// TODO - Create a faster way to gain a safe reference to the SimpleStream wrapping
    /// the fd instead of an O(n) lookup for every event. Currently lookup time is
    /// O(n) * MAX_EPOLL_EVENTS, where MAX_EPOLL_EVENTS is user defined in this function's
    /// caller.
    fn handle_epoll_event(uspace_tx: Sender<EventTuple>,
                          event: &EpollEvent,
                          sockets: SocketList) {

        // The fd we are traversing the list for
        let fd = event.data;

        // We need a handle before the list gets locked and used
        let s_list_clone = sockets.clone();

        // TODO - Replace with recoverable version once into_inner() is stable
        // Unfortunately, this is the only stable way to use mutexes at the moment
        // Hopefully recovering from poisoning will be in 1.2
        // let mut s_guard = match sockets.lock() {
        //     Ok(guard) => guard,
        //     Err(poisoned) => poisoned.into_inner()
        // };
        let mut s_guard = sockets.lock().unwrap();
        let s_list = s_guard.deref_mut();
        for socket in s_list.iter_mut() {
            if socket.raw_fd() as u64 == fd {
                // We've found the socket for the event passed from epoll
                // Lets attempt to read from it
                match socket.read() {
                    Ok(()) => {
                        for msg in socket.buffer().iter() {
                            let list_handle = s_list_clone.clone();
                            let socket_clone = socket.clone();
                            let msg_clone = msg.clone();
                            uspace_tx.send((list_handle, socket_clone, msg_clone));
                        }
                    }
                    Err(e) => {
                        // TODO - Figure out how to handle
                    }
                }
            }
        }
    }
}
<commit_msg>Debugging<commit_after>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// 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/.
//
// This Source Code Form is "Incompatible
// With Secondary Licenses", as defined by
// the Mozilla Public License, v. 2.0.

use std::thread;
use std::thread::JoinHandle;
use std::net::TcpStream;
use std::ops::{DerefMut, Deref};
use std::os::unix::io::RawFd;
use std::collections::LinkedList;
use std::process::Command;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{
    channel,
    Sender,
    Receiver,
    TryRecvError
};

use super::types::*;
use super::epoll;
use super::epoll::util::*;
use super::epoll::EpollEvent;
use super::num_cpus;
use super::socket::Socket;
use super::simple_stream::SimpleStream;

pub struct EventLoop {
    /// Handle to event loop process
    prox: JoinHandle<()>,
    /// Sender<T> to proc
    prox_tx: Sender<TcpStream>
}

impl EventLoop {

    /// Returns a new EventLoop
    pub fn new(server_tx: Sender<EventTuple>) -> EventLoop {
        let (tx, rx): (Sender<TcpStream>, Receiver<TcpStream>) = channel();
        let prox = thread::Builder::new()
            .name("EventLoop".to_string())
            .spawn(move || {
                EventLoop::start(rx, server_tx);
            }).unwrap();

        EventLoop {
            prox: prox,
            prox_tx: tx
        }
    }

    /// Returns a clone of this EventLoop's Sender<TcpStream> channel
    pub fn sender(&self) -> Sender<TcpStream> {
        self.prox_tx.clone()
    }

    /// Main event loop
    fn start(rx: Receiver<TcpStream>, uspace_tx: Sender<EventTuple>) {
        // Master socket list
        let mut sockets = Arc::new(Mutex::new(LinkedList::<Socket>::new()));

        // Master id list
        // TODO - Figure out if this is needed to ensure collisions aren't made?
        let mut ids = Arc::new(Mutex::new(LinkedList::<u32>::new()));

        // Our error handler for this thread and it's children
        let (err_tx, err_rx): (Sender<()>, Receiver<()>) = channel();

        // Create an epoll instance
        let result = epoll::create1(0);
        if result.is_err() {
            let err = result.unwrap_err();
            panic!("Unable to create epoll instance: {}", err)
        }
        let epoll_instance = result.unwrap();

        println!("efd: {}", epoll_instance);

        // Start the epoll thread
        let c_sockets = sockets.clone();
        let c_epoll_instance = epoll_instance.clone();
        let epoll_prox = thread::Builder::new()
            .name("EpollLoop".to_string())
            .spawn(move || {
                EventLoop::epoll_loop(uspace_tx, c_sockets, c_epoll_instance, err_rx);
            }).unwrap();

        for new_stream in rx.iter() {
            match SimpleStream::new(new_stream) {
                Ok(s_stream) => {
                    // Add to master list
                    let mut socket = Socket::new(s_stream);

                    // TODO - Replace with recoverable version once into_inner() is stable
                    // Unfortunately, this is the only stable way to use mutexes at the moment
                    // Hopefully recovering from poisoning will be in 1.2
                    // let mut s_guard = match sockets.lock() {
                    //     Ok(guard) => guard,
                    //     Err(poisoned) => poisoned.into_inner()
                    // };
                    let mut s_guard = sockets.lock().unwrap();
                    let s_list = s_guard.deref_mut();
                    let s_fd = socket.raw_fd();
                    s_list.push_back(socket);

                    // Add to epoll
                    let event = Box::new(EpollEvent {
                        data: s_fd as u64,
                        events: (event_type::EPOLLIN | event_type::EPOLLET)
                        });
                    match epoll::ctl(epoll_instance, ctl_op::ADD, s_fd, event) {
                        Ok(()) => {},
                        Err(e) => println!("Epoll CtrlError: {}", e)
                    };
                }
                Err(e) => {
                    // TODO - write error to log file
                    println!("Error: {}", e);
                }
            };
        }

        // If we get here, shit is real bad. It means we have lost our
        // channel to the outside world.
        // Kill off event loop, so unwinding can begin
        err_tx.send(());
    }

    ///
    fn epoll_loop(uspace_tx: Sender<EventTuple>,
                  sockets: SocketList,
                  epoll_instance: RawFd,
                  err_rx: Receiver<()>) {

        // This is the maximum number of events we want to be notified of at one time
        let mut events = Vec::<EpollEvent>::with_capacity(100);

        println!("epd: {}", epoll_instance);

        loop {
            // Wait for epoll events
            match epoll::wait(epoll_instance, &mut events[..], -1) {
                Ok(num_events) => {
                    for x in 0..num_events {
                        let tx_clone = uspace_tx.clone();
                        let s_clone = sockets.clone();
                        EventLoop::handle_epoll_event(tx_clone, &events[x as usize], s_clone);
                    }
                }
                Err(e) => {
                    panic!("Error on epoll::wait(): {}", e)
                }
            }

            // If we receive anything on this end or lose communication, we need to halt,
            // because we have no where to send up events, our "user space" channel is
            // gone
            match err_rx.try_recv() {
                Ok(_) => {
                    println!("Error, terminating epoll_loop");
                    break;
                }
                Err(e) => {
                    match e {
                        TryRecvError::Empty => {}
                        _ => {
                            println!("Error, terminating epoll_loo");
                            break;
                        }
                    }
                }
            }
        }
    }

    /// Processes a read on the socket that is ready for reading
    ///
    /// An epoll event is passed to this function, with the fd that is ready to be read
    /// A traversal through the list of sockets is then performed in order to locate the
    /// SimpleStream instance that is wrapping that file descriptor.
    /// After a read is performed on that socket, it's data will be passed back to the
    /// "user-space" section of the Server to process the payload however it needs to.
    ///
    /// TODO - Create a faster way to gain a safe reference to the SimpleStream wrapping
    /// the fd instead of an O(n) lookup for every event. Currently lookup time is
    /// O(n) * MAX_EPOLL_EVENTS, where MAX_EPOLL_EVENTS is user defined in this function's
    /// caller.
    fn handle_epoll_event(uspace_tx: Sender<EventTuple>,
                          event: &EpollEvent,
                          sockets: SocketList) {

        // The fd we are traversing the list for
        let fd = event.data;

        // We need a handle before the list gets locked and used
        let s_list_clone = sockets.clone();

        // TODO - Replace with recoverable version once into_inner() is stable
        // Unfortunately, this is the only stable way to use mutexes at the moment
        // Hopefully recovering from poisoning will be in 1.2
        // let mut s_guard = match sockets.lock() {
        //     Ok(guard) => guard,
        //     Err(poisoned) => poisoned.into_inner()
        // };
        let mut s_guard = sockets.lock().unwrap();
        let s_list = s_guard.deref_mut();
        for socket in s_list.iter_mut() {
            if socket.raw_fd() as u64 == fd {
                // We've found the socket for the event passed from epoll
                // Lets attempt to read from it
                match socket.read() {
                    Ok(()) => {
                        for msg in socket.buffer().iter() {
                            let list_handle = s_list_clone.clone();
                            let socket_clone = socket.clone();
                            let msg_clone = msg.clone();
                            uspace_tx.send((list_handle, socket_clone, msg_clone));
                        }
                    }
                    Err(e) => {
                        // TODO - Figure out how to handle
                    }
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use backend::{MemoryBackend, StoreBackend};
use errors::HatError;
use hat::HatRc;
use hat::family::Family;
use key;
use std::collections::HashMap;
use std::sync::Arc;
use util::FileIterator;

pub fn setup_hat<B: StoreBackend>(backend: Arc<B>) -> HatRc<B> {
    let max_blob_size = 4 * 1024 * 1024;
    HatRc::new_for_testing(backend, max_blob_size).unwrap()
}

fn setup_family() -> (Arc<MemoryBackend>, HatRc<MemoryBackend>, Family<MemoryBackend>) {
    let backend = Arc::new(MemoryBackend::new());
    let mut hat = setup_hat(backend.clone());

    let family = "familyname".to_string();
    let fam = hat.open_family(family).unwrap();

    (backend, hat, fam)
}

pub fn entry(name: Vec<u8>) -> key::Entry {
    key::Entry::new(None, name, None)
}

fn snapshot_files<B: StoreBackend>(family: &Family<B>,
                                   files: Vec<(&str, Vec<u8>)>)
                                   -> Result<(), HatError> {
    let mut dirs = HashMap::new();
    for (name, contents) in files {
        let mut parent = None;
        let mut parts = name.split("/").peekable();
        let mut current = parts.next().unwrap();
        loop {
            if parts.peek().is_none() {
                // Reached the filename part of the string.
                break;
            }
            let mut e = entry(current.bytes().collect());
            e.parent_id = parent.clone();

            parent = dirs.entry((parent, current))
                .or_insert_with(|| {
                    Some(family.snapshot_direct(e, true, None)
                        .unwrap())
                })
                .clone();
            current = parts.next().unwrap();
        }
        if current.len() > 0 {
            // We have a file to insert.
            let mut e = entry(current.bytes().collect());
            e.parent_id = parent.clone();
            family.snapshot_direct(e, false, Some(FileIterator::from_bytes(contents)))?;
        }
    }
    Ok(())
}

fn basic_snapshot<B: StoreBackend>(fam: &Family<B>) {
    snapshot_files(&fam,
                   vec![("zeros", vec![0; 1000000]),
                        ("ones", vec![1; 1000000]),
                        ("twos", vec![2; 1000000]),
                        ("zeros2", vec![0; 1000000]),
                        ("block1", "block1".into()),
                        ("block2", "block2".into()),
                        ("block3", "block3".into()),
                        ("block12", "block1".into()),
                        ("some/number/of/empty/dirs/with/an/empty/file/deep/down", vec![]),
                        ("dir1/zeros", vec![0; 10]),
                        ("dir1/block1", "block1".into()),
                        ("dir1/unique", "abcdefg".into()),
                        ("dir2/zeros", vec![0; 10]),
                        ("dir2/dir3/twos", vec![2; 10]),
                        ("dir2/dir3/dir4/ones", vec![1; 10]),
                        ("x/y/z/a", vec![]),
                        ("x/y/z/b/", vec![]),
                        ("z/y/x/a", vec![]),
                        ("y/x/z/b/", vec![]),
                        ("a/", vec![]),
                        ("b/", vec![]),
                        ("c/", vec![])])
        .unwrap();
}

#[test]
fn snapshot_commit() {
    let (_, mut hat, mut fam) = setup_family();

    basic_snapshot(&fam);

    fam.flush().unwrap();
    hat.commit(&mut fam, None).unwrap();
    hat.meta_commit().unwrap();

    let (deleted, live) = hat.gc().unwrap();
    assert_eq!(deleted, 0);
    assert!(live > 0);
}

#[test]
fn snapshot_commit_many_empty_files() {
    let (_, mut hat, mut fam) = setup_family();

    let names: Vec<String> = (0..3000).map(|i| format!("name-{}", i)).collect();
    snapshot_files(&fam, names.iter().map(|n| (n.as_str(), vec![])).collect()).unwrap();

    fam.flush().unwrap();
    hat.commit(&mut fam, None).unwrap();
    hat.meta_commit().unwrap();

    let (deleted, live) = hat.gc().unwrap();
    assert_eq!(deleted, 0);
    assert!(live > 0);

    hat.deregister(&fam, 1).unwrap();
    let (deleted, live) = hat.gc().unwrap();
    assert!(deleted > 0);
    assert!(live > 0);

    // Delete everything including root.
    hat.delete_all_snapshots().unwrap();
    let (deleted, live) = hat.gc().unwrap();
    assert!(deleted > 0);
    assert_eq!(live, 0);
}

#[test]
fn snapshot_commit_many_empty_directories() {
    let (_, mut hat, mut fam) = setup_family();

    for i in 0..3000 {
        fam.snapshot_direct(entry(format!("name-{}", i).bytes().collect()), true, None)
            .unwrap();
    }

    fam.flush().unwrap();
    hat.commit(&mut fam, None).unwrap();
    hat.meta_commit().unwrap();

    let (deleted, live) = hat.gc().unwrap();
    assert_eq!(deleted, 0);
    assert!(live > 0);

    hat.deregister(&fam, 1).unwrap();
    let (deleted, live) = hat.gc().unwrap();
    assert!(deleted > 0);
    assert!(live > 0);

    // Delete everything including root.
    hat.delete_all_snapshots().unwrap();
    let (deleted, live) = hat.gc().unwrap();
    assert!(deleted > 0);
    assert_eq!(live, 0);
}

#[test]
fn snapshot_reuse_index() {
    let (_, mut hat, mut fam) = setup_family();

    // Insert hashes.
    basic_snapshot(&fam);
    fam.flush().unwrap();

    // Reuse hashes.
    basic_snapshot(&fam);
    basic_snapshot(&fam);
    fam.flush().unwrap();

    // No commit, so GC removes all the new hashes.
    let (deleted, live) = hat.gc().unwrap();
    assert!(deleted > 0);
    assert_eq!(live, 0);

    // Update index and reinsert hashes.
    basic_snapshot(&fam);
    fam.flush().unwrap();

    // Commit.
    hat.commit(&mut fam, None).unwrap();
    let (deleted, live) = hat.gc().unwrap();
    assert_eq!(deleted, 0);
    assert!(live > 0);

    // Inserting again does not increase number of hashes.
    basic_snapshot(&fam);
    fam.flush().unwrap();
    let (deleted2, live2) = hat.gc().unwrap();
    assert_eq!(live2, live);
    assert_eq!(deleted2, 0);

    // Cleanup: only 1 snapshot was committed.
    hat.deregister(&fam, 1).unwrap();
    let (deleted, live) = hat.gc().unwrap();
    assert!(deleted > 0);
    assert_eq!(live, 0);
}

#[test]
fn snapshot_gc() {
    let (_, mut hat, fam) = setup_family();

    basic_snapshot(&fam);
    fam.flush().unwrap();

    // No commit so everything is deleted.
    let (deleted, live) = hat.gc().unwrap();
    assert!(deleted > 0);
    assert_eq!(live, 0);
}

#[test]
fn recover() {
    // Prepare a snapshot.
    let (backend, mut hat, mut fam) = setup_family();
    basic_snapshot(&fam);
    fam.flush().unwrap();

    hat.commit(&mut fam, None).unwrap();
    hat.meta_commit().unwrap();

    let (deleted, live1) = hat.gc().unwrap();
    assert_eq!(deleted, 0);
    assert!(live1 > 0);

    // Create a new hat to wipe the index states.
    let mut hat2 = setup_hat(backend);

    // Recover index states.
    hat2.recover().unwrap();

    // Check that we now reference all the blobs.
    let (deleted, live2) = hat2.gc().unwrap();
    assert_eq!(deleted, 0);
    assert_eq!(live1, live2);

    // Check that we can delete the snapshot.
    hat2.deregister(&fam, 1).unwrap();

    let (deleted, live3) = hat2.gc().unwrap();
    assert!(deleted > 0);
    assert!(live3 > 0);

    // Delete everything including root.
    hat2.delete_all_snapshots().unwrap();
    let (deleted, live4) = hat2.gc().unwrap();
    assert!(deleted > 0);
    assert_eq!(live4, 0);
}
<commit_msg>Add data flush after commit.<commit_after>// Copyright 2014 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use backend::{MemoryBackend, StoreBackend};
use errors::HatError;
use hat::HatRc;
use hat::family::Family;
use key;
use std::collections::HashMap;
use std::sync::Arc;
use util::FileIterator;

pub fn setup_hat<B: StoreBackend>(backend: Arc<B>) -> HatRc<B> {
    let max_blob_size = 4 * 1024 * 1024;
    HatRc::new_for_testing(backend, max_blob_size).unwrap()
}

fn setup_family() -> (Arc<MemoryBackend>, HatRc<MemoryBackend>, Family<MemoryBackend>) {
    let backend = Arc::new(MemoryBackend::new());
    let mut hat = setup_hat(backend.clone());

    let family = "familyname".to_string();
    let fam = hat.open_family(family).unwrap();

    (backend, hat, fam)
}

pub fn entry(name: Vec<u8>) -> key::Entry {
    key::Entry::new(None, name, None)
}

fn snapshot_files<B: StoreBackend>(family: &Family<B>,
                                   files: Vec<(&str, Vec<u8>)>)
                                   -> Result<(), HatError> {
    let mut dirs = HashMap::new();
    for (name, contents) in files {
        let mut parent = None;
        let mut parts = name.split("/").peekable();
        let mut current = parts.next().unwrap();
        loop {
            if parts.peek().is_none() {
                // Reached the filename part of the string.
                break;
            }
            let mut e = entry(current.bytes().collect());
            e.parent_id = parent.clone();

            parent = dirs.entry((parent, current))
                .or_insert_with(|| {
                    Some(family.snapshot_direct(e, true, None)
                        .unwrap())
                })
                .clone();
            current = parts.next().unwrap();
        }
        if current.len() > 0 {
            // We have a file to insert.
            let mut e = entry(current.bytes().collect());
            e.parent_id = parent.clone();
            family.snapshot_direct(e, false, Some(FileIterator::from_bytes(contents)))?;
        }
    }
    Ok(())
}

fn basic_snapshot<B: StoreBackend>(fam: &Family<B>) {
    snapshot_files(&fam,
                   vec![("zeros", vec![0; 1000000]),
                        ("ones", vec![1; 1000000]),
                        ("twos", vec![2; 1000000]),
                        ("zeros2", vec![0; 1000000]),
                        ("block1", "block1".into()),
                        ("block2", "block2".into()),
                        ("block3", "block3".into()),
                        ("block12", "block1".into()),
                        ("some/number/of/empty/dirs/with/an/empty/file/deep/down", vec![]),
                        ("dir1/zeros", vec![0; 10]),
                        ("dir1/block1", "block1".into()),
                        ("dir1/unique", "abcdefg".into()),
                        ("dir2/zeros", vec![0; 10]),
                        ("dir2/dir3/twos", vec![2; 10]),
                        ("dir2/dir3/dir4/ones", vec![1; 10]),
                        ("x/y/z/a", vec![]),
                        ("x/y/z/b/", vec![]),
                        ("z/y/x/a", vec![]),
                        ("y/x/z/b/", vec![]),
                        ("a/", vec![]),
                        ("b/", vec![]),
                        ("c/", vec![])])
        .unwrap();
}

#[test]
fn snapshot_commit() {
    let (_, mut hat, mut fam) = setup_family();

    basic_snapshot(&fam);

    fam.flush().unwrap();
    hat.commit(&mut fam, None).unwrap();
    hat.meta_commit().unwrap();

    let (deleted, live) = hat.gc().unwrap();
    assert_eq!(deleted, 0);
    assert!(live > 0);
}

#[test]
fn snapshot_commit_many_empty_files() {
    let (_, mut hat, mut fam) = setup_family();

    let names: Vec<String> = (0..3000).map(|i| format!("name-{}", i)).collect();
    snapshot_files(&fam, names.iter().map(|n| (n.as_str(), vec![])).collect()).unwrap();

    fam.flush().unwrap();
    hat.commit(&mut fam, None).unwrap();
    hat.meta_commit().unwrap();

    let (deleted, live) = hat.gc().unwrap();
    assert_eq!(deleted, 0);
    assert!(live > 0);

    hat.deregister(&fam, 1).unwrap();
    let (deleted, live) = hat.gc().unwrap();
    assert!(deleted > 0);
    assert!(live > 0);

    // Delete everything including root.
    hat.delete_all_snapshots().unwrap();
    let (deleted, live) = hat.gc().unwrap();
    assert!(deleted > 0);
    assert_eq!(live, 0);
}

#[test]
fn snapshot_commit_many_empty_directories() {
    let (_, mut hat, mut fam) = setup_family();

    for i in 0..3000 {
        fam.snapshot_direct(entry(format!("name-{}", i).bytes().collect()), true, None)
            .unwrap();
    }

    fam.flush().unwrap();
    hat.commit(&mut fam, None).unwrap();
    hat.meta_commit().unwrap();

    let (deleted, live) = hat.gc().unwrap();
    assert_eq!(deleted, 0);
    assert!(live > 0);

    hat.deregister(&fam, 1).unwrap();
    let (deleted, live) = hat.gc().unwrap();
    assert!(deleted > 0);
    assert!(live > 0);

    // Delete everything including root.
    hat.delete_all_snapshots().unwrap();
    let (deleted, live) = hat.gc().unwrap();
    assert!(deleted > 0);
    assert_eq!(live, 0);
}

#[test]
fn snapshot_reuse_index() {
    let (_, mut hat, mut fam) = setup_family();

    // Insert hashes.
    basic_snapshot(&fam);
    fam.flush().unwrap();

    // Reuse hashes.
    basic_snapshot(&fam);
    basic_snapshot(&fam);
    fam.flush().unwrap();

    // No commit, so GC removes all the new hashes.
    let (deleted, live) = hat.gc().unwrap();
    assert!(deleted > 0);
    assert_eq!(live, 0);

    // Update index and reinsert hashes.
    basic_snapshot(&fam);
    fam.flush().unwrap();

    // Commit.
    hat.commit(&mut fam, None).unwrap();
    hat.data_flush().unwrap();
    let (deleted, live) = hat.gc().unwrap();
    assert_eq!(deleted, 0);
    assert!(live > 0);

    // Inserting again does not increase number of hashes.
    basic_snapshot(&fam);
    fam.flush().unwrap();
    let (deleted2, live2) = hat.gc().unwrap();
    assert_eq!(live2, live);
    assert_eq!(deleted2, 0);

    // Cleanup: only 1 snapshot was committed.
    hat.deregister(&fam, 1).unwrap();
    let (deleted, live) = hat.gc().unwrap();
    assert!(deleted > 0);
    assert_eq!(live, 0);
}

#[test]
fn snapshot_gc() {
    let (_, mut hat, fam) = setup_family();

    basic_snapshot(&fam);
    fam.flush().unwrap();

    // No commit so everything is deleted.
    let (deleted, live) = hat.gc().unwrap();
    assert!(deleted > 0);
    assert_eq!(live, 0);
}

#[test]
fn recover() {
    // Prepare a snapshot.
    let (backend, mut hat, mut fam) = setup_family();
    basic_snapshot(&fam);
    fam.flush().unwrap();

    hat.commit(&mut fam, None).unwrap();
    hat.meta_commit().unwrap();
    hat.data_flush().unwrap();

    let (deleted, live1) = hat.gc().unwrap();
    assert_eq!(deleted, 0);
    assert!(live1 > 0);

    // Create a new hat to wipe the index states.
    let mut hat2 = setup_hat(backend);

    // Recover index states.
    hat2.recover().unwrap();

    // Check that we now reference all the blobs.
    let (deleted, live2) = hat2.gc().unwrap();
    assert_eq!(deleted, 0);
    assert_eq!(live1, live2);

    // Check that we can delete the snapshot.
    hat2.deregister(&fam, 1).unwrap();

    let (deleted, live3) = hat2.gc().unwrap();
    assert!(deleted > 0);
    assert!(live3 > 0);

    // Delete everything including root.
    hat2.delete_all_snapshots().unwrap();
    let (deleted, live4) = hat2.gc().unwrap();
    assert!(deleted > 0);
    assert_eq!(live4, 0);
}
<|endoftext|>