<commit_before>// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use super::register::{Register, RegisterInterface, RegisterOffset, RegisterRange, RegisterValue};
use std::collections::btree_map::BTreeMap;

/// Register space repesents a set of registers. It can handle read/write operations.
pub struct RegisterSpace {
    regs: BTreeMap<RegisterRange, Box<RegisterInterface>>,
}

impl RegisterSpace {
    /// Creates a new empty RegisterSpace.
    pub fn new() -> RegisterSpace {
        RegisterSpace {
            regs: BTreeMap::new(),
        }
    }

    /// Add a register to register space.
    pub fn add_register<T: RegisterInterface + 'static>(&mut self, reg: T) {
        let range = reg.range();
        debug_assert!(self.get_register(range.from).is_none());
        if cfg!(debug_assertions) {
            if let Some(r) = self.first_before(range.to) {
                debug_assert!(r.range().to < range.to);
            }
        }

        let insert_result = self.regs.insert(range, Box::new(reg)).is_none();
        debug_assert!(insert_result);
    }

    /// Add an array of registers.
    pub fn add_register_array<T: RegisterValue>(&mut self, regs: &[Register<T>]) {
        for r in regs {
            self.add_register(r.clone());
        }
    }

    /// Read range.
    pub fn read(&self, addr: RegisterOffset, data: &mut [u8]) {
        let mut current_addr: RegisterOffset = addr;
        while current_addr < addr + data.len() as RegisterOffset {
            if let Some(r) = self.get_register(current_addr) {
                // Next addr to read is.
                current_addr = r.range().to + 1;
                r.read(addr, data);
            } else {
                // TODO(jkwang) Add logging for debug here.
                current_addr = current_addr + 1;
            }
        }
    }

    /// Write range. If the targeted register has a callback, it will be invoked with the new
    /// value.
    pub fn write(&self, addr: RegisterOffset, data: &[u8]) {
        let mut current_addr: RegisterOffset = addr;
        while current_addr < addr + data.len() as RegisterOffset {
            if let Some(r) = self.get_register(current_addr) {
                // Next addr to read is, range is inclusive.
                current_addr = r.range().to + 1;
                r.write(addr, data);
            } else {
                current_addr = current_addr + 1;
            }
        }
    }

    /// Get first register before this addr.
    fn first_before(&self, addr: RegisterOffset) -> Option<&Box<RegisterInterface>> {
        for (range, r) in self.regs.iter().rev() {
            if range.from <= addr {
                return Some(r);
            }
        }
        None
    }

    /// Get register at this addr.
    fn get_register(&self, addr: RegisterOffset) -> Option<&Box<RegisterInterface>> {
        let r = self.first_before(addr)?;
        let range = r.range();
        if addr <= range.to {
            Some(r)
        } else {
            None
        }
    }
}

#[cfg(test)]
mod tests {
    use super::super::{RegisterSpec, StaticRegister, StaticRegisterSpec};
    use super::*;
    use std::sync::Arc;
    use sync::Mutex;

    #[test]
    fn regs_no_reg() {
        let regs = RegisterSpace::new();
        let mut data: [u8; 4] = [4, 3, 2, 1];
        // Read should be no op cause no register.
        regs.read(0, &mut data);
        assert_eq!([4, 3, 2, 1], data);
        // Write should be no op.
        regs.write(0, &[0, 0, 0, 0]);
        regs.read(0, &mut data);
        assert_eq!([4, 3, 2, 1], data);
    }

    #[test]
    #[should_panic]
    fn regs_reg_overlap() {
        let mut regs = RegisterSpace::new();
        regs.add_register(static_register!(
        ty: u32,
        offset: 4,
        value: 11,
        ));

        regs.add_register(static_register!(
        ty: u16,
        offset: 7,
        value: 11,
        ));
    }

    #[test]
    fn regs_static_reg() {
        let mut regs = RegisterSpace::new();
        regs.add_register(static_register!(
            ty: u8,
            offset: 0,
            value: 11,
        ));
        let mut data: [u8; 4] = [4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([11, 3, 2, 1], data);
        // Write should be no op.
        regs.write(0, &[0, 0, 0, 0]);
        let mut data: [u8; 4] = [4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([11, 3, 2, 1], data);
    }

    #[test]
    fn regs_static_reg_offset() {
        let mut regs = RegisterSpace::new();
        regs.add_register(static_register!(
            ty: u32,
            offset: 2,
            value: 0xaabbccdd,
        ));
        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data);
        // Write should be no op.
        regs.write(0, &[0, 0, 0, 0, 0, 0, 0, 0]);
        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data);
    }

    #[test]
    fn regs_reg_write() {
        let mut regs = RegisterSpace::new();
        regs.add_register(register!(
            name: "",
            ty: u32,
            offset: 2,
            reset_value: 0xaabbccdd,
        ));
        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data);
        regs.write(0, &[0, 0, 0, 0, 0, 0, 0, 0]);
        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0, 0, 0, 0, 2, 1], data);
    }

    #[test]
    fn regs_reg_writeable() {
        let mut regs = RegisterSpace::new();
        regs.add_register(register!(
            name: "",
            ty: u32,
            offset: 2,
            reset_value: 0xaabbccdd,
            guest_writeable_mask: 0x00f0000f,
            guest_write_1_to_clear_mask: 0,
        ));
        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data);
        regs.write(0, &[0, 0, 0, 0, 0, 0, 0, 0]);
        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0xd0, 0xcc, 0x0b, 0xaa, 2, 1], data);
    }

    #[test]
    fn regs_reg_writeable_callback() {
        let state = Arc::new(Mutex::new(0u32));
        let mut regs = RegisterSpace::new();
        let reg = register!(
            name: "",
            ty: u32,
            offset: 2,
            reset_value: 0xaabbccdd,
            guest_writeable_mask: 0x00f0000f,
            guest_write_1_to_clear_mask: 0,
        );
        regs.add_register(reg.clone());
        let state_clone = state.clone();
        reg.set_write_cb(move |val: u32| {
            *state_clone.lock() = val;
            val
        });

        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data);
        regs.write(0, &[0, 0, 0, 0, 0, 0, 0, 0]);
        assert_eq!(0xaa0bccd0, *state.lock());
    }

    #[test]
    fn regs_reg_write_to_clear() {
        let mut regs = RegisterSpace::new();
        regs.add_register(register!(
        name: "",
        ty: u32,
        offset: 2,
        reset_value: 0xaabbccdd,
        guest_writeable_mask: 0xfff0000f,
        guest_write_1_to_clear_mask: 0xf0000000,
        ));
        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data);
        regs.write(0, &[0, 0, 0, 0, 0, 0xad, 0, 0]);
        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0xd0, 0xcc, 0x0b, 0x0d, 2, 1], data);
    }

    #[test]
    fn regs_reg_array() {
        let mut regs = RegisterSpace::new();
        regs.add_register_array(&register_array!(
            name: "",
            ty: u8,
            cnt: 8,
            base_offset: 10,
            stride: 2,
            reset_value: 0xff,
            guest_writeable_mask: !0,
            guest_write_1_to_clear_mask: 0,
        ));
        let mut data: [u8; 8] = [0; 8];
        regs.read(8, &mut data);
        assert_eq!([0, 0, 0xff, 0, 0xff, 0, 0xff, 0], data);
    }

    #[test]
    fn regs_reg_multi_array() {
        let mut regs = RegisterSpace::new();
        regs.add_register_array(&register_array!(
        name: "",
        ty: u8,
        cnt: 8,
        base_offset: 10,
        stride: 2,
        reset_value: 0xff,
        guest_writeable_mask: !0,
        guest_write_1_to_clear_mask: 0,
        ));
        regs.add_register_array(&register_array!(
        name: "",
        ty: u8,
        cnt: 8,
        base_offset: 11,
        stride: 2,
        reset_value: 0xee,
        guest_writeable_mask: !0,
        guest_write_1_to_clear_mask: 0,
        ));
        let mut data: [u8; 8] = [0; 8];
        regs.read(8, &mut data);
        assert_eq!([0, 0, 0xff, 0xee, 0xff, 0xee, 0xff, 0xee], data);
    }

}
<commit_msg>register_space: Only run panic test when debug assertions are on<commit_after>// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use super::register::{Register, RegisterInterface, RegisterOffset, RegisterRange, RegisterValue};
use std::collections::btree_map::BTreeMap;

/// Register space repesents a set of registers. It can handle read/write operations.
pub struct RegisterSpace {
    regs: BTreeMap<RegisterRange, Box<RegisterInterface>>,
}

impl RegisterSpace {
    /// Creates a new empty RegisterSpace.
    pub fn new() -> RegisterSpace {
        RegisterSpace {
            regs: BTreeMap::new(),
        }
    }

    /// Add a register to register space.
    pub fn add_register<T: RegisterInterface + 'static>(&mut self, reg: T) {
        let range = reg.range();
        debug_assert!(self.get_register(range.from).is_none());
        if cfg!(debug_assertions) {
            if let Some(r) = self.first_before(range.to) {
                debug_assert!(r.range().to < range.to);
            }
        }

        let insert_result = self.regs.insert(range, Box::new(reg)).is_none();
        debug_assert!(insert_result);
    }

    /// Add an array of registers.
    pub fn add_register_array<T: RegisterValue>(&mut self, regs: &[Register<T>]) {
        for r in regs {
            self.add_register(r.clone());
        }
    }

    /// Read range.
    pub fn read(&self, addr: RegisterOffset, data: &mut [u8]) {
        let mut current_addr: RegisterOffset = addr;
        while current_addr < addr + data.len() as RegisterOffset {
            if let Some(r) = self.get_register(current_addr) {
                // Next addr to read is.
                current_addr = r.range().to + 1;
                r.read(addr, data);
            } else {
                // TODO(jkwang) Add logging for debug here.
                current_addr = current_addr + 1;
            }
        }
    }

    /// Write range. If the targeted register has a callback, it will be invoked with the new
    /// value.
    pub fn write(&self, addr: RegisterOffset, data: &[u8]) {
        let mut current_addr: RegisterOffset = addr;
        while current_addr < addr + data.len() as RegisterOffset {
            if let Some(r) = self.get_register(current_addr) {
                // Next addr to read is, range is inclusive.
                current_addr = r.range().to + 1;
                r.write(addr, data);
            } else {
                current_addr = current_addr + 1;
            }
        }
    }

    /// Get first register before this addr.
    fn first_before(&self, addr: RegisterOffset) -> Option<&Box<RegisterInterface>> {
        for (range, r) in self.regs.iter().rev() {
            if range.from <= addr {
                return Some(r);
            }
        }
        None
    }

    /// Get register at this addr.
    fn get_register(&self, addr: RegisterOffset) -> Option<&Box<RegisterInterface>> {
        let r = self.first_before(addr)?;
        let range = r.range();
        if addr <= range.to {
            Some(r)
        } else {
            None
        }
    }
}

#[cfg(test)]
mod tests {
    use super::super::{RegisterSpec, StaticRegister, StaticRegisterSpec};
    use super::*;
    use std::sync::Arc;
    use sync::Mutex;

    #[test]
    fn regs_no_reg() {
        let regs = RegisterSpace::new();
        let mut data: [u8; 4] = [4, 3, 2, 1];
        // Read should be no op cause no register.
        regs.read(0, &mut data);
        assert_eq!([4, 3, 2, 1], data);
        // Write should be no op.
        regs.write(0, &[0, 0, 0, 0]);
        regs.read(0, &mut data);
        assert_eq!([4, 3, 2, 1], data);
    }

    #[test]
    #[should_panic]
    #[cfg(debug_assertions)]
    fn regs_reg_overlap() {
        let mut regs = RegisterSpace::new();
        regs.add_register(static_register!(
        ty: u32,
        offset: 4,
        value: 11,
        ));

        regs.add_register(static_register!(
        ty: u16,
        offset: 7,
        value: 11,
        ));
    }

    #[test]
    fn regs_static_reg() {
        let mut regs = RegisterSpace::new();
        regs.add_register(static_register!(
            ty: u8,
            offset: 0,
            value: 11,
        ));
        let mut data: [u8; 4] = [4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([11, 3, 2, 1], data);
        // Write should be no op.
        regs.write(0, &[0, 0, 0, 0]);
        let mut data: [u8; 4] = [4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([11, 3, 2, 1], data);
    }

    #[test]
    fn regs_static_reg_offset() {
        let mut regs = RegisterSpace::new();
        regs.add_register(static_register!(
            ty: u32,
            offset: 2,
            value: 0xaabbccdd,
        ));
        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data);
        // Write should be no op.
        regs.write(0, &[0, 0, 0, 0, 0, 0, 0, 0]);
        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data);
    }

    #[test]
    fn regs_reg_write() {
        let mut regs = RegisterSpace::new();
        regs.add_register(register!(
            name: "",
            ty: u32,
            offset: 2,
            reset_value: 0xaabbccdd,
        ));
        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data);
        regs.write(0, &[0, 0, 0, 0, 0, 0, 0, 0]);
        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0, 0, 0, 0, 2, 1], data);
    }

    #[test]
    fn regs_reg_writeable() {
        let mut regs = RegisterSpace::new();
        regs.add_register(register!(
            name: "",
            ty: u32,
            offset: 2,
            reset_value: 0xaabbccdd,
            guest_writeable_mask: 0x00f0000f,
            guest_write_1_to_clear_mask: 0,
        ));
        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data);
        regs.write(0, &[0, 0, 0, 0, 0, 0, 0, 0]);
        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0xd0, 0xcc, 0x0b, 0xaa, 2, 1], data);
    }

    #[test]
    fn regs_reg_writeable_callback() {
        let state = Arc::new(Mutex::new(0u32));
        let mut regs = RegisterSpace::new();
        let reg = register!(
            name: "",
            ty: u32,
            offset: 2,
            reset_value: 0xaabbccdd,
            guest_writeable_mask: 0x00f0000f,
            guest_write_1_to_clear_mask: 0,
        );
        regs.add_register(reg.clone());
        let state_clone = state.clone();
        reg.set_write_cb(move |val: u32| {
            *state_clone.lock() = val;
            val
        });

        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data);
        regs.write(0, &[0, 0, 0, 0, 0, 0, 0, 0]);
        assert_eq!(0xaa0bccd0, *state.lock());
    }

    #[test]
    fn regs_reg_write_to_clear() {
        let mut regs = RegisterSpace::new();
        regs.add_register(register!(
        name: "",
        ty: u32,
        offset: 2,
        reset_value: 0xaabbccdd,
        guest_writeable_mask: 0xfff0000f,
        guest_write_1_to_clear_mask: 0xf0000000,
        ));
        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0xdd, 0xcc, 0xbb, 0xaa, 2, 1], data);
        regs.write(0, &[0, 0, 0, 0, 0, 0xad, 0, 0]);
        let mut data: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
        regs.read(0, &mut data);
        assert_eq!([8, 7, 0xd0, 0xcc, 0x0b, 0x0d, 2, 1], data);
    }

    #[test]
    fn regs_reg_array() {
        let mut regs = RegisterSpace::new();
        regs.add_register_array(&register_array!(
            name: "",
            ty: u8,
            cnt: 8,
            base_offset: 10,
            stride: 2,
            reset_value: 0xff,
            guest_writeable_mask: !0,
            guest_write_1_to_clear_mask: 0,
        ));
        let mut data: [u8; 8] = [0; 8];
        regs.read(8, &mut data);
        assert_eq!([0, 0, 0xff, 0, 0xff, 0, 0xff, 0], data);
    }

    #[test]
    fn regs_reg_multi_array() {
        let mut regs = RegisterSpace::new();
        regs.add_register_array(&register_array!(
        name: "",
        ty: u8,
        cnt: 8,
        base_offset: 10,
        stride: 2,
        reset_value: 0xff,
        guest_writeable_mask: !0,
        guest_write_1_to_clear_mask: 0,
        ));
        regs.add_register_array(&register_array!(
        name: "",
        ty: u8,
        cnt: 8,
        base_offset: 11,
        stride: 2,
        reset_value: 0xee,
        guest_writeable_mask: !0,
        guest_write_1_to_clear_mask: 0,
        ));
        let mut data: [u8; 8] = [0; 8];
        regs.read(8, &mut data);
        assert_eq!([0, 0, 0xff, 0xee, 0xff, 0xee, 0xff, 0xee], data);
    }

}
<|endoftext|>


<commit_before>use std::any::TypeId;
use std::borrow::Cow;
use std::cell::{RefCell, RefMut};
use std::collections::HashMap;
use std::hash::Hash;
use std::ops::{Deref, DerefMut};

use backend::Backend;
use query_builder::*;
use result::QueryResult;

#[doc(hidden)]
#[allow(missing_debug_implementations)]
pub struct StatementCache<DB: Backend, Statement> {
    pub cache: RefCell<HashMap<StatementCacheKey<DB>, Statement>>,
}

#[cfg_attr(feature="clippy", allow(len_without_is_empty))]
impl<DB, Statement> StatementCache<DB, Statement> where
    DB: Backend,
    DB::TypeMetadata: Clone,
    DB::QueryBuilder: Default,
    StatementCacheKey<DB>: Hash + Eq,
{
    pub fn new() -> Self {
        StatementCache {
            cache: RefCell::new(HashMap::new())
        }
    }

    pub fn len(&self) -> usize {
        self.cache.borrow().len()
    }

    pub fn cached_statement<T, F>(
        &self,
        source: &T,
        bind_types: &[DB::TypeMetadata],
        prepare_fn: F,
    ) -> QueryResult<MaybeCached<Statement>> where
        T: QueryFragment<DB> + QueryId,
        F: FnOnce(&str) -> QueryResult<Statement>,
    {
        use std::collections::hash_map::Entry::{Occupied, Vacant};

        let cache_key = try!(StatementCacheKey::for_source(source, bind_types));

        if !source.is_safe_to_cache_prepared() {
            let sql = try!(cache_key.sql(source));
            return prepare_fn(&sql).map(MaybeCached::CannotCache)
        }

        refmut_map_result(self.cache.borrow_mut(), |cache| {
            match cache.entry(cache_key) {
                Occupied(entry) => Ok(entry.into_mut()),
                Vacant(entry) => {
                    let statement = {
                        let sql = try!(entry.key().sql(source));
                        prepare_fn(&sql)
                    };

                    Ok(entry.insert(try!(statement)))
                }
            }
        }).map(MaybeCached::Cached)
    }
}

#[doc(hidden)]
#[allow(missing_debug_implementations)]
pub enum MaybeCached<'a, T: 'a> {
    CannotCache(T),
    Cached(RefMut<'a, T>),
}

impl<'a, T> Deref for MaybeCached<'a, T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        match *self {
            MaybeCached::CannotCache(ref x) => x,
            MaybeCached::Cached(ref x) => &**x,
        }
    }
}

impl<'a, T> DerefMut for MaybeCached<'a, T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        match *self {
            MaybeCached::CannotCache(ref mut x) => x,
            MaybeCached::Cached(ref mut x) => &mut **x,
        }
    }
}

#[doc(hidden)]
#[allow(missing_debug_implementations)]
#[derive(Hash, PartialEq, Eq)]
pub enum StatementCacheKey<DB: Backend> {
    Type(TypeId),
    Sql {
        sql: String,
        bind_types: Vec<DB::TypeMetadata>,
    }
}

impl<DB> StatementCacheKey<DB> where
    DB: Backend,
    DB::QueryBuilder: Default,
    DB::TypeMetadata: Clone,
{
    pub fn for_source<T>(source: &T, bind_types: &[DB::TypeMetadata])
        -> QueryResult<Self> where
            T: QueryFragment<DB> + QueryId,
    {
        match T::query_id() {
            Some(id) => Ok(StatementCacheKey::Type(id)),
            None => {
                let sql = try!(Self::construct_sql(source));
                Ok(StatementCacheKey::Sql {
                    sql: sql,
                    bind_types: bind_types.into(),
                })
            }
        }
    }

    pub fn sql<T: QueryFragment<DB>>(&self, source: &T) -> QueryResult<Cow<str>> {
        match *self {
            StatementCacheKey::Type(_) => Self::construct_sql(source).map(Cow::Owned),
            StatementCacheKey::Sql { ref sql, .. } => Ok(Cow::Borrowed(sql)),
        }
    }

    fn construct_sql<T: QueryFragment<DB>>(source: &T) -> QueryResult<String> {
        use result::Error::QueryBuilderError;

        let mut query_builder = DB::QueryBuilder::default();
        try!(source.to_sql(&mut query_builder).map_err(QueryBuilderError));
        Ok(query_builder.finish())
    }
}

fn refmut_map_result<T, U, F>(refmut: RefMut<T>, mapper: F)
    -> QueryResult<RefMut<U>> where
        F: FnOnce(&mut T) -> QueryResult<&mut U>,
{
    use std::mem;

    let mut error = None;
    let result = RefMut::map(refmut, |mutref| match mapper(mutref) {
        Ok(x) => x,
        Err(e) => {
            error = Some(e);
            unsafe { mem::uninitialized() }
        }
    });
    match error {
        Some(e) => Err(e),
        None => Ok(result),
    }
}
<commit_msg>Add some internal documentation about prepared statement caching<commit_after>//! A primer on prepared statement caching in Diesel
//! ------------------------------------------------
//!
//! Diesel uses prepared statements for virtually all queries. This is most
//! visible in our lack of any sort of "quoting" API. Values must always be
//! transmitted as bind parameters, we do not support direct interpolation. The
//! only method in the public API that doesn't require the use of prepared
//! statements is `Connection#batch_execute`.
//!
//! In order to avoid the cost of re-parsing and planning subsequent queries,
//! Diesel caches the prepared statement whenever possible. Queries will fall
//! into one of three buckets:
//!
//! - Unsafe to cache
//! - Cached by SQL
//! - Cached by type
//!
//! A query is considered unsafe to cache if it represents a potentially
//! unbounded number of queries. This is communicated to the connection through
//! `QueryFragment#is_safe_to_cache_prepared`. While this is done as a full AST
//! pass, after monomorphisation and inlining this will usually be optimized to
//! a constant. Only boxed queries will need to do actual work to answer this
//! question.
//!
//! The majority of AST nodes are safe to cache if their components are safe to
//! cache. There are at least 4 cases where a query is unsafe to cache:
//!
//! - queries containing `IN` with bind parameters
//!     - This requires 1 bind parameter per value, and is therefore unbounded
//!     - `IN` with subselects are cached (assuming the subselect is safe to
//!        cache)
//! - `INSERT` statements
//!     - The SQL varies based on the number of rows being inserted. We could in
//!       theory cache the single row case, but the cost of parsing in a write
//!       query is pretty insignificant compared to reads
//! - `UPDATE` statements
//!     - Technically it's bounded on "number of optional values being passed to
//!       `SET` factorial" but that's still quite high, and not worth caching
//!       for the same reason as single row inserts
//! - `SqlLiteral` nodes
//!     - We have no way of knowing whether the SQL was generated dynamically or
//!       not, so we must assume that it's unbounded
//!
//! For queries which are unsafe to cache, the statement cache will never insert
//! them. They will be prepared and immediately released after use (or in the
//! case of PG they will use the unnamed prepared statement).
//!
//! For statements which are able to be cached, we then have to determine what
//! to use as the cache key. The standard method that virtually all ORMs or
//! database access layers use in the wild is to store the statements in a
//! hash map, using the SQL as the key.
//!
//! However, the majority of queries using Diesel that are safe to cache as
//! prepared statements will be uniquely identified by their type. For these
//! queries, we can bypass the query builder entirely. Since our AST is
//! generally optimized away by the compiler, for these queries the cost of
//! fetching a prepared statement from the cache is the cost of `HashMap<u32,
//! _>::get`, where the key we're fetching by is a compile time constant. For
//! these types, the AST pass to gather the bind parameters will also be
//! optimized to accessing each parameter individually.
//!
//! Determining if a query can be cached by type is the responsibility of the
//! `QueryId` trait. This trait is quite similar to `Any`, but with a few
//! differences:
//!
//! - No `'static` bound
//!     - Something being a reference never changes the SQL that is generated,
//!       so `&T` has the same query id as `T`.
//! - `Option<TypeId>` instead of `TypeId`
//!     - We need to be able to constrain on this trait being implemented, but
//!       not all types will actually have a static query id. Hopefully once
//!       specialization is stable we can remove the `QueryId` bound and
//!       specialize on it instead (or provide a blanket impl for all `T`)
//! - Implementors give a more broad type than `Self`
//!     - This really only affects bind parameters. There are 6 different Rust
//!       types which can be used for a parameter of type `timestamp`. The same
//!       statement can be used regardless of the Rust type, so `Bound<ST, T>`
//!       defines its `QueryId` as `Bound<ST, ()>`.
//!
//! A type returning `Some(id)` or `None` for its query ID is based on whether
//! the SQL it generates can change without the type changing. At the moment,
//! the only type which is safe to cache as a prepared statement but does not
//! have a static query ID is something which has been boxed.
//!
//! One potential optimization that we don't perform is storing the queries
//! which are cached by type ID in a separate map. Since a type ID is a u64,
//! this would allow us to use a specialized map which knows that there will
//! never be hashing collisions (also known as a perfect hashing function),
//! which would mean lookups are always constant time. However, this would save
//! nanoseconds on an operation that will take microseconds or even
//! milliseconds.

use std::any::TypeId;
use std::borrow::Cow;
use std::cell::{RefCell, RefMut};
use std::collections::HashMap;
use std::hash::Hash;
use std::ops::{Deref, DerefMut};

use backend::Backend;
use query_builder::*;
use result::QueryResult;

#[doc(hidden)]
#[allow(missing_debug_implementations)]
pub struct StatementCache<DB: Backend, Statement> {
    pub cache: RefCell<HashMap<StatementCacheKey<DB>, Statement>>,
}

#[cfg_attr(feature="clippy", allow(len_without_is_empty))]
impl<DB, Statement> StatementCache<DB, Statement> where
    DB: Backend,
    DB::TypeMetadata: Clone,
    DB::QueryBuilder: Default,
    StatementCacheKey<DB>: Hash + Eq,
{
    pub fn new() -> Self {
        StatementCache {
            cache: RefCell::new(HashMap::new())
        }
    }

    pub fn len(&self) -> usize {
        self.cache.borrow().len()
    }

    pub fn cached_statement<T, F>(
        &self,
        source: &T,
        bind_types: &[DB::TypeMetadata],
        prepare_fn: F,
    ) -> QueryResult<MaybeCached<Statement>> where
        T: QueryFragment<DB> + QueryId,
        F: FnOnce(&str) -> QueryResult<Statement>,
    {
        use std::collections::hash_map::Entry::{Occupied, Vacant};

        let cache_key = try!(StatementCacheKey::for_source(source, bind_types));

        if !source.is_safe_to_cache_prepared() {
            let sql = try!(cache_key.sql(source));
            return prepare_fn(&sql).map(MaybeCached::CannotCache)
        }

        refmut_map_result(self.cache.borrow_mut(), |cache| {
            match cache.entry(cache_key) {
                Occupied(entry) => Ok(entry.into_mut()),
                Vacant(entry) => {
                    let statement = {
                        let sql = try!(entry.key().sql(source));
                        prepare_fn(&sql)
                    };

                    Ok(entry.insert(try!(statement)))
                }
            }
        }).map(MaybeCached::Cached)
    }
}

#[doc(hidden)]
#[allow(missing_debug_implementations)]
pub enum MaybeCached<'a, T: 'a> {
    CannotCache(T),
    Cached(RefMut<'a, T>),
}

impl<'a, T> Deref for MaybeCached<'a, T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        match *self {
            MaybeCached::CannotCache(ref x) => x,
            MaybeCached::Cached(ref x) => &**x,
        }
    }
}

impl<'a, T> DerefMut for MaybeCached<'a, T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        match *self {
            MaybeCached::CannotCache(ref mut x) => x,
            MaybeCached::Cached(ref mut x) => &mut **x,
        }
    }
}

#[doc(hidden)]
#[allow(missing_debug_implementations)]
#[derive(Hash, PartialEq, Eq)]
pub enum StatementCacheKey<DB: Backend> {
    Type(TypeId),
    Sql {
        sql: String,
        bind_types: Vec<DB::TypeMetadata>,
    }
}

impl<DB> StatementCacheKey<DB> where
    DB: Backend,
    DB::QueryBuilder: Default,
    DB::TypeMetadata: Clone,
{
    pub fn for_source<T>(source: &T, bind_types: &[DB::TypeMetadata])
        -> QueryResult<Self> where
            T: QueryFragment<DB> + QueryId,
    {
        match T::query_id() {
            Some(id) => Ok(StatementCacheKey::Type(id)),
            None => {
                let sql = try!(Self::construct_sql(source));
                Ok(StatementCacheKey::Sql {
                    sql: sql,
                    bind_types: bind_types.into(),
                })
            }
        }
    }

    pub fn sql<T: QueryFragment<DB>>(&self, source: &T) -> QueryResult<Cow<str>> {
        match *self {
            StatementCacheKey::Type(_) => Self::construct_sql(source).map(Cow::Owned),
            StatementCacheKey::Sql { ref sql, .. } => Ok(Cow::Borrowed(sql)),
        }
    }

    fn construct_sql<T: QueryFragment<DB>>(source: &T) -> QueryResult<String> {
        use result::Error::QueryBuilderError;

        let mut query_builder = DB::QueryBuilder::default();
        try!(source.to_sql(&mut query_builder).map_err(QueryBuilderError));
        Ok(query_builder.finish())
    }
}

/// Similar to `RefMut::map`, but for functions which return `Result`
///
/// If we were in Haskell (and if `RefMut` were a functor), this would just be
/// `sequenceA`.
fn refmut_map_result<T, U, F>(refmut: RefMut<T>, mapper: F)
    -> QueryResult<RefMut<U>> where
        F: FnOnce(&mut T) -> QueryResult<&mut U>,
{
    use std::mem;

    let mut error = None;
    let result = RefMut::map(refmut, |mutref| match mapper(mutref) {
        Ok(x) => x,
        Err(e) => {
            error = Some(e);
            unsafe { mem::uninitialized() }
        }
    });
    match error {
        Some(e) => Err(e),
        None => Ok(result),
    }
}
<|endoftext|>


<commit_before>use crate::task::{waker_ref, ArcWake};
use futures_core::future::{FusedFuture, Future};
use futures_core::task::{Context, Poll, Waker};
use slab::Slab;
use std::cell::UnsafeCell;
use std::fmt;
use std::pin::Pin;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::{Acquire, SeqCst};
use std::sync::{Arc, Mutex, Weak};

/// Future for the [`shared`](super::FutureExt::shared) method.
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Shared<Fut: Future> {
    inner: Option<Arc<Inner<Fut>>>,
    waker_key: usize,
}

struct Inner<Fut: Future> {
    future_or_output: UnsafeCell<FutureOrOutput<Fut>>,
    notifier: Arc<Notifier>,
}

struct Notifier {
    state: AtomicUsize,
    wakers: Mutex<Option<Slab<Option<Waker>>>>,
}

/// A weak reference to a [`Shared`] that can be upgraded much like an `Arc`.
pub struct WeakShared<Fut: Future>(Weak<Inner<Fut>>);

// The future itself is polled behind the `Arc`, so it won't be moved
// when `Shared` is moved.
impl<Fut: Future> Unpin for Shared<Fut> {}

impl<Fut: Future> fmt::Debug for Shared<Fut> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Shared")
            .field("inner", &self.inner)
            .field("waker_key", &self.waker_key)
            .finish()
    }
}

impl<Fut: Future> fmt::Debug for Inner<Fut> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Inner").finish()
    }
}

impl<Fut: Future> fmt::Debug for WeakShared<Fut> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("WeakShared").finish()
    }
}

enum FutureOrOutput<Fut: Future> {
    Future(Fut),
    Output(Fut::Output),
}

unsafe impl<Fut> Send for Inner<Fut>
where
    Fut: Future + Send,
    Fut::Output: Send + Sync,
{
}

unsafe impl<Fut> Sync for Inner<Fut>
where
    Fut: Future + Send,
    Fut::Output: Send + Sync,
{
}

const IDLE: usize = 0;
const POLLING: usize = 1;
const COMPLETE: usize = 2;
const POISONED: usize = 3;

const NULL_WAKER_KEY: usize = usize::max_value();

impl<Fut: Future> Shared<Fut> {
    pub(super) fn new(future: Fut) -> Self {
        let inner = Inner {
            future_or_output: UnsafeCell::new(FutureOrOutput::Future(future)),
            notifier: Arc::new(Notifier {
                state: AtomicUsize::new(IDLE),
                wakers: Mutex::new(Some(Slab::new())),
            }),
        };

        Self { inner: Some(Arc::new(inner)), waker_key: NULL_WAKER_KEY }
    }
}

impl<Fut> Shared<Fut>
where
    Fut: Future,
    Fut::Output: Clone,
{
    /// Returns [`Some`] containing a reference to this [`Shared`]'s output if
    /// it has already been computed by a clone or [`None`] if it hasn't been
    /// computed yet or this [`Shared`] already returned its output from
    /// [`poll`](Future::poll).
    pub fn peek(&self) -> Option<&Fut::Output> {
        if let Some(inner) = self.inner.as_ref() {
            match inner.notifier.state.load(SeqCst) {
                COMPLETE => unsafe { return Some(inner.output()) },
                POISONED => panic!("inner future panicked during poll"),
                _ => {}
            }
        }
        None
    }

    /// Creates a new [`WeakShared`] for this [`Shared`].
    ///
    /// Returns [`None`] if it has already been polled to completion.
    pub fn downgrade(&self) -> Option<WeakShared<Fut>> {
        if let Some(inner) = self.inner.as_ref() {
            return Some(WeakShared(Arc::downgrade(inner)));
        }
        None
    }

    /// Gets the number of strong pointers to this allocation.
    ///
    /// Returns [`None`] if it has already been polled to completion.
    ///
    /// # Safety
    ///
    /// This method by itself is safe, but using it correctly requires extra care. Another thread
    /// can change the strong count at any time, including potentially between calling this method
    /// and acting on the result.
    pub fn strong_count(&self) -> Option<usize> {
        self.inner.as_ref().map(|arc| Arc::strong_count(arc))
    }

    /// Gets the number of weak pointers to this allocation.
    ///
    /// Returns [`None`] if it has already been polled to completion.
    ///
    /// # Safety
    ///
    /// This method by itself is safe, but using it correctly requires extra care. Another thread
    /// can change the weak count at any time, including potentially between calling this method
    /// and acting on the result.
    pub fn weak_count(&self) -> Option<usize> {
        self.inner.as_ref().map(|arc| Arc::weak_count(arc))
    }
}

impl<Fut> Inner<Fut>
where
    Fut: Future,
    Fut::Output: Clone,
{
    /// Safety: callers must first ensure that `self.inner.state`
    /// is `COMPLETE`
    unsafe fn output(&self) -> &Fut::Output {
        match &*self.future_or_output.get() {
            FutureOrOutput::Output(ref item) => item,
            FutureOrOutput::Future(_) => unreachable!(),
        }
    }
    /// Registers the current task to receive a wakeup when we are awoken.
    fn record_waker(&self, waker_key: &mut usize, cx: &mut Context<'_>) {
        let mut wakers_guard = self.notifier.wakers.lock().unwrap();

        let wakers = match wakers_guard.as_mut() {
            Some(wakers) => wakers,
            None => return,
        };

        let new_waker = cx.waker();

        if *waker_key == NULL_WAKER_KEY {
            *waker_key = wakers.insert(Some(new_waker.clone()));
        } else {
            match wakers[*waker_key] {
                Some(ref old_waker) if new_waker.will_wake(old_waker) => {}
                // Could use clone_from here, but Waker doesn't specialize it.
                ref mut slot => *slot = Some(new_waker.clone()),
            }
        }
        debug_assert!(*waker_key != NULL_WAKER_KEY);
    }

    /// Safety: callers must first ensure that `inner.state`
    /// is `COMPLETE`
    unsafe fn take_or_clone_output(self: Arc<Self>) -> Fut::Output {
        match Arc::try_unwrap(self) {
            Ok(inner) => match inner.future_or_output.into_inner() {
                FutureOrOutput::Output(item) => item,
                FutureOrOutput::Future(_) => unreachable!(),
            },
            Err(inner) => inner.output().clone(),
        }
    }
}

impl<Fut> FusedFuture for Shared<Fut>
where
    Fut: Future,
    Fut::Output: Clone,
{
    fn is_terminated(&self) -> bool {
        self.inner.is_none()
    }
}

impl<Fut> Future for Shared<Fut>
where
    Fut: Future,
    Fut::Output: Clone,
{
    type Output = Fut::Output;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let this = &mut *self;

        let inner = this.inner.take().expect("Shared future polled again after completion");

        // Fast path for when the wrapped future has already completed
        if inner.notifier.state.load(Acquire) == COMPLETE {
            // Safety: We're in the COMPLETE state
            return unsafe { Poll::Ready(inner.take_or_clone_output()) };
        }

        inner.record_waker(&mut this.waker_key, cx);

        match inner
            .notifier
            .state
            .compare_exchange(IDLE, POLLING, SeqCst, SeqCst)
            .unwrap_or_else(|x| x)
        {
            IDLE => {
                // Lock acquired, fall through
            }
            POLLING => {
                // Another task is currently polling, at this point we just want
                // to ensure that the waker for this task is registered
                this.inner = Some(inner);
                return Poll::Pending;
            }
            COMPLETE => {
                // Safety: We're in the COMPLETE state
                return unsafe { Poll::Ready(inner.take_or_clone_output()) };
            }
            POISONED => panic!("inner future panicked during poll"),
            _ => unreachable!(),
        }

        let waker = waker_ref(&inner.notifier);
        let mut cx = Context::from_waker(&waker);

        struct Reset<'a>(&'a AtomicUsize);

        impl Drop for Reset<'_> {
            fn drop(&mut self) {
                use std::thread;

                if thread::panicking() {
                    self.0.store(POISONED, SeqCst);
                }
            }
        }

        let _reset = Reset(&inner.notifier.state);

        let output = {
            let future = unsafe {
                match &mut *inner.future_or_output.get() {
                    FutureOrOutput::Future(fut) => Pin::new_unchecked(fut),
                    _ => unreachable!(),
                }
            };

            match future.poll(&mut cx) {
                Poll::Pending => {
                    if inner.notifier.state.compare_exchange(POLLING, IDLE, SeqCst, SeqCst).is_ok()
                    {
                        // Success
                        drop(_reset);
                        this.inner = Some(inner);
                        return Poll::Pending;
                    } else {
                        unreachable!()
                    }
                }
                Poll::Ready(output) => output,
            }
        };

        unsafe {
            *inner.future_or_output.get() = FutureOrOutput::Output(output);
        }

        inner.notifier.state.store(COMPLETE, SeqCst);

        // Wake all tasks and drop the slab
        let mut wakers_guard = inner.notifier.wakers.lock().unwrap();
        let mut wakers = wakers_guard.take().unwrap();
        for waker in wakers.drain().flatten() {
            waker.wake();
        }

        drop(_reset); // Make borrow checker happy
        drop(wakers_guard);

        // Safety: We're in the COMPLETE state
        unsafe { Poll::Ready(inner.take_or_clone_output()) }
    }
}

impl<Fut> Clone for Shared<Fut>
where
    Fut: Future,
{
    fn clone(&self) -> Self {
        Self { inner: self.inner.clone(), waker_key: NULL_WAKER_KEY }
    }
}

impl<Fut> Drop for Shared<Fut>
where
    Fut: Future,
{
    fn drop(&mut self) {
        if self.waker_key != NULL_WAKER_KEY {
            if let Some(ref inner) = self.inner {
                if let Ok(mut wakers) = inner.notifier.wakers.lock() {
                    if let Some(wakers) = wakers.as_mut() {
                        wakers.remove(self.waker_key);
                    }
                }
            }
        }
    }
}

impl ArcWake for Notifier {
    fn wake_by_ref(arc_self: &Arc<Self>) {
        let wakers = &mut *arc_self.wakers.lock().unwrap();
        if let Some(wakers) = wakers.as_mut() {
            for (_key, opt_waker) in wakers {
                if let Some(waker) = opt_waker.take() {
                    waker.wake();
                }
            }
        }
    }
}

impl<Fut: Future> WeakShared<Fut> {
    /// Attempts to upgrade this [`WeakShared`] into a [`Shared`].
    ///
    /// Returns [`None`] if all clones of the [`Shared`] have been dropped or polled
    /// to completion.
    pub fn upgrade(&self) -> Option<Shared<Fut>> {
        Some(Shared { inner: Some(self.0.upgrade()?), waker_key: NULL_WAKER_KEY })
    }
}
<commit_msg>Add Clone to WeakShared<commit_after>use crate::task::{waker_ref, ArcWake};
use futures_core::future::{FusedFuture, Future};
use futures_core::task::{Context, Poll, Waker};
use slab::Slab;
use std::cell::UnsafeCell;
use std::fmt;
use std::pin::Pin;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::{Acquire, SeqCst};
use std::sync::{Arc, Mutex, Weak};

/// Future for the [`shared`](super::FutureExt::shared) method.
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Shared<Fut: Future> {
    inner: Option<Arc<Inner<Fut>>>,
    waker_key: usize,
}

struct Inner<Fut: Future> {
    future_or_output: UnsafeCell<FutureOrOutput<Fut>>,
    notifier: Arc<Notifier>,
}

struct Notifier {
    state: AtomicUsize,
    wakers: Mutex<Option<Slab<Option<Waker>>>>,
}

/// A weak reference to a [`Shared`] that can be upgraded much like an `Arc`.
pub struct WeakShared<Fut: Future>(Weak<Inner<Fut>>);

impl<Fut: Future> Clone for WeakShared<Fut> {
    fn clone(&self) -> Self {
        Self(self.0.clone())
    }
}

// The future itself is polled behind the `Arc`, so it won't be moved
// when `Shared` is moved.
impl<Fut: Future> Unpin for Shared<Fut> {}

impl<Fut: Future> fmt::Debug for Shared<Fut> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Shared")
            .field("inner", &self.inner)
            .field("waker_key", &self.waker_key)
            .finish()
    }
}

impl<Fut: Future> fmt::Debug for Inner<Fut> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Inner").finish()
    }
}

impl<Fut: Future> fmt::Debug for WeakShared<Fut> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("WeakShared").finish()
    }
}

enum FutureOrOutput<Fut: Future> {
    Future(Fut),
    Output(Fut::Output),
}

unsafe impl<Fut> Send for Inner<Fut>
where
    Fut: Future + Send,
    Fut::Output: Send + Sync,
{
}

unsafe impl<Fut> Sync for Inner<Fut>
where
    Fut: Future + Send,
    Fut::Output: Send + Sync,
{
}

const IDLE: usize = 0;
const POLLING: usize = 1;
const COMPLETE: usize = 2;
const POISONED: usize = 3;

const NULL_WAKER_KEY: usize = usize::max_value();

impl<Fut: Future> Shared<Fut> {
    pub(super) fn new(future: Fut) -> Self {
        let inner = Inner {
            future_or_output: UnsafeCell::new(FutureOrOutput::Future(future)),
            notifier: Arc::new(Notifier {
                state: AtomicUsize::new(IDLE),
                wakers: Mutex::new(Some(Slab::new())),
            }),
        };

        Self { inner: Some(Arc::new(inner)), waker_key: NULL_WAKER_KEY }
    }
}

impl<Fut> Shared<Fut>
where
    Fut: Future,
    Fut::Output: Clone,
{
    /// Returns [`Some`] containing a reference to this [`Shared`]'s output if
    /// it has already been computed by a clone or [`None`] if it hasn't been
    /// computed yet or this [`Shared`] already returned its output from
    /// [`poll`](Future::poll).
    pub fn peek(&self) -> Option<&Fut::Output> {
        if let Some(inner) = self.inner.as_ref() {
            match inner.notifier.state.load(SeqCst) {
                COMPLETE => unsafe { return Some(inner.output()) },
                POISONED => panic!("inner future panicked during poll"),
                _ => {}
            }
        }
        None
    }

    /// Creates a new [`WeakShared`] for this [`Shared`].
    ///
    /// Returns [`None`] if it has already been polled to completion.
    pub fn downgrade(&self) -> Option<WeakShared<Fut>> {
        if let Some(inner) = self.inner.as_ref() {
            return Some(WeakShared(Arc::downgrade(inner)));
        }
        None
    }

    /// Gets the number of strong pointers to this allocation.
    ///
    /// Returns [`None`] if it has already been polled to completion.
    ///
    /// # Safety
    ///
    /// This method by itself is safe, but using it correctly requires extra care. Another thread
    /// can change the strong count at any time, including potentially between calling this method
    /// and acting on the result.
    pub fn strong_count(&self) -> Option<usize> {
        self.inner.as_ref().map(|arc| Arc::strong_count(arc))
    }

    /// Gets the number of weak pointers to this allocation.
    ///
    /// Returns [`None`] if it has already been polled to completion.
    ///
    /// # Safety
    ///
    /// This method by itself is safe, but using it correctly requires extra care. Another thread
    /// can change the weak count at any time, including potentially between calling this method
    /// and acting on the result.
    pub fn weak_count(&self) -> Option<usize> {
        self.inner.as_ref().map(|arc| Arc::weak_count(arc))
    }
}

impl<Fut> Inner<Fut>
where
    Fut: Future,
    Fut::Output: Clone,
{
    /// Safety: callers must first ensure that `self.inner.state`
    /// is `COMPLETE`
    unsafe fn output(&self) -> &Fut::Output {
        match &*self.future_or_output.get() {
            FutureOrOutput::Output(ref item) => item,
            FutureOrOutput::Future(_) => unreachable!(),
        }
    }
    /// Registers the current task to receive a wakeup when we are awoken.
    fn record_waker(&self, waker_key: &mut usize, cx: &mut Context<'_>) {
        let mut wakers_guard = self.notifier.wakers.lock().unwrap();

        let wakers = match wakers_guard.as_mut() {
            Some(wakers) => wakers,
            None => return,
        };

        let new_waker = cx.waker();

        if *waker_key == NULL_WAKER_KEY {
            *waker_key = wakers.insert(Some(new_waker.clone()));
        } else {
            match wakers[*waker_key] {
                Some(ref old_waker) if new_waker.will_wake(old_waker) => {}
                // Could use clone_from here, but Waker doesn't specialize it.
                ref mut slot => *slot = Some(new_waker.clone()),
            }
        }
        debug_assert!(*waker_key != NULL_WAKER_KEY);
    }

    /// Safety: callers must first ensure that `inner.state`
    /// is `COMPLETE`
    unsafe fn take_or_clone_output(self: Arc<Self>) -> Fut::Output {
        match Arc::try_unwrap(self) {
            Ok(inner) => match inner.future_or_output.into_inner() {
                FutureOrOutput::Output(item) => item,
                FutureOrOutput::Future(_) => unreachable!(),
            },
            Err(inner) => inner.output().clone(),
        }
    }
}

impl<Fut> FusedFuture for Shared<Fut>
where
    Fut: Future,
    Fut::Output: Clone,
{
    fn is_terminated(&self) -> bool {
        self.inner.is_none()
    }
}

impl<Fut> Future for Shared<Fut>
where
    Fut: Future,
    Fut::Output: Clone,
{
    type Output = Fut::Output;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let this = &mut *self;

        let inner = this.inner.take().expect("Shared future polled again after completion");

        // Fast path for when the wrapped future has already completed
        if inner.notifier.state.load(Acquire) == COMPLETE {
            // Safety: We're in the COMPLETE state
            return unsafe { Poll::Ready(inner.take_or_clone_output()) };
        }

        inner.record_waker(&mut this.waker_key, cx);

        match inner
            .notifier
            .state
            .compare_exchange(IDLE, POLLING, SeqCst, SeqCst)
            .unwrap_or_else(|x| x)
        {
            IDLE => {
                // Lock acquired, fall through
            }
            POLLING => {
                // Another task is currently polling, at this point we just want
                // to ensure that the waker for this task is registered
                this.inner = Some(inner);
                return Poll::Pending;
            }
            COMPLETE => {
                // Safety: We're in the COMPLETE state
                return unsafe { Poll::Ready(inner.take_or_clone_output()) };
            }
            POISONED => panic!("inner future panicked during poll"),
            _ => unreachable!(),
        }

        let waker = waker_ref(&inner.notifier);
        let mut cx = Context::from_waker(&waker);

        struct Reset<'a>(&'a AtomicUsize);

        impl Drop for Reset<'_> {
            fn drop(&mut self) {
                use std::thread;

                if thread::panicking() {
                    self.0.store(POISONED, SeqCst);
                }
            }
        }

        let _reset = Reset(&inner.notifier.state);

        let output = {
            let future = unsafe {
                match &mut *inner.future_or_output.get() {
                    FutureOrOutput::Future(fut) => Pin::new_unchecked(fut),
                    _ => unreachable!(),
                }
            };

            match future.poll(&mut cx) {
                Poll::Pending => {
                    if inner.notifier.state.compare_exchange(POLLING, IDLE, SeqCst, SeqCst).is_ok()
                    {
                        // Success
                        drop(_reset);
                        this.inner = Some(inner);
                        return Poll::Pending;
                    } else {
                        unreachable!()
                    }
                }
                Poll::Ready(output) => output,
            }
        };

        unsafe {
            *inner.future_or_output.get() = FutureOrOutput::Output(output);
        }

        inner.notifier.state.store(COMPLETE, SeqCst);

        // Wake all tasks and drop the slab
        let mut wakers_guard = inner.notifier.wakers.lock().unwrap();
        let mut wakers = wakers_guard.take().unwrap();
        for waker in wakers.drain().flatten() {
            waker.wake();
        }

        drop(_reset); // Make borrow checker happy
        drop(wakers_guard);

        // Safety: We're in the COMPLETE state
        unsafe { Poll::Ready(inner.take_or_clone_output()) }
    }
}

impl<Fut> Clone for Shared<Fut>
where
    Fut: Future,
{
    fn clone(&self) -> Self {
        Self { inner: self.inner.clone(), waker_key: NULL_WAKER_KEY }
    }
}

impl<Fut> Drop for Shared<Fut>
where
    Fut: Future,
{
    fn drop(&mut self) {
        if self.waker_key != NULL_WAKER_KEY {
            if let Some(ref inner) = self.inner {
                if let Ok(mut wakers) = inner.notifier.wakers.lock() {
                    if let Some(wakers) = wakers.as_mut() {
                        wakers.remove(self.waker_key);
                    }
                }
            }
        }
    }
}

impl ArcWake for Notifier {
    fn wake_by_ref(arc_self: &Arc<Self>) {
        let wakers = &mut *arc_self.wakers.lock().unwrap();
        if let Some(wakers) = wakers.as_mut() {
            for (_key, opt_waker) in wakers {
                if let Some(waker) = opt_waker.take() {
                    waker.wake();
                }
            }
        }
    }
}

impl<Fut: Future> WeakShared<Fut> {
    /// Attempts to upgrade this [`WeakShared`] into a [`Shared`].
    ///
    /// Returns [`None`] if all clones of the [`Shared`] have been dropped or polled
    /// to completion.
    pub fn upgrade(&self) -> Option<Shared<Fut>> {
        Some(Shared { inner: Some(self.0.upgrade()?), waker_key: NULL_WAKER_KEY })
    }
}
<|endoftext|>


<commit_before>use std::num;

pub trait Addressable<ADDR: Int, DATA: Int> {
	pub fn get (&self, addr: ADDR) -> DATA;
	pub fn set (&mut self, addr: ADDR, data: DATA);
}

// FIXME: With default methods, we won't need this anymore
trait AddressableUtil<ADDR: Int, DATA: Int> {
	pub fn get_be<T: Int> (&self, addr: ADDR) -> T;
	pub fn get_le<T: Int> (&self, addr: ADDR) -> T;
	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T);
	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T);
}

impl<ADDR: Int, DATA: Int, A: Addressable<ADDR, DATA>> AddressableUtil<ADDR, DATA> for A {
	pub fn get_be<T: Int> (&self, addr: ADDR) -> T {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mut val = num::Zero::zero::<T>();
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast((count-i-1) * num::Primitive::bits::<DATA>());
			let d: T = num::cast(self.get(addr + num::cast(i)));
			val = val + (d << shift);
		}
		val
	}

	pub fn get_le<T: Int> (&self, addr: ADDR) -> T {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mut val = num::Zero::zero::<T>();
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast(i * num::Primitive::bits::<DATA>());
			let d: T = num::cast(self.get(addr + num::cast(i)));
			val = val + (d << shift);
		}
		val
	}

	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T) {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mask = (1 << num::Primitive::bits::<DATA>()) - 1;
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast((count-i-1) * num::Primitive::bits::<DATA>());
			let d: DATA = num::cast((val >> shift) & num::cast(mask));
			self.set(addr + num::cast(i), d);
		}
	}

	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T) {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mask = (1 << num::Primitive::bits::<DATA>()) - 1;
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast(i * num::Primitive::bits::<DATA>());
			let d: DATA = num::cast((val >> shift) & num::cast(mask));
			self.set(addr + num::cast(i), d);
		}
	}
}

#[cfg(test)]
mod tests {
	use super::*;

	struct DummyData;
	impl Addressable<u16, u8> for DummyData {
		pub fn get (&self, addr: u16) -> u8 {
			addr as u8
		}
		pub fn set (&mut self, addr: u16, data: u8) {
			assert_eq!(data, addr as u8);
		}
	}

	#[test]
	fn test_get () {
		let data = DummyData;
		assert_eq!(data.get(0x12), 0x12);
		assert_eq!(data.get(0x1234), 0x34);
	}

	#[test]
	fn test_get_big_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_be(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_be(0x0054_u16));
		assert_eq!(    0x0203_u16, data.get_be(0x0002_u16));
		assert_eq!(    0x5455_u16, data.get_be(0x0054_u16));
		assert_eq!(0x02030405_u32, data.get_be(0x0002_u16));
		assert_eq!(0x54555657_u32, data.get_be(0x0054_u16));
	}

	#[test]
	fn test_get_little_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_le(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_le(0x0054_u16));
		assert_eq!(    0x0302_u16, data.get_le(0x0002_u16));
		assert_eq!(    0x5554_u16, data.get_le(0x0054_u16));
		assert_eq!(0x05040302_u32, data.get_le(0x0002_u16));
		assert_eq!(0x57565554_u32, data.get_le(0x0054_u16));
	}

	#[test]
	fn test_set () {
		let mut data = DummyData;
		data.set(0x12, 0x12);
		data.set(0x1234, 0x34);
	}

	#[test]
	fn test_set_big_endian () {
		let mut data = DummyData;
		data.set_be(0x0002_u16, 0x02_u8);
		data.set_be(0x0054_u16, 0x54_u8);
		data.set_be(0x0002_u16, 0x0203_u16);
		data.set_be(0x0054_u16, 0x5455_u16);
		data.set_be(0x0002_u16, 0x02030405_u32);
		data.set_be(0x0054_u16, 0x54555657_u32);
	}

	#[test]
	fn test_set_little_endian () {
		let mut data = DummyData;
		data.set_le(0x0002_u16, 0x02_u8);
		data.set_le(0x0054_u16, 0x54_u8);
		data.set_le(0x0002_u16, 0x0302_u16);
		data.set_le(0x0054_u16, 0x5554_u16);
		data.set_le(0x0002_u16, 0x05040302_u32);
		data.set_le(0x0054_u16, 0x57565554_u32);
	}
}
<commit_msg>Made addressable until trait public<commit_after>use std::num;

pub trait Addressable<ADDR: Int, DATA: Int> {
	pub fn get (&self, addr: ADDR) -> DATA;
	pub fn set (&mut self, addr: ADDR, data: DATA);
}

// FIXME: With default methods, we won't need this anymore
pub trait AddressableUtil<ADDR: Int, DATA: Int> {
	pub fn get_be<T: Int> (&self, addr: ADDR) -> T;
	pub fn get_le<T: Int> (&self, addr: ADDR) -> T;
	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T);
	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T);
}

impl<ADDR: Int, DATA: Int, A: Addressable<ADDR, DATA>> AddressableUtil<ADDR, DATA> for A {
	pub fn get_be<T: Int> (&self, addr: ADDR) -> T {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mut val = num::Zero::zero::<T>();
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast((count-i-1) * num::Primitive::bits::<DATA>());
			let d: T = num::cast(self.get(addr + num::cast(i)));
			val = val + (d << shift);
		}
		val
	}

	pub fn get_le<T: Int> (&self, addr: ADDR) -> T {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mut val = num::Zero::zero::<T>();
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast(i * num::Primitive::bits::<DATA>());
			let d: T = num::cast(self.get(addr + num::cast(i)));
			val = val + (d << shift);
		}
		val
	}

	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T) {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mask = (1 << num::Primitive::bits::<DATA>()) - 1;
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast((count-i-1) * num::Primitive::bits::<DATA>());
			let d: DATA = num::cast((val >> shift) & num::cast(mask));
			self.set(addr + num::cast(i), d);
		}
	}

	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T) {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mask = (1 << num::Primitive::bits::<DATA>()) - 1;
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast(i * num::Primitive::bits::<DATA>());
			let d: DATA = num::cast((val >> shift) & num::cast(mask));
			self.set(addr + num::cast(i), d);
		}
	}
}

#[cfg(test)]
mod tests {
	use super::*;

	struct DummyData;
	impl Addressable<u16, u8> for DummyData {
		pub fn get (&self, addr: u16) -> u8 {
			addr as u8
		}
		pub fn set (&mut self, addr: u16, data: u8) {
			assert_eq!(data, addr as u8);
		}
	}

	#[test]
	fn test_get () {
		let data = DummyData;
		assert_eq!(data.get(0x12), 0x12);
		assert_eq!(data.get(0x1234), 0x34);
	}

	#[test]
	fn test_get_big_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_be(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_be(0x0054_u16));
		assert_eq!(    0x0203_u16, data.get_be(0x0002_u16));
		assert_eq!(    0x5455_u16, data.get_be(0x0054_u16));
		assert_eq!(0x02030405_u32, data.get_be(0x0002_u16));
		assert_eq!(0x54555657_u32, data.get_be(0x0054_u16));
	}

	#[test]
	fn test_get_little_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_le(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_le(0x0054_u16));
		assert_eq!(    0x0302_u16, data.get_le(0x0002_u16));
		assert_eq!(    0x5554_u16, data.get_le(0x0054_u16));
		assert_eq!(0x05040302_u32, data.get_le(0x0002_u16));
		assert_eq!(0x57565554_u32, data.get_le(0x0054_u16));
	}

	#[test]
	fn test_set () {
		let mut data = DummyData;
		data.set(0x12, 0x12);
		data.set(0x1234, 0x34);
	}

	#[test]
	fn test_set_big_endian () {
		let mut data = DummyData;
		data.set_be(0x0002_u16, 0x02_u8);
		data.set_be(0x0054_u16, 0x54_u8);
		data.set_be(0x0002_u16, 0x0203_u16);
		data.set_be(0x0054_u16, 0x5455_u16);
		data.set_be(0x0002_u16, 0x02030405_u32);
		data.set_be(0x0054_u16, 0x54555657_u32);
	}

	#[test]
	fn test_set_little_endian () {
		let mut data = DummyData;
		data.set_le(0x0002_u16, 0x02_u8);
		data.set_le(0x0054_u16, 0x54_u8);
		data.set_le(0x0002_u16, 0x0302_u16);
		data.set_le(0x0054_u16, 0x5554_u16);
		data.set_le(0x0002_u16, 0x05040302_u32);
		data.set_le(0x0054_u16, 0x57565554_u32);
	}
}
<|endoftext|>


<commit_before>extern crate core;
extern crate libc;
extern crate minifb;
extern crate prodbg_api;
extern crate bgfx_rs;
extern crate imgui_sys;

use core::{DynamicReload, Search};
use minifb::{Window, Key, Scale, WindowOptions, MouseMode, MouseButton};
use libc::{c_void};
use prodbg_api::view::CViewCallbacks;
//use prodbg_api::ui::Ui;
use prodbg_api::ui_ffi::{PDVec2};
use core::view_plugins::{ViewPlugins};
use core::session::SessionHandle;
use std::rc::Rc;
use std::cell::RefCell;
use imgui_sys::Imgui;

// use core::plugin_handler::*;
use core::plugins::*;
use std::ptr;
use bgfx_rs::Bgfx;

const WIDTH: usize = 1024;
const HEIGHT: usize = 800;

fn is_inside(v: (f32, f32), pos: PDVec2, size: PDVec2) -> bool {
    let x0 = pos.x;
    let y0 = pos.y;
    let x1 = pos.x + size.x;
    let y1 = pos.y + size.y;

    if (v.0 >= x0 && v.0 < x1) && (v.1 >= y0 && v.1 < y1) {
        true
    } else {
        false
    }
}

fn main() {
    let bgfx = Bgfx::new();

    let mut window = Window::new("Noise Test - Press ESC to exit",
                                 WIDTH,
                                 HEIGHT,
                                 WindowOptions {
                                     resize: true,
                                     scale: Scale::X1,
                                     ..WindowOptions::default()
                                 })
                         .expect("Unable to create window");

    let mut lib_handler = DynamicReload::new(None, Some("t2-output"), Search::Backwards);
    let mut plugins = Plugins::new();

    // Would be nice to nat have it this way
    let view_plugins = Rc::new(RefCell::new(ViewPlugins::new()));

    plugins.add_handler(&view_plugins);
    plugins.add_plugin(&mut lib_handler, "registers_plugin");

    let ui = Imgui::create_ui_instance();

    view_plugins.borrow_mut().create_instance(ui, &"Registers View".to_owned(), SessionHandle(0));

    Bgfx::create_window(window.get_window_handle() as *mut c_void,
                           WIDTH as i32,
                           HEIGHT as i32);

    while window.is_open() && !window.is_key_down(Key::Escape) {
        plugins.update(&mut lib_handler);

        bgfx.pre_update();

        let mouse = window.get_mouse_pos(MouseMode::Clamp).unwrap_or((0.0, 0.0));
        let mut has_shown_menu = 0u32;

        Bgfx::set_mouse_pos(mouse);
        Bgfx::set_mouse_state(0, window.get_mouse_down(MouseButton::Left));

        let show_context_menu = window.get_mouse_down(MouseButton::Right);

        for instance in &view_plugins.borrow_mut().instances {
            let ui = instance.ui;

            //bgfx_imgui_set_window_pos(0.0, 0.0);
            //bgfx_imgui_set_window_size(500.0, 500.0);

            Imgui::begin_window("Test", true);
            Imgui::init_state(ui.api);

            let pos = ui.get_window_pos();
            let size = ui.get_window_size();

            if is_inside(mouse, pos, size) && show_context_menu {
                Imgui::mark_show_popup(ui.api, true);
            } else {
                Imgui::mark_show_popup(ui.api, false);
            }

            unsafe {
                let plugin_funcs = instance.plugin_type.plugin_funcs as *mut CViewCallbacks;
                ((*plugin_funcs).update.unwrap())(instance.plugin_data,
                                                    ui.api as *mut c_void,
                                                    ptr::null_mut(),
                                                    ptr::null_mut());
            }

            has_shown_menu |= Imgui::has_showed_popup(ui.api);

            Imgui::end_window();
        }

        // if now plugin has showed a menu we do it here

        if has_shown_menu == 0 && show_context_menu {
            Bgfx::test_menu(true);
        } else {
            Bgfx::test_menu(false);
        }

        bgfx.post_update();

        window.update();
    }

    //unsafe {
     //   bgfx_destroy();
    //}
}

// dummy
#[no_mangle]
pub fn init_plugin() {
}<commit_msg>Use dummy session<commit_after>extern crate core;
extern crate libc;
extern crate minifb;
extern crate prodbg_api;
extern crate bgfx_rs;
extern crate imgui_sys;

use core::{DynamicReload, Search};
use minifb::{Window, Key, Scale, WindowOptions, MouseMode, MouseButton};
use libc::{c_void};
use prodbg_api::view::CViewCallbacks;
//use prodbg_api::ui::Ui;
use prodbg_api::ui_ffi::{PDVec2};
use core::view_plugins::{ViewPlugins};
use core::session::{Sessions, SessionHandle};
use std::rc::Rc;
use std::cell::RefCell;
use imgui_sys::Imgui;

// use core::plugin_handler::*;
use core::plugins::*;
//use std::ptr;
use bgfx_rs::Bgfx;

const WIDTH: usize = 1024;
const HEIGHT: usize = 800;

fn is_inside(v: (f32, f32), pos: PDVec2, size: PDVec2) -> bool {
    let x0 = pos.x;
    let y0 = pos.y;
    let x1 = pos.x + size.x;
    let y1 = pos.y + size.y;

    if (v.0 >= x0 && v.0 < x1) && (v.1 >= y0 && v.1 < y1) {
        true
    } else {
        false
    }
}

fn main() {
    let bgfx = Bgfx::new();

    let mut window = Window::new("Noise Test - Press ESC to exit",
                                 WIDTH,
                                 HEIGHT,
                                 WindowOptions {
                                     resize: true,
                                     scale: Scale::X1,
                                     ..WindowOptions::default()
                                 })
                         .expect("Unable to create window");

    let mut sessions = Sessions::new();
    let mut lib_handler = DynamicReload::new(None, Some("t2-output"), Search::Backwards);
    let mut plugins = Plugins::new();

    // Would be nice to nat have it this way
    let view_plugins = Rc::new(RefCell::new(ViewPlugins::new()));
    sessions.create_instance();

    plugins.add_handler(&view_plugins);
    plugins.add_plugin(&mut lib_handler, "sourcecode_plugin");

    let ui = Imgui::create_ui_instance();

    view_plugins.borrow_mut().create_instance(ui, &"Source Code View".to_owned(), SessionHandle(0));

    Bgfx::create_window(window.get_window_handle() as *mut c_void,
                           WIDTH as i32,
                           HEIGHT as i32);

    while window.is_open() && !window.is_key_down(Key::Escape) {
        plugins.update(&mut lib_handler);

        bgfx.pre_update();

        let mouse = window.get_mouse_pos(MouseMode::Clamp).unwrap_or((0.0, 0.0));
        let mut has_shown_menu = 0u32;

        Bgfx::set_mouse_pos(mouse);
        Bgfx::set_mouse_state(0, window.get_mouse_down(MouseButton::Left));

        let show_context_menu = window.get_mouse_down(MouseButton::Right);

        for instance in &view_plugins.borrow_mut().instances {
            let ui = instance.ui;

            //bgfx_imgui_set_window_pos(0.0, 0.0);
            //bgfx_imgui_set_window_size(500.0, 500.0);

            Imgui::begin_window("Test", true);
            Imgui::init_state(ui.api);

            let pos = ui.get_window_pos();
            let size = ui.get_window_size();

            if is_inside(mouse, pos, size) && show_context_menu {
                Imgui::mark_show_popup(ui.api, true);
            } else {
                Imgui::mark_show_popup(ui.api, false);
            }

            unsafe {
                let plugin_funcs = instance.plugin_type.plugin_funcs as *mut CViewCallbacks;
                let session = sessions.get_session(SessionHandle(0)).unwrap();
                ((*plugin_funcs).update.unwrap())(instance.plugin_data,
                                                    ui.api as *mut c_void,
                                                    session.reader.api as *mut c_void,
                                                    session.get_current_writer().api as *mut c_void);
            }

            has_shown_menu |= Imgui::has_showed_popup(ui.api);

            Imgui::end_window();
        }

        // if now plugin has showed a menu we do it here

        if has_shown_menu == 0 && show_context_menu {
            Bgfx::test_menu(true);
        } else {
            Bgfx::test_menu(false);
        }

        bgfx.post_update();
        sessions.update();

        window.update();
    }

    //unsafe {
     //   bgfx_destroy();
    //}
}

// dummy
#[no_mangle]
pub fn init_plugin() {
}
<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// pretty-expanded FIXME #23616

/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

#![allow(warnings)]
#![feature(box_syntax, box_heap)]
#![feature(placement_in_syntax)]

// Tests that the new `box` syntax works with unique pointers.

use std::boxed::{Box, HEAP};

struct Structure {
    x: isize,
    y: isize,
}

pub fn main() {
    let x: Box<isize> = box(HEAP) 2;
    let y: Box<isize> = box 2;
    let b: Box<isize> = box()(1 + 2);
    let c = box()(3 + 4);
}
<commit_msg>Add actual use of the `struct Structure` lying dormant in `new-box-syntax.rs`.<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// pretty-expanded FIXME #23616

/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

#![allow(warnings)]
#![feature(box_syntax, box_heap)]
#![feature(placement_in_syntax)]

// Tests that the new `box` syntax works with unique pointers.

use std::boxed::{Box, HEAP};

struct Structure {
    x: isize,
    y: isize,
}

pub fn main() {
    let x: Box<isize> = box(HEAP) 2;
    let y: Box<isize> = box 2;
    let b: Box<isize> = box()(1 + 2);
    let c = box()(3 + 4);

    let s: Box<Structure> = box Structure {
        x: 3,
        y: 4,
    };
}
<|endoftext|>


<commit_before>#![feature(proc_macro_span)]

extern crate peg_codegen;
extern crate proc_macro;

use std::iter;

use proc_macro::{ TokenStream, TokenTree, Span };

#[proc_macro]
pub fn peg(input: TokenStream) -> TokenStream {
    let (name, source, span) = parse_peg_args(input);

    let line = span.start().line;
    let fname = span.source_file().path().display().to_string();

    // Make PEG line numbers match source line numbers
    let source = iter::repeat('\n').take(line - 1).collect::<String>() + &source;

    expand_peg(name, fname, source)
}

/// Parse a TokenStream of the form `name r#""#`
fn parse_peg_args(input: TokenStream) -> (String, String, Span) {
    let mut iter = input.into_iter();
    let name = match iter.next() {
        Some(TokenTree::Ident(i)) => i.to_string(),
        Some(other) => panic!("Expected grammar name, found {}", other),
        None => panic!("Unexpected end of macro input")
    };
    let (body_literal, span) = match iter.next() {
        Some(TokenTree::Literal(l)) => (l.to_string(), l.span()),
        Some(other) => panic!("Expected raw string literal, found {}", other),
        None => panic!("Unexpected end of macro input")
    };
    if !body_literal.starts_with("r#\"") || !body_literal.ends_with("\"#") {
        panic!("Expected raw string literal (`r#\"...\"#`)");
    }
    let body_string = body_literal[3..body_literal.len()-2].to_string();
    match iter.next() {
        None => {}
        Some(_) => panic!("Unexpected trailing tokens in macro")
    }
    (name, body_string, span)
}

fn expand_peg(name: String, filename: String, source: String) -> TokenStream {
    let code = match peg_codegen::compile(filename, source) {
        Ok(code) => code,
        Err(()) => panic!("Errors above in rust-peg grammar"),
    };

    format!("mod {} {{ {} }}", name, code).parse().unwrap()
}
<commit_msg>Drop dependency on #![feature(proc_macro_span)]<commit_after>extern crate peg_codegen;
extern crate proc_macro;

use proc_macro::{ TokenStream, TokenTree, Span };

#[proc_macro]
pub fn peg(input: TokenStream) -> TokenStream {
    let (name, source, _) = parse_peg_args(input);

    expand_peg(name, "<peg>".into(), source)
}

/// Parse a TokenStream of the form `name r#""#`
fn parse_peg_args(input: TokenStream) -> (String, String, Span) {
    let mut iter = input.into_iter();
    let name = match iter.next() {
        Some(TokenTree::Ident(i)) => i.to_string(),
        Some(other) => panic!("Expected grammar name, found {}", other),
        None => panic!("Unexpected end of macro input")
    };
    let (body_literal, span) = match iter.next() {
        Some(TokenTree::Literal(l)) => (l.to_string(), l.span()),
        Some(other) => panic!("Expected raw string literal, found {}", other),
        None => panic!("Unexpected end of macro input")
    };
    if !body_literal.starts_with("r#\"") || !body_literal.ends_with("\"#") {
        panic!("Expected raw string literal (`r#\"...\"#`)");
    }
    let body_string = body_literal[3..body_literal.len()-2].to_string();
    match iter.next() {
        None => {}
        Some(_) => panic!("Unexpected trailing tokens in macro")
    }
    (name, body_string, span)
}

fn expand_peg(name: String, filename: String, source: String) -> TokenStream {
    let code = match peg_codegen::compile(filename, source) {
        Ok(code) => code,
        Err(()) => panic!("Errors above in rust-peg grammar"),
    };

    format!("mod {} {{ {} }}", name, code).parse().unwrap()
}
<|endoftext|>


<commit_before>use std::mem;
use std::ops;
use std::sync::{Condvar, Mutex, MutexGuard, PoisonError};

pub struct MutexSet<V> {
    vals: Mutex<Vec<V>>,
    cond: Condvar,
}

pub struct MutexSetGuard<'mutex, V: 'mutex> {
    m: &'mutex MutexSet<V>,
    v: Option<V>,
}

impl<'mutex, V> ops::Deref for MutexSetGuard<'mutex, V> {
    type Target = V;
    fn deref(&self) -> &V {
        self.v.as_ref().unwrap()
    }
}

impl<'mutex, V> ops::DerefMut for MutexSetGuard<'mutex, V> {
    fn deref_mut(&mut self) -> &mut V {
        self.v.as_mut().unwrap()
    }
}

impl<'mutex, V> ops::Drop for MutexSetGuard<'mutex, V> {
    fn drop(&mut self) {
        let mut vals = self.m.vals.lock().unwrap();
        let v = mem::replace(&mut self.v, None);
        vals.push(v.unwrap());
        self.m.cond.notify_one();
    }
}

impl<V> MutexSet<V> {
    pub fn new(vals: Vec<V>) -> MutexSet<V> {
        MutexSet {
            vals: Mutex::new(vals),
            cond: Condvar::new(),
        }
    }

    pub fn len(&self) -> usize {
        self.vals.lock().unwrap().len()
    }

    pub fn with<F, R>(&self, f: F) -> R
        where F: FnOnce(&mut V) -> R
    {
        let mut v = self.lock().unwrap();
        let r = f(&mut *v);
        r
    }

    pub fn lock(&self) -> Result<MutexSetGuard<V>, PoisonError<MutexGuard<Vec<V>>>> {
        let v = {
            let mut vs = try!(self.vals.lock());
            while vs.len() == 0 {
                vs = try!(self.cond.wait(vs));
            }
            vs.pop().unwrap()
        };
        Ok(MutexSetGuard {
            m: &self,
            v: Some(v),
        })
    }
}
<commit_msg>Cleanup unused methods.<commit_after>use std::mem;
use std::ops;
use std::sync::{Condvar, Mutex, MutexGuard, PoisonError};

pub struct MutexSet<V> {
    vals: Mutex<Vec<V>>,
    cond: Condvar,
}

pub struct MutexSetGuard<'mutex, V: 'mutex> {
    m: &'mutex MutexSet<V>,
    v: Option<V>,
}

impl<'mutex, V> ops::Deref for MutexSetGuard<'mutex, V> {
    type Target = V;
    fn deref(&self) -> &V {
        self.v.as_ref().unwrap()
    }
}

impl<'mutex, V> ops::DerefMut for MutexSetGuard<'mutex, V> {
    fn deref_mut(&mut self) -> &mut V {
        self.v.as_mut().unwrap()
    }
}

impl<'mutex, V> ops::Drop for MutexSetGuard<'mutex, V> {
    fn drop(&mut self) {
        let mut vals = self.m.vals.lock().unwrap();
        let v = mem::replace(&mut self.v, None);
        vals.push(v.unwrap());
        self.m.cond.notify_one();
    }
}

impl<V> MutexSet<V> {
    pub fn new(vals: Vec<V>) -> MutexSet<V> {
        MutexSet {
            vals: Mutex::new(vals),
            cond: Condvar::new(),
        }
    }

    pub fn lock(&self) -> Result<MutexSetGuard<V>, PoisonError<MutexGuard<Vec<V>>>> {
        let v = {
            let mut vs = try!(self.vals.lock());
            while vs.len() == 0 {
                vs = try!(self.cond.wait(vs));
            }
            vs.pop().unwrap()
        };
        Ok(MutexSetGuard {
            m: &self,
            v: Some(v),
        })
    }
}
<|endoftext|>


<commit_before>use std::io;

use protobuf;
use serde;

use serde_protobuf;
use serde_protobuf::descriptor;

use error;
use value;

pub struct ProtobufSource<'a>(serde_protobuf::de::Deserializer<'a>);

#[inline]
pub fn source<'a>(descriptors: &'a descriptor::Descriptors,
                  message_name: &str,
                  input: &'a mut protobuf::CodedInputStream<'a>)
                  -> error::Result<ProtobufSource<'a>> {
    let de = try!(serde_protobuf::de::Deserializer::for_named_message(descriptors,
                                                                      message_name,
                                                                      input));
    Ok(ProtobufSource(de))
}

impl<'a> value::Source for ProtobufSource<'a> {
    #[inline]
    fn read(&mut self) -> error::Result<Option<value::Value>> {
        match serde::Deserialize::deserialize(&mut self.0) {
            Ok(v) => Ok(Some(v)),
            Err(serde_protobuf::error::Error::EndOfStream) => Ok(None),
            Err(e) => Err(error::Error::from(e)),
        }
    }
}
<commit_msg>Make protobuf source only produce one value<commit_after>use protobuf;
use serde;

use serde_protobuf;
use serde_protobuf::descriptor;

use error;
use value;

pub struct ProtobufSource<'a>(serde_protobuf::de::Deserializer<'a>, bool);

#[inline]
pub fn source<'a>(descriptors: &'a descriptor::Descriptors,
                  message_name: &str,
                  input: &'a mut protobuf::CodedInputStream<'a>)
                  -> error::Result<ProtobufSource<'a>> {
    let de = try!(serde_protobuf::de::Deserializer::for_named_message(descriptors,
                                                                      message_name,
                                                                      input));
    Ok(ProtobufSource(de, true))
}

impl<'a> value::Source for ProtobufSource<'a> {
    #[inline]
    fn read(&mut self) -> error::Result<Option<value::Value>> {
        if self.1 {
            self.1 = false;
            match serde::Deserialize::deserialize(&mut self.0) {
                Ok(v) => Ok(Some(v)),
                Err(serde_protobuf::error::Error::EndOfStream) => Ok(None),
                Err(e) => Err(error::Error::from(e)),
            }
        } else {
            Ok(None)
        }
    }
}
<|endoftext|>


<commit_before>

use visit::IntoNeighbors;
use visit::{VisitMap, Visitable};

/// Strictly monotonically increasing event time for a depth first search.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Default)]
pub struct Time(pub usize);

/// A depth first search (DFS) visitor event.
#[derive(Copy, Clone, Debug)]
pub enum DfsEvent<N> {
    Discover(N, Time),
    /// An edge of the tree formed by the traversal.
    TreeEdge(N, N),
    /// An edge to an already visited node.
    BackEdge(N, N),
    /// A cross or forward edge.
    ///
    /// For an edge *(u, v)*, if the discover time of *v* is greater than *u*,
    /// then it is a forward edge, else a cross edge.
    CrossForwardEdge(N, N),
    Finish(N, Time),
}

macro_rules! control {
    ($e:expr) => {
        match $e {
            x => if x.should_break() {
                return x;
            } else {
            }
        }
    }
}

/// Control flow for visitor callbacks.
#[derive(Copy, Clone, Debug)]
pub enum Control<B> {
    Continue,
    Break(B),
}

impl<B> Control<B> {
    /// Get the value in `Control::Break(_)`, if present.
    pub fn break_value(self) -> Option<B> {
        match self {
            Control::Continue => None,
            Control::Break(b) => Some(b),
        }
    }
}

/// The default is `Continue`.
impl<B> Default for Control<B> {
    fn default() -> Self { Control::Continue }
}

/// Control flow for visitor callbacks.
///
/// The empty return value `()` will continue until the visit is done.
pub trait ControlFlow : Default {
    #[inline]
    fn should_break(&self) -> bool { false }
}

impl ControlFlow for () { }

impl<B> ControlFlow for Control<B> {
    fn should_break(&self) -> bool {
        if let Control::Break(_) = *self { true } else { false }
    }
}

/// A recursive depth first search.
///
/// Starting points are the nodes in the iterator `starts` (specify just one
/// start vertex *x* by using `Some(x)`).
///
/// The traversal emits discovery and finish events for each reachable vertex,
/// and edge classification of each reachable edge. `visitor` is called for each
/// event, see [`DfsEvent`][de] for possible values.
///
/// If the return value of the visitor is simply `()`, the visit runs until it
/// is finished. If the return value is a `Control<B>`, it can be used to
/// break the visit early, and the last control value is returned by the
/// function.
///
/// [de]: enum.DfsEvent.html
///
/// # Example
///
/// Find a path from vertex 0 to 5, and exit the visit as soon as we reach
/// the goal vertex.
///
/// ```
/// use petgraph::prelude::*;
/// use petgraph::graph::node_index as n;
/// use petgraph::visit::depth_first_search;
/// use petgraph::visit::{DfsEvent, Control};
///
/// let gr: Graph<(), ()> = Graph::from_edges(&[
///     (0, 1), (0, 2), (0, 3),
///     (1, 3),
///     (2, 3), (2, 4),
///     (4, 0), (4, 5),
/// ]);
///
/// // record each predecessor, mapping node → node
/// let mut predecessor = vec![NodeIndex::end(); gr.node_count()];
/// let start = n(0);
/// let goal = n(5);
/// depth_first_search(&gr, Some(start), |event| {
///     if let DfsEvent::TreeEdge(u, v) = event {
///         predecessor[v.index()] = u;
///         if v == goal {
///             return Control::Break(v);
///         }
///     }
///     Control::Continue
/// });
///
/// let mut next = goal;
/// let mut path = vec![next];
/// while next != start {
///     let pred = predecessor[next.index()];
///     path.push(pred);
///     next = pred;
/// }
/// path.reverse();
/// assert_eq!(&path, &[n(0), n(2), n(4), n(5)]);
/// ```
pub fn depth_first_search<G, I, F, C>(graph: G, starts: I, mut visitor: F) -> C
    where G: IntoNeighbors + Visitable,
          I: IntoIterator<Item=G::NodeId>,
          F: FnMut(DfsEvent<G::NodeId>) -> C,
          C: ControlFlow,
{
    let time = &mut Time(0);
    let discovered = &mut graph.visit_map();
    let finished = &mut graph.visit_map();

    for start in starts {
        control!(dfs_visitor(graph, start, &mut visitor, discovered, finished, time));
    }
    C::default()
}

fn dfs_visitor<G, F, C>(graph: G, u: G::NodeId, visitor: &mut F,
                     discovered: &mut G::Map, finished: &mut G::Map,
                     time: &mut Time) -> C
    where G: IntoNeighbors + Visitable,
          F: FnMut(DfsEvent<G::NodeId>) -> C,
          C: ControlFlow,
{
    if !discovered.visit(u) {
        return C::default();
    }
    control!(visitor(DfsEvent::Discover(u, time_post_inc(time))));
    for v in graph.neighbors(u) {
        if !discovered.is_visited(&v) {
            control!(visitor(DfsEvent::TreeEdge(u, v)));
            control!(dfs_visitor(graph, v, visitor, discovered, finished, time));
        } else if !finished.is_visited(&v) {
            control!(visitor(DfsEvent::BackEdge(u, v)));
        } else {
            control!(visitor(DfsEvent::CrossForwardEdge(u, v)));
        }
    }
    let first_finish = finished.visit(u);
    debug_assert!(first_finish);
    control!(visitor(DfsEvent::Finish(u, time_post_inc(time))));
    C::default()
}

fn time_post_inc(x: &mut Time) -> Time {
    let v = *x;
    x.0 += 1;
    v
}
<commit_msg>Upgrade ControlFlow to the better version used in permutohedron<commit_after>

use visit::IntoNeighbors;
use visit::{VisitMap, Visitable};

/// Strictly monotonically increasing event time for a depth first search.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Default)]
pub struct Time(pub usize);

/// A depth first search (DFS) visitor event.
#[derive(Copy, Clone, Debug)]
pub enum DfsEvent<N> {
    Discover(N, Time),
    /// An edge of the tree formed by the traversal.
    TreeEdge(N, N),
    /// An edge to an already visited node.
    BackEdge(N, N),
    /// A cross or forward edge.
    ///
    /// For an edge *(u, v)*, if the discover time of *v* is greater than *u*,
    /// then it is a forward edge, else a cross edge.
    CrossForwardEdge(N, N),
    Finish(N, Time),
}

/// Return if the expression is a break value.
macro_rules! try_control {
    ($e:expr) => {
        match $e {
            x => if x.should_break() {
                return x;
            }
        }
    }
}

/// Control flow for callbacks.
///
/// `Break` can carry a value.
#[derive(Copy, Clone, Debug)]
pub enum Control<B> {
    Continue,
    Break(B),
}

impl<B> Control<B> {
    pub fn breaking() -> Control<()> { Control::Break(()) }
    /// Get the value in `Control::Break(_)`, if present.
    pub fn break_value(self) -> Option<B> {
        match self {
            Control::Continue => None,
            Control::Break(b) => Some(b),
        }
    }
}

/// Control flow for callbacks.
///
/// The empty return value `()` is equivalent to continue.
pub trait ControlFlow {
    fn continuing() -> Self;
    #[inline]
    fn should_break(&self) -> bool { false }
}

impl ControlFlow for () {
    fn continuing() { }
}

impl<B> ControlFlow for Control<B> {
    fn continuing() -> Self { Control::Continue }
    fn should_break(&self) -> bool {
        if let Control::Break(_) = *self { true } else { false }
    }
}

impl<E> ControlFlow for Result<(), E> {
    fn continuing() -> Self { Ok(()) }
    fn should_break(&self) -> bool {
        if let Err(_) = *self { true } else { false }
    }
}

/// The default is `Continue`.
impl<B> Default for Control<B> {
    fn default() -> Self { Control::Continue }
}

/// A recursive depth first search.
///
/// Starting points are the nodes in the iterator `starts` (specify just one
/// start vertex *x* by using `Some(x)`).
///
/// The traversal emits discovery and finish events for each reachable vertex,
/// and edge classification of each reachable edge. `visitor` is called for each
/// event, see [`DfsEvent`][de] for possible values.
///
/// If the return value of the visitor is simply `()`, the visit runs until it
/// is finished. If the return value is a `Control<B>`, it can be used to
/// break the visit early, and the last control value is returned by the
/// function.
///
/// [de]: enum.DfsEvent.html
///
/// # Example
///
/// Find a path from vertex 0 to 5, and exit the visit as soon as we reach
/// the goal vertex.
///
/// ```
/// use petgraph::prelude::*;
/// use petgraph::graph::node_index as n;
/// use petgraph::visit::depth_first_search;
/// use petgraph::visit::{DfsEvent, Control};
///
/// let gr: Graph<(), ()> = Graph::from_edges(&[
///     (0, 1), (0, 2), (0, 3),
///     (1, 3),
///     (2, 3), (2, 4),
///     (4, 0), (4, 5),
/// ]);
///
/// // record each predecessor, mapping node → node
/// let mut predecessor = vec![NodeIndex::end(); gr.node_count()];
/// let start = n(0);
/// let goal = n(5);
/// depth_first_search(&gr, Some(start), |event| {
///     if let DfsEvent::TreeEdge(u, v) = event {
///         predecessor[v.index()] = u;
///         if v == goal {
///             return Control::Break(v);
///         }
///     }
///     Control::Continue
/// });
///
/// let mut next = goal;
/// let mut path = vec![next];
/// while next != start {
///     let pred = predecessor[next.index()];
///     path.push(pred);
///     next = pred;
/// }
/// path.reverse();
/// assert_eq!(&path, &[n(0), n(2), n(4), n(5)]);
/// ```
pub fn depth_first_search<G, I, F, C>(graph: G, starts: I, mut visitor: F) -> C
    where G: IntoNeighbors + Visitable,
          I: IntoIterator<Item=G::NodeId>,
          F: FnMut(DfsEvent<G::NodeId>) -> C,
          C: ControlFlow,
{
    let time = &mut Time(0);
    let discovered = &mut graph.visit_map();
    let finished = &mut graph.visit_map();

    for start in starts {
        try_control!(dfs_visitor(graph, start, &mut visitor, discovered, finished, time));
    }
    C::continuing()
}

fn dfs_visitor<G, F, C>(graph: G, u: G::NodeId, visitor: &mut F,
                     discovered: &mut G::Map, finished: &mut G::Map,
                     time: &mut Time) -> C
    where G: IntoNeighbors + Visitable,
          F: FnMut(DfsEvent<G::NodeId>) -> C,
          C: ControlFlow,
{
    if !discovered.visit(u) {
        return C::continuing();
    }
    try_control!(visitor(DfsEvent::Discover(u, time_post_inc(time))));
    for v in graph.neighbors(u) {
        if !discovered.is_visited(&v) {
            try_control!(visitor(DfsEvent::TreeEdge(u, v)));
            try_control!(dfs_visitor(graph, v, visitor, discovered, finished, time));
        } else if !finished.is_visited(&v) {
            try_control!(visitor(DfsEvent::BackEdge(u, v)));
        } else {
            try_control!(visitor(DfsEvent::CrossForwardEdge(u, v)));
        }
    }
    let first_finish = finished.visit(u);
    debug_assert!(first_finish);
    try_control!(visitor(DfsEvent::Finish(u, time_post_inc(time))));
    C::continuing()
}

fn time_post_inc(x: &mut Time) -> Time {
    let v = *x;
    x.0 += 1;
    v
}
<|endoftext|>