<commit_before>// Copyright 2016 Amanieu d'Antras
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://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.

use std::cell::UnsafeCell;
use std::ops::Deref;
use std::time::{Duration, Instant};
use std::fmt;
use std::mem;
use std::marker::PhantomData;
use raw_remutex::RawReentrantMutex;

#[cfg(feature = "owning_ref")]
use owning_ref::StableAddress;

/// A mutex which can be recursively locked by a single thread.
///
/// This type is identical to `Mutex` except for the following points:
///
/// - Locking multiple times from the same thread will work correctly instead of
///   deadlocking.
/// - `ReentrantMutexGuard` does not give mutable references to the locked data.
///   Use a `RefCell` if you need this.
/// - `ReentrantMutexGuard` is not `Send`.
///
/// See [`Mutex`](struct.Mutex.html) for more details about the underlying mutex
/// primitive.
pub struct ReentrantMutex<T: ?Sized> {
    raw: RawReentrantMutex,
    data: UnsafeCell<T>,
}

unsafe impl<T: Send> Send for ReentrantMutex<T> {}
unsafe impl<T: Send> Sync for ReentrantMutex<T> {}

/// An RAII implementation of a "scoped lock" of a reentrant mutex. When this structure
/// is dropped (falls out of scope), the lock will be unlocked.
///
/// The data protected by the mutex can be accessed through this guard via its
/// `Deref` implementation.
#[must_use]
pub struct ReentrantMutexGuard<'a, T: ?Sized + 'a> {
    raw: &'a RawReentrantMutex,
    data: *const T,
    marker: PhantomData<&'a T>,
}

unsafe impl<'a, T: ?Sized + Sync + 'a> Sync for ReentrantMutexGuard<'a, T> {}

impl<T> ReentrantMutex<T> {
    /// Creates a new reentrant mutex in an unlocked state ready for use.
    #[cfg(feature = "nightly")]
    #[inline]
    pub const fn new(val: T) -> ReentrantMutex<T> {
        ReentrantMutex {
            data: UnsafeCell::new(val),
            raw: RawReentrantMutex::new(),
        }
    }

    /// Creates a new reentrant mutex in an unlocked state ready for use.
    #[cfg(not(feature = "nightly"))]
    #[inline]
    pub fn new(val: T) -> ReentrantMutex<T> {
        ReentrantMutex {
            data: UnsafeCell::new(val),
            raw: RawReentrantMutex::new(),
        }
    }

    /// Consumes this reentrant mutex, returning the underlying data.
    #[inline]
    pub fn into_inner(self) -> T {
        unsafe { self.data.into_inner() }
    }
}

impl<T: ?Sized> ReentrantMutex<T> {
    #[inline]
    fn guard(&self) -> ReentrantMutexGuard<T> {
        ReentrantMutexGuard {
            raw: &self.raw,
            data: self.data.get(),
            marker: PhantomData,
        }
    }

    /// Acquires a reentrant mutex, blocking the current thread until it is able
    /// to do so.
    ///
    /// If the mutex is held by another thread then this function will block the
    /// local thread until it is available to acquire the mutex. If the mutex is
    /// already held by the current thread then this function will increment the
    /// lock reference count and return immediately. Upon returning,
    /// the thread is the only thread with the mutex held. An RAII guard is
    /// returned to allow scoped unlock of the lock. When the guard goes out of
    /// scope, the mutex will be unlocked.
    #[inline]
    pub fn lock(&self) -> ReentrantMutexGuard<T> {
        self.raw.lock();
        self.guard()
    }

    /// Attempts to acquire this lock.
    ///
    /// If the lock could not be acquired at this time, then `None` is returned.
    /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
    /// guard is dropped.
    ///
    /// This function does not block.
    #[inline]
    pub fn try_lock(&self) -> Option<ReentrantMutexGuard<T>> {
        if self.raw.try_lock() {
            Some(self.guard())
        } else {
            None
        }
    }

    /// Attempts to acquire this lock until a timeout is reached.
    ///
    /// If the lock could not be acquired before the timeout expired, then
    /// `None` is returned. Otherwise, an RAII guard is returned. The lock will
    /// be unlocked when the guard is dropped.
    #[inline]
    pub fn try_lock_for(&self, timeout: Duration) -> Option<ReentrantMutexGuard<T>> {
        if self.raw.try_lock_for(timeout) {
            Some(self.guard())
        } else {
            None
        }
    }

    /// Attempts to acquire this lock until a timeout is reached.
    ///
    /// If the lock could not be acquired before the timeout expired, then
    /// `None` is returned. Otherwise, an RAII guard is returned. The lock will
    /// be unlocked when the guard is dropped.
    #[inline]
    pub fn try_lock_until(&self, timeout: Instant) -> Option<ReentrantMutexGuard<T>> {
        if self.raw.try_lock_until(timeout) {
            Some(self.guard())
        } else {
            None
        }
    }

    /// Returns a mutable reference to the underlying data.
    ///
    /// Since this call borrows the `ReentrantMutex` mutably, no actual locking needs to
    /// take place---the mutable borrow statically guarantees no locks exist.
    #[inline]
    pub fn get_mut(&mut self) -> &mut T {
        unsafe { &mut *self.data.get() }
    }

    /// Releases the mutex.
    ///
    /// # Safety
    ///
    /// This function must only be called if the mutex was locked using
    /// `raw_lock` or `raw_try_lock`, or if a `ReentrantMutexGuard` from this mutex was
    /// leaked (e.g. with `mem::forget`). The mutex must be locked.
    #[inline]
    pub unsafe fn raw_unlock(&self) {
        self.raw.unlock(false);
    }

    /// Releases the mutex using a fair unlock protocol.
    ///
    /// See `ReentrantMutexGuard::unlock_fair`.
    ///
    /// # Safety
    ///
    /// This function must only be called if the mutex was locked using
    /// `raw_lock` or `raw_try_lock`, or if a `ReentrantMutexGuard` from this mutex was
    /// leaked (e.g. with `mem::forget`). The mutex must be locked.
    #[inline]
    pub unsafe fn raw_unlock_fair(&self) {
        self.raw.unlock(true);
    }
}
impl ReentrantMutex<()> {
    /// Acquires a mutex, blocking the current thread until it is able to do so.
    ///
    /// This is similar to `lock`, except that a `ReentrantMutexGuard` is not returned.
    /// Instead you will need to call `raw_unlock` to release the mutex.
    #[inline]
    pub fn raw_lock(&self) {
        self.raw.lock();
    }

    /// Attempts to acquire this lock.
    ///
    /// This is similar to `try_lock`, except that a `ReentrantMutexGuard` is not
    /// returned. Instead you will need to call `raw_unlock` to release the
    /// mutex.
    #[inline]
    pub fn raw_try_lock(&self) -> bool {
        self.raw.try_lock()
    }
}

impl<T: ?Sized + Default> Default for ReentrantMutex<T> {
    #[inline]
    fn default() -> ReentrantMutex<T> {
        ReentrantMutex::new(Default::default())
    }
}

impl<T: ?Sized + fmt::Debug> fmt::Debug for ReentrantMutex<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.try_lock() {
            Some(guard) => write!(f, "ReentrantMutex {{ data: {:?} }}", &*guard),
            None => write!(f, "ReentrantMutex {{ <locked> }}"),
        }
    }
}

impl<'a, T: ?Sized + 'a> ReentrantMutexGuard<'a, T> {
    /// Unlocks the mutex using a fair unlock protocol.
    ///
    /// By default, mutexes are unfair and allow the current thread to re-lock
    /// the mutex before another has the chance to acquire the lock, even if
    /// that thread has been blocked on the mutex for a long time. This is the
    /// default because it allows much higher throughput as it avoids forcing a
    /// context switch on every mutex unlock. This can result in one thread
    /// acquiring a mutex many more times than other threads.
    ///
    /// However in some cases it can be beneficial to ensure fairness by forcing
    /// the lock to pass on to a waiting thread if there is one. This is done by
    /// using this method instead of dropping the `ReentrantMutexGuard` normally.
    #[inline]
    pub fn unlock_fair(self) {
        self.raw.unlock(true);
        mem::forget(self);
    }

    /// Make a new `ReentrantMutexGuard` for a component of the locked data.
    ///
    /// This operation cannot fail as the `ReentrantMutexGuard` passed
    /// in already locked the mutex.
    ///
    /// This is an associated function that needs to be
    /// used as `ReentrantMutexGuard::map(...)`. A method would interfere with
    /// methods of the same name on the contents of the locked data.
    #[inline]
    pub fn map<U: ?Sized, F>(orig: Self, f: F) -> ReentrantMutexGuard<'a, U>
    where
        F: FnOnce(&T) -> &U,
    {
        let raw = orig.raw;
        let data = f(unsafe { &*orig.data });
        mem::forget(orig);
        ReentrantMutexGuard {
            raw,
            data,
            marker: PhantomData,
        }
    }
}

impl<'a, T: ?Sized + 'a> Deref for ReentrantMutexGuard<'a, T> {
    type Target = T;
    #[inline]
    fn deref(&self) -> &T {
        unsafe { &*self.data }
    }
}

impl<'a, T: ?Sized + 'a> Drop for ReentrantMutexGuard<'a, T> {
    #[inline]
    fn drop(&mut self) {
        self.raw.unlock(false);
    }
}

#[cfg(feature = "owning_ref")]
unsafe impl<'a, T: ?Sized> StableAddress for ReentrantMutexGuard<'a, T> {}

#[cfg(test)]
mod tests {
    use std::cell::RefCell;
    use std::sync::Arc;
    use std::thread;
    use ReentrantMutex;

    #[test]
    fn smoke() {
        let m = ReentrantMutex::new(());
        {
            let a = m.lock();
            {
                let b = m.lock();
                {
                    let c = m.lock();
                    assert_eq!(*c, ());
                }
                assert_eq!(*b, ());
            }
            assert_eq!(*a, ());
        }
    }

    #[test]
    fn is_mutex() {
        let m = Arc::new(ReentrantMutex::new(RefCell::new(0)));
        let m2 = m.clone();
        let lock = m.lock();
        let child = thread::spawn(move || {
            let lock = m2.lock();
            assert_eq!(*lock.borrow(), 4950);
        });
        for i in 0..100 {
            let lock = m.lock();
            *lock.borrow_mut() += i;
        }
        drop(lock);
        child.join().unwrap();
    }

    #[test]
    fn trylock_works() {
        let m = Arc::new(ReentrantMutex::new(()));
        let m2 = m.clone();
        let _lock = m.try_lock();
        let _lock2 = m.try_lock();
        thread::spawn(move || {
            let lock = m2.try_lock();
            assert!(lock.is_none());
        }).join()
            .unwrap();
        let _lock3 = m.try_lock();
    }
}
<commit_msg>Add `?Sized` on `Send`- and `Sync`-impl for `ReentrantMutex`.<commit_after>// Copyright 2016 Amanieu d'Antras
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://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.

use std::cell::UnsafeCell;
use std::ops::Deref;
use std::time::{Duration, Instant};
use std::fmt;
use std::mem;
use std::marker::PhantomData;
use raw_remutex::RawReentrantMutex;

#[cfg(feature = "owning_ref")]
use owning_ref::StableAddress;

/// A mutex which can be recursively locked by a single thread.
///
/// This type is identical to `Mutex` except for the following points:
///
/// - Locking multiple times from the same thread will work correctly instead of
///   deadlocking.
/// - `ReentrantMutexGuard` does not give mutable references to the locked data.
///   Use a `RefCell` if you need this.
/// - `ReentrantMutexGuard` is not `Send`.
///
/// See [`Mutex`](struct.Mutex.html) for more details about the underlying mutex
/// primitive.
pub struct ReentrantMutex<T: ?Sized> {
    raw: RawReentrantMutex,
    data: UnsafeCell<T>,
}

unsafe impl<T: ?Sized + Send> Send for ReentrantMutex<T> {}
unsafe impl<T: ?Sized + Send> Sync for ReentrantMutex<T> {}

/// An RAII implementation of a "scoped lock" of a reentrant mutex. When this structure
/// is dropped (falls out of scope), the lock will be unlocked.
///
/// The data protected by the mutex can be accessed through this guard via its
/// `Deref` implementation.
#[must_use]
pub struct ReentrantMutexGuard<'a, T: ?Sized + 'a> {
    raw: &'a RawReentrantMutex,
    data: *const T,
    marker: PhantomData<&'a T>,
}

unsafe impl<'a, T: ?Sized + Sync + 'a> Sync for ReentrantMutexGuard<'a, T> {}

impl<T> ReentrantMutex<T> {
    /// Creates a new reentrant mutex in an unlocked state ready for use.
    #[cfg(feature = "nightly")]
    #[inline]
    pub const fn new(val: T) -> ReentrantMutex<T> {
        ReentrantMutex {
            data: UnsafeCell::new(val),
            raw: RawReentrantMutex::new(),
        }
    }

    /// Creates a new reentrant mutex in an unlocked state ready for use.
    #[cfg(not(feature = "nightly"))]
    #[inline]
    pub fn new(val: T) -> ReentrantMutex<T> {
        ReentrantMutex {
            data: UnsafeCell::new(val),
            raw: RawReentrantMutex::new(),
        }
    }

    /// Consumes this reentrant mutex, returning the underlying data.
    #[inline]
    pub fn into_inner(self) -> T {
        unsafe { self.data.into_inner() }
    }
}

impl<T: ?Sized> ReentrantMutex<T> {
    #[inline]
    fn guard(&self) -> ReentrantMutexGuard<T> {
        ReentrantMutexGuard {
            raw: &self.raw,
            data: self.data.get(),
            marker: PhantomData,
        }
    }

    /// Acquires a reentrant mutex, blocking the current thread until it is able
    /// to do so.
    ///
    /// If the mutex is held by another thread then this function will block the
    /// local thread until it is available to acquire the mutex. If the mutex is
    /// already held by the current thread then this function will increment the
    /// lock reference count and return immediately. Upon returning,
    /// the thread is the only thread with the mutex held. An RAII guard is
    /// returned to allow scoped unlock of the lock. When the guard goes out of
    /// scope, the mutex will be unlocked.
    #[inline]
    pub fn lock(&self) -> ReentrantMutexGuard<T> {
        self.raw.lock();
        self.guard()
    }

    /// Attempts to acquire this lock.
    ///
    /// If the lock could not be acquired at this time, then `None` is returned.
    /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
    /// guard is dropped.
    ///
    /// This function does not block.
    #[inline]
    pub fn try_lock(&self) -> Option<ReentrantMutexGuard<T>> {
        if self.raw.try_lock() {
            Some(self.guard())
        } else {
            None
        }
    }

    /// Attempts to acquire this lock until a timeout is reached.
    ///
    /// If the lock could not be acquired before the timeout expired, then
    /// `None` is returned. Otherwise, an RAII guard is returned. The lock will
    /// be unlocked when the guard is dropped.
    #[inline]
    pub fn try_lock_for(&self, timeout: Duration) -> Option<ReentrantMutexGuard<T>> {
        if self.raw.try_lock_for(timeout) {
            Some(self.guard())
        } else {
            None
        }
    }

    /// Attempts to acquire this lock until a timeout is reached.
    ///
    /// If the lock could not be acquired before the timeout expired, then
    /// `None` is returned. Otherwise, an RAII guard is returned. The lock will
    /// be unlocked when the guard is dropped.
    #[inline]
    pub fn try_lock_until(&self, timeout: Instant) -> Option<ReentrantMutexGuard<T>> {
        if self.raw.try_lock_until(timeout) {
            Some(self.guard())
        } else {
            None
        }
    }

    /// Returns a mutable reference to the underlying data.
    ///
    /// Since this call borrows the `ReentrantMutex` mutably, no actual locking needs to
    /// take place---the mutable borrow statically guarantees no locks exist.
    #[inline]
    pub fn get_mut(&mut self) -> &mut T {
        unsafe { &mut *self.data.get() }
    }

    /// Releases the mutex.
    ///
    /// # Safety
    ///
    /// This function must only be called if the mutex was locked using
    /// `raw_lock` or `raw_try_lock`, or if a `ReentrantMutexGuard` from this mutex was
    /// leaked (e.g. with `mem::forget`). The mutex must be locked.
    #[inline]
    pub unsafe fn raw_unlock(&self) {
        self.raw.unlock(false);
    }

    /// Releases the mutex using a fair unlock protocol.
    ///
    /// See `ReentrantMutexGuard::unlock_fair`.
    ///
    /// # Safety
    ///
    /// This function must only be called if the mutex was locked using
    /// `raw_lock` or `raw_try_lock`, or if a `ReentrantMutexGuard` from this mutex was
    /// leaked (e.g. with `mem::forget`). The mutex must be locked.
    #[inline]
    pub unsafe fn raw_unlock_fair(&self) {
        self.raw.unlock(true);
    }
}
impl ReentrantMutex<()> {
    /// Acquires a mutex, blocking the current thread until it is able to do so.
    ///
    /// This is similar to `lock`, except that a `ReentrantMutexGuard` is not returned.
    /// Instead you will need to call `raw_unlock` to release the mutex.
    #[inline]
    pub fn raw_lock(&self) {
        self.raw.lock();
    }

    /// Attempts to acquire this lock.
    ///
    /// This is similar to `try_lock`, except that a `ReentrantMutexGuard` is not
    /// returned. Instead you will need to call `raw_unlock` to release the
    /// mutex.
    #[inline]
    pub fn raw_try_lock(&self) -> bool {
        self.raw.try_lock()
    }
}

impl<T: ?Sized + Default> Default for ReentrantMutex<T> {
    #[inline]
    fn default() -> ReentrantMutex<T> {
        ReentrantMutex::new(Default::default())
    }
}

impl<T: ?Sized + fmt::Debug> fmt::Debug for ReentrantMutex<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.try_lock() {
            Some(guard) => write!(f, "ReentrantMutex {{ data: {:?} }}", &*guard),
            None => write!(f, "ReentrantMutex {{ <locked> }}"),
        }
    }
}

impl<'a, T: ?Sized + 'a> ReentrantMutexGuard<'a, T> {
    /// Unlocks the mutex using a fair unlock protocol.
    ///
    /// By default, mutexes are unfair and allow the current thread to re-lock
    /// the mutex before another has the chance to acquire the lock, even if
    /// that thread has been blocked on the mutex for a long time. This is the
    /// default because it allows much higher throughput as it avoids forcing a
    /// context switch on every mutex unlock. This can result in one thread
    /// acquiring a mutex many more times than other threads.
    ///
    /// However in some cases it can be beneficial to ensure fairness by forcing
    /// the lock to pass on to a waiting thread if there is one. This is done by
    /// using this method instead of dropping the `ReentrantMutexGuard` normally.
    #[inline]
    pub fn unlock_fair(self) {
        self.raw.unlock(true);
        mem::forget(self);
    }

    /// Make a new `ReentrantMutexGuard` for a component of the locked data.
    ///
    /// This operation cannot fail as the `ReentrantMutexGuard` passed
    /// in already locked the mutex.
    ///
    /// This is an associated function that needs to be
    /// used as `ReentrantMutexGuard::map(...)`. A method would interfere with
    /// methods of the same name on the contents of the locked data.
    #[inline]
    pub fn map<U: ?Sized, F>(orig: Self, f: F) -> ReentrantMutexGuard<'a, U>
    where
        F: FnOnce(&T) -> &U,
    {
        let raw = orig.raw;
        let data = f(unsafe { &*orig.data });
        mem::forget(orig);
        ReentrantMutexGuard {
            raw,
            data,
            marker: PhantomData,
        }
    }
}

impl<'a, T: ?Sized + 'a> Deref for ReentrantMutexGuard<'a, T> {
    type Target = T;
    #[inline]
    fn deref(&self) -> &T {
        unsafe { &*self.data }
    }
}

impl<'a, T: ?Sized + 'a> Drop for ReentrantMutexGuard<'a, T> {
    #[inline]
    fn drop(&mut self) {
        self.raw.unlock(false);
    }
}

#[cfg(feature = "owning_ref")]
unsafe impl<'a, T: ?Sized> StableAddress for ReentrantMutexGuard<'a, T> {}

#[cfg(test)]
mod tests {
    use std::cell::RefCell;
    use std::sync::Arc;
    use std::thread;
    use ReentrantMutex;

    #[test]
    fn smoke() {
        let m = ReentrantMutex::new(());
        {
            let a = m.lock();
            {
                let b = m.lock();
                {
                    let c = m.lock();
                    assert_eq!(*c, ());
                }
                assert_eq!(*b, ());
            }
            assert_eq!(*a, ());
        }
    }

    #[test]
    fn is_mutex() {
        let m = Arc::new(ReentrantMutex::new(RefCell::new(0)));
        let m2 = m.clone();
        let lock = m.lock();
        let child = thread::spawn(move || {
            let lock = m2.lock();
            assert_eq!(*lock.borrow(), 4950);
        });
        for i in 0..100 {
            let lock = m.lock();
            *lock.borrow_mut() += i;
        }
        drop(lock);
        child.join().unwrap();
    }

    #[test]
    fn trylock_works() {
        let m = Arc::new(ReentrantMutex::new(()));
        let m2 = m.clone();
        let _lock = m.try_lock();
        let _lock2 = m.try_lock();
        thread::spawn(move || {
            let lock = m2.try_lock();
            assert!(lock.is_none());
        }).join()
            .unwrap();
        let _lock3 = m.try_lock();
    }
}
<|endoftext|>


<commit_before>#[macro_use]
pub mod proto;

use std::collections::HashMap;
use std::sync::Arc;
use std::io;
use std::time::Duration;
use parking_lot::{Mutex, RwLock};
use std::thread;
use tcp;
use utils::time;
use utils::u8vec::*;
use futures::Future;
use bifrost_hasher::hash_str;
use DISABLE_SHORTCUT;

lazy_static! {
    pub static ref DEFAULT_CLIENT_POOL: ClientPool = ClientPool::new();
}

#[derive(Serialize, Deserialize, Debug)]
pub enum RPCRequestError {
    FunctionIdNotFound,
    ServiceIdNotFound,
    Other,
}

#[derive(Debug)]
pub enum RPCError {
    IOError(io::Error),
    RequestError(RPCRequestError),
}

pub trait RPCService: Sync + Send {
    fn dispatch(&self, data: Vec<u8>) -> Result<Vec<u8>, RPCRequestError>;
    fn register_shortcut_service(&self, service_ptr: usize, server_id: u64, service_id: u64);
}

pub struct Server {
    services: RwLock<HashMap<u64, Arc<RPCService>>>,
    pub address: String,
    pub server_id: u64
}

pub struct ClientPool {
    clients: Mutex<HashMap<String, Arc<RPCClient>>>
}

fn encode_res(res: Result<Vec<u8>, RPCRequestError>) -> Vec<u8> {
    match res {
        Ok(vec) => {
            [0u8; 1].iter().cloned().chain(vec.into_iter()).collect()
        },
        Err(e) => {
            let err_id = match e {
                RPCRequestError::FunctionIdNotFound => 1u8,
                RPCRequestError::ServiceIdNotFound => 2u8,
                _ => 255u8
            };
            vec!(err_id)
        }
    }
}

fn decode_res(res: io::Result<Vec<u8>>) -> Result<Vec<u8>, RPCError> {
    match res {
        Ok(res) => {
            if res[0] == 0u8 {
                Ok(res.into_iter().skip(1).collect())
            } else {
                match res[0] {
                    1u8 => Err(RPCError::RequestError(RPCRequestError::FunctionIdNotFound)),
                    2u8 => Err(RPCError::RequestError(RPCRequestError::ServiceIdNotFound)),
                    _ => Err(RPCError::RequestError(RPCRequestError::Other)),
                }
            }
        },
        Err(e) => Err(RPCError::IOError(e))
    }
}

impl Server {
    pub fn new(address: &String) -> Arc<Server> {
        Arc::new(Server {
            services: RwLock::new(HashMap::new()),
            address: address.clone(),
            server_id: hash_str(address)
        })
    }
    pub fn listen(server: &Arc<Server>) {
        let address = &server.address;
        let server = server.clone();
        tcp::server::Server::new(address, Box::new(move |data| {
            let (svr_id, data) = extract_u64_head(data);
            let svr_map = server.services.read();
            let service = svr_map.get(&svr_id);
            let res = match service {
                Some(service) => {
                    encode_res(service.dispatch(data))
                },
                None => encode_res(Err(RPCRequestError::ServiceIdNotFound) as Result<Vec<u8>, RPCRequestError>)
            };
            //println!("SVR RPC: {} - {}ms", svr_id, time::get_time() - t);
            res
        }));
    }
    pub fn listen_and_resume(server: &Arc<Server>) {
        let server = server.clone();
        thread::spawn(move|| {
            let server = server;
            Server::listen(&server);
        });
    }
    pub fn register_service<T>(&self, service_id: u64,  service: &Arc<T>)
    where T: RPCService + Sized + 'static{
        let service = service.clone();
        if !DISABLE_SHORTCUT {
            let service_ptr = Arc::into_raw(service.clone()) as usize;
            service.register_shortcut_service(service_ptr, self.server_id, service_id);
        } else {
            println!("SERVICE SHORTCUT DISABLED");
        }
        self.services.write().insert(service_id, service);
    }
    pub fn remove_service(&self, service_id: u64) {
        self.services.write().remove(&service_id);
    }
    pub fn address(&self) -> &String {
        &self.address
    }
}

pub struct RPCClient {
    client: Mutex<tcp::client::Client>,
    pub server_id: u64,
    pub address: String
}

impl RPCClient {
    pub fn send(&self, svr_id: u64, data: Vec<u8>) -> Result<Vec<u8>, RPCError> {
        decode_res(self.client.lock().send(prepend_u64(svr_id, data)))
    }
    pub fn send_async(&self, svr_id: u64, data: Vec<u8>) -> Box<Future<Item = Vec<u8>, Error = RPCError>> {
        Box::new(self.client.lock()
            .send_async(prepend_u64(svr_id, data))
            .then(move |res| decode_res(res)))
    }
    pub fn new(addr: &String) -> io::Result<Arc<RPCClient>> {
        let client = tcp::client::Client::connect(addr)?;
        Ok(Arc::new(RPCClient {
            server_id: client.server_id,
            client: Mutex::new(client),
            address: addr.clone()
        }))
    }
    pub fn with_timeout(addr: &String, timeout: Duration) -> io::Result<Arc<RPCClient>> {
        let client = tcp::client::Client::connect_with_timeout(addr, timeout)?;
        Ok(Arc::new(RPCClient {
            server_id: client.server_id,
            client: Mutex::new(client),
            address: addr.clone()
        }))
    }
}

impl ClientPool {
    pub fn new() -> ClientPool {
        ClientPool {
            clients: Mutex::new(HashMap::new())
        }
    }

    pub fn get(&self, addr: &String) -> io::Result<Arc<RPCClient>> {
        let mut clients = self.clients.lock();
        if clients.contains_key(addr) {
            Ok(clients.get(addr).unwrap().clone())
        } else {
            let client = RPCClient::new(addr);
            if let Ok(client) = client {
                clients.insert(addr.clone(), client.clone());
                Ok(client)
            } else {
                Err(client.err().unwrap())
            }
        }
    }
}<commit_msg>fixing rpc but it is not async yet<commit_after>#[macro_use]
pub mod proto;

use std::collections::HashMap;
use std::sync::Arc;
use std::io;
use std::time::Duration;
use parking_lot::{Mutex, RwLock};
use std::thread;
use tcp;
use utils::time;
use utils::u8vec::*;
use futures::{Future, future};
use bifrost_hasher::hash_str;
use DISABLE_SHORTCUT;

lazy_static! {
    pub static ref DEFAULT_CLIENT_POOL: ClientPool = ClientPool::new();
}

#[derive(Serialize, Deserialize, Debug)]
pub enum RPCRequestError {
    FunctionIdNotFound,
    ServiceIdNotFound,
    Other,
}

#[derive(Debug)]
pub enum RPCError {
    IOError(io::Error),
    RequestError(RPCRequestError),
}

pub trait RPCService: Sync + Send {
    fn dispatch(&self, data: Vec<u8>) -> Result<Vec<u8>, RPCRequestError>;
    fn register_shortcut_service(&self, service_ptr: usize, server_id: u64, service_id: u64);
}

pub struct Server {
    services: RwLock<HashMap<u64, Arc<RPCService>>>,
    pub address: String,
    pub server_id: u64
}

pub struct ClientPool {
    clients: Mutex<HashMap<String, Arc<RPCClient>>>
}

fn encode_res(res: Result<Vec<u8>, RPCRequestError>) -> Vec<u8> {
    match res {
        Ok(vec) => {
            [0u8; 1].iter().cloned().chain(vec.into_iter()).collect()
        },
        Err(e) => {
            let err_id = match e {
                RPCRequestError::FunctionIdNotFound => 1u8,
                RPCRequestError::ServiceIdNotFound => 2u8,
                _ => 255u8
            };
            vec!(err_id)
        }
    }
}

fn decode_res(res: io::Result<Vec<u8>>) -> Result<Vec<u8>, RPCError> {
    match res {
        Ok(res) => {
            if res[0] == 0u8 {
                Ok(res.into_iter().skip(1).collect())
            } else {
                match res[0] {
                    1u8 => Err(RPCError::RequestError(RPCRequestError::FunctionIdNotFound)),
                    2u8 => Err(RPCError::RequestError(RPCRequestError::ServiceIdNotFound)),
                    _ => Err(RPCError::RequestError(RPCRequestError::Other)),
                }
            }
        },
        Err(e) => Err(RPCError::IOError(e))
    }
}

impl Server {
    pub fn new(address: &String) -> Arc<Server> {
        Arc::new(Server {
            services: RwLock::new(HashMap::new()),
            address: address.clone(),
            server_id: hash_str(address)
        })
    }
    pub fn listen(server: &Arc<Server>) {
        let address = &server.address;
        let server = server.clone();
        tcp::server::Server::new(address, Box::new(move |data| {
            let (svr_id, data) = extract_u64_head(data);
            let svr_map = server.services.read();
            let service = svr_map.get(&svr_id);
            let res = match service {
                Some(service) => {
                    encode_res(service.dispatch(data))
                },
                None => encode_res(Err(RPCRequestError::ServiceIdNotFound) as Result<Vec<u8>, RPCRequestError>)
            };
            //println!("SVR RPC: {} - {}ms", svr_id, time::get_time() - t);
            Box::new(future::finished(res))
        }));
    }
    pub fn listen_and_resume(server: &Arc<Server>) {
        let server = server.clone();
        thread::spawn(move|| {
            let server = server;
            Server::listen(&server);
        });
    }
    pub fn register_service<T>(&self, service_id: u64,  service: &Arc<T>)
    where T: RPCService + Sized + 'static{
        let service = service.clone();
        if !DISABLE_SHORTCUT {
            let service_ptr = Arc::into_raw(service.clone()) as usize;
            service.register_shortcut_service(service_ptr, self.server_id, service_id);
        } else {
            println!("SERVICE SHORTCUT DISABLED");
        }
        self.services.write().insert(service_id, service);
    }
    pub fn remove_service(&self, service_id: u64) {
        self.services.write().remove(&service_id);
    }
    pub fn address(&self) -> &String {
        &self.address
    }
}

pub struct RPCClient {
    client: Mutex<tcp::client::Client>,
    pub server_id: u64,
    pub address: String
}

impl RPCClient {
    pub fn send(&self, svr_id: u64, data: Vec<u8>) -> Result<Vec<u8>, RPCError> {
        decode_res(self.client.lock().send(prepend_u64(svr_id, data)))
    }
    pub fn send_async(&self, svr_id: u64, data: Vec<u8>) -> Box<Future<Item = Vec<u8>, Error = RPCError>> {
        Box::new(self.client.lock()
            .send_async(prepend_u64(svr_id, data))
            .then(move |res| decode_res(res)))
    }
    pub fn new(addr: &String) -> io::Result<Arc<RPCClient>> {
        let client = tcp::client::Client::connect(addr)?;
        Ok(Arc::new(RPCClient {
            server_id: client.server_id,
            client: Mutex::new(client),
            address: addr.clone()
        }))
    }
    pub fn with_timeout(addr: &String, timeout: Duration) -> io::Result<Arc<RPCClient>> {
        let client = tcp::client::Client::connect_with_timeout(addr, timeout)?;
        Ok(Arc::new(RPCClient {
            server_id: client.server_id,
            client: Mutex::new(client),
            address: addr.clone()
        }))
    }
}

impl ClientPool {
    pub fn new() -> ClientPool {
        ClientPool {
            clients: Mutex::new(HashMap::new())
        }
    }

    pub fn get(&self, addr: &String) -> io::Result<Arc<RPCClient>> {
        let mut clients = self.clients.lock();
        if clients.contains_key(addr) {
            Ok(clients.get(addr).unwrap().clone())
        } else {
            let client = RPCClient::new(addr);
            if let Ok(client) = client {
                clients.insert(addr.clone(), client.clone());
                Ok(client)
            } else {
                Err(client.err().unwrap())
            }
        }
    }
}<|endoftext|>


<commit_before>use sass::value_part::ValuePart;
use evaluator::Evaluator;

use std::borrow::Cow::*;
use std::str::FromStr;
use std::collections::HashMap;

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Op {
    Plus,
    Minus,
    Star,
    Slash,
    Percent,
    LeftParen,
    RightParen,
    Comma,
}

impl FromStr for Op {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "+" => Ok(Op::Plus),
            "-" => Ok(Op::Minus),
            "*" => Ok(Op::Star),
            "/" => Ok(Op::Slash),
            "%" => Ok(Op::Percent),
            "(" => Ok(Op::LeftParen),
            ")" => Ok(Op::RightParen),
            "," => Ok(Op::Comma),
            _   => Err(()),
        }
    }
}

impl Op {
    pub fn apply<'a>(&self, first: ValuePart<'a>, second: ValuePart<'a>, paren_level: i32) -> ValuePart<'a> {
        match (self, second) {
            (&Op::Plus, s @ ValuePart::List(..)) => self.apply_list(first, s),
            (&Op::Plus, s @ ValuePart::String(..)) => {
                ValuePart::String(format!("{}{}", first, s).into())
            },
            (&Op::Slash, s) => self.apply_slash(first, s, paren_level),
            (&Op::Comma, s) => {
                ValuePart::concat_into_list(
                    ValuePart::concat_into_list(first, ValuePart::Operator(*self)),
                    s,
                )
            },
            (_, s) => {
                self.apply_math(first, s)
            },
        }
    }

    fn force_list_collapse<'a>(&self, mut vp: ValuePart<'a>) -> ValuePart<'a> {
        match vp {
            ValuePart::List(ref mut l) => {
                if l.iter().any(|v| {
                    match v {
                        &ValuePart::Operator(Op::Slash) => true,
                        _ => false,
                    }
                }) {
                    let mut ve = vec![ValuePart::Operator(Op::LeftParen)];
                    l.push(ValuePart::Operator(Op::RightParen));
                    ve.append(l);
                    Evaluator::new(ve).evaluate(&HashMap::new())
                } else {
                    ValuePart::List(l.clone())
                }
            },
            _ => vp,
        }
    }

    fn apply_list<'a>(&self, first: ValuePart<'a>, second: ValuePart<'a>) -> ValuePart<'a> {
        let first_collapsed  = self.force_list_collapse(first);
        let second_collapsed = self.force_list_collapse(second);

        match (first_collapsed, second_collapsed) {
            (ValuePart::Number(fnum), ValuePart::List(mut slist)) => {
                let new_first_item_value = format!("{}{}", fnum, slist.remove(0));
                let v = ValuePart::String(new_first_item_value.into());

                ValuePart::concat_into_list(v, ValuePart::List(slist))
            },
            (ValuePart::List(mut flist), ValuePart::Number(snum)) => {
                let new_last_item_value = format!("{}{}",
                    flist.pop().unwrap_or(ValuePart::String(Borrowed(""))),
                    snum
                );
                let v = ValuePart::String(new_last_item_value.into());
                ValuePart::concat_into_list(ValuePart::List(flist), v)
            },
            (f @ ValuePart::List(..), s @ ValuePart::List(..)) => {
                ValuePart::concat_into_list(f, s)
            },
            (f @ ValuePart::Number(..), s @ ValuePart::Number(..)) => {
                self.apply_math(f, s)
            },
            (unk_first, unk_second) => {
                return ValuePart::String(format!(
                    "Unknown apply_list match:\n  first: {:?}\n  second: {:?}",
                    unk_first, unk_second
                ).into())
            },
        }
    }

    fn apply_slash<'a>(&self, first: ValuePart<'a>, second: ValuePart<'a>, paren_level: i32) -> ValuePart<'a> {
        if paren_level == 0 {
            if first.computed_number() || second.computed_number() {
                self.apply_math(self.force_list_collapse(first), self.force_list_collapse(second))
            } else {
                ValuePart::concat_into_list(
                    ValuePart::concat_into_list(first, ValuePart::Operator(*self)),
                    second,
                )
            }
        } else {
            match first {
                ValuePart::List(..) => {
                    ValuePart::concat_into_list(
                        ValuePart::concat_into_list(first, ValuePart::Operator(*self)),
                        second,
                    )
                },
                _ => {
                    self.apply_math(first, second)
                },
            }
        }
    }

    fn apply_math<'a>(&self, first: ValuePart<'a>, second: ValuePart<'a>) -> ValuePart<'a> {
        let (f, s) = match (first, second) {
            (ValuePart::Number(f), ValuePart::Number(s)) => (f, s),
            (f, s) => return ValuePart::String(format!("Invalid apply math arguments:\n  first: {:?}\n  second: {:?}\n", f, s).into()),
        };

        ValuePart::Number(f.apply_math(*self, s))
    }

    pub fn same_or_greater_precedence(self, other: Op) -> bool {
        match (self, other) {
            (Op::Plus, Op::Star) |
            (Op::Minus, Op::Star) |
            (Op::Plus, Op::Slash) |
            (Op::Minus, Op::Slash) |
            (Op::LeftParen, _) => false,
            (_, _) => true,
        }
    }
}
<commit_msg>Inline the math application since it's way smaller now<commit_after>use sass::value_part::ValuePart;
use evaluator::Evaluator;

use std::borrow::Cow::*;
use std::str::FromStr;
use std::collections::HashMap;

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Op {
    Plus,
    Minus,
    Star,
    Slash,
    Percent,
    LeftParen,
    RightParen,
    Comma,
}

impl FromStr for Op {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "+" => Ok(Op::Plus),
            "-" => Ok(Op::Minus),
            "*" => Ok(Op::Star),
            "/" => Ok(Op::Slash),
            "%" => Ok(Op::Percent),
            "(" => Ok(Op::LeftParen),
            ")" => Ok(Op::RightParen),
            "," => Ok(Op::Comma),
            _   => Err(()),
        }
    }
}

impl Op {
    pub fn apply<'a>(&self, first: ValuePart<'a>, second: ValuePart<'a>, paren_level: i32) -> ValuePart<'a> {
        match (self, second) {
            (&Op::Plus, s @ ValuePart::List(..)) => self.apply_list(first, s),
            (&Op::Plus, s @ ValuePart::String(..)) => {
                ValuePart::String(format!("{}{}", first, s).into())
            },
            (&Op::Slash, s) => self.apply_slash(first, s, paren_level),
            (&Op::Comma, s) => {
                ValuePart::concat_into_list(
                    ValuePart::concat_into_list(first, ValuePart::Operator(*self)),
                    s,
                )
            },
            (_, s) => {
                self.apply_math(first, s)
            },
        }
    }

    fn force_list_collapse<'a>(&self, mut vp: ValuePart<'a>) -> ValuePart<'a> {
        match vp {
            ValuePart::List(ref mut l) => {
                if l.iter().any(|v| {
                    match v {
                        &ValuePart::Operator(Op::Slash) => true,
                        _ => false,
                    }
                }) {
                    let mut ve = vec![ValuePart::Operator(Op::LeftParen)];
                    l.push(ValuePart::Operator(Op::RightParen));
                    ve.append(l);
                    Evaluator::new(ve).evaluate(&HashMap::new())
                } else {
                    ValuePart::List(l.clone())
                }
            },
            _ => vp,
        }
    }

    fn apply_list<'a>(&self, first: ValuePart<'a>, second: ValuePart<'a>) -> ValuePart<'a> {
        let first_collapsed  = self.force_list_collapse(first);
        let second_collapsed = self.force_list_collapse(second);

        match (first_collapsed, second_collapsed) {
            (ValuePart::Number(fnum), ValuePart::List(mut slist)) => {
                let new_first_item_value = format!("{}{}", fnum, slist.remove(0));
                let v = ValuePart::String(new_first_item_value.into());

                ValuePart::concat_into_list(v, ValuePart::List(slist))
            },
            (ValuePart::List(mut flist), ValuePart::Number(snum)) => {
                let new_last_item_value = format!("{}{}",
                    flist.pop().unwrap_or(ValuePart::String(Borrowed(""))),
                    snum
                );
                let v = ValuePart::String(new_last_item_value.into());
                ValuePart::concat_into_list(ValuePart::List(flist), v)
            },
            (f @ ValuePart::List(..), s @ ValuePart::List(..)) => {
                ValuePart::concat_into_list(f, s)
            },
            (f @ ValuePart::Number(..), s @ ValuePart::Number(..)) => {
                self.apply_math(f, s)
            },
            (unk_first, unk_second) => {
                return ValuePart::String(format!(
                    "Unknown apply_list match:\n  first: {:?}\n  second: {:?}",
                    unk_first, unk_second
                ).into())
            },
        }
    }

    fn apply_slash<'a>(&self, first: ValuePart<'a>, second: ValuePart<'a>, paren_level: i32) -> ValuePart<'a> {
        if paren_level == 0 {
            if first.computed_number() || second.computed_number() {
                self.apply_math(self.force_list_collapse(first), self.force_list_collapse(second))
            } else {
                ValuePart::concat_into_list(
                    ValuePart::concat_into_list(first, ValuePart::Operator(*self)),
                    second,
                )
            }
        } else {
            match first {
                ValuePart::List(..) => {
                    ValuePart::concat_into_list(
                        ValuePart::concat_into_list(first, ValuePart::Operator(*self)),
                        second,
                    )
                },
                _ => {
                    self.apply_math(first, second)
                },
            }
        }
    }

    fn apply_math<'a>(&self, first: ValuePart<'a>, second: ValuePart<'a>) -> ValuePart<'a> {
        match (first, second) {
            (ValuePart::Number(f), ValuePart::Number(s)) => {
                ValuePart::Number(f.apply_math(*self, s))
            },
            (f, s) => {
                // TODO: result
                ValuePart::String(
                    format!("Invalid apply math arguments:\n  first: {:?}\n  second: {:?}\n", f, s).into()
                )
            },
        }
    }

    pub fn same_or_greater_precedence(self, other: Op) -> bool {
        match (self, other) {
            (Op::Plus, Op::Star) |
            (Op::Minus, Op::Star) |
            (Op::Plus, Op::Slash) |
            (Op::Minus, Op::Slash) |
            (Op::LeftParen, _) => false,
            (_, _) => true,
        }
    }
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::default::Default;
use std::fmt;
use union_find::{QuickFindUf, Union, UnionByRank, UnionFind, UnionResult};
use base::fixed::{FixedMap, FixedVec};
use base::interner::InternedStr;

pub struct Substitution<T> {
    map: RefCell<QuickFindUf<UnionByLevel>>,
    variables: FixedVec<T>,
    types: FixedMap<u32, T>,
    pub named_variables: RefCell<HashMap<InternedStr, T>>,
}

pub trait Variable {
    fn get_id(&self) -> u32;
}

impl Variable for u32 {
    fn get_id(&self) -> u32 {
        *self
    }
}

pub trait Substitutable: PartialEq + Clone {
    type Variable: Variable;
    fn new(x: u32) -> Self;
    fn from_variable(x: Self::Variable) -> Self;
    fn get_var(&self) -> Option<&Self::Variable>;
    fn occurs(&self, subs: &Substitution<Self>, var: &Self::Variable) -> bool;
}

#[derive(Debug)]
struct UnionByLevel {
    rank: UnionByRank,
    level: u32
}

impl Default for UnionByLevel {
    fn default() -> UnionByLevel {
        UnionByLevel { rank: UnionByRank::default(), level: ::std::u32::MAX }
    }
}

impl Union for UnionByLevel {
    #[inline]
    fn union(left: UnionByLevel, right: UnionByLevel) -> UnionResult<UnionByLevel> {
        use std::cmp::Ordering;
        let (rank_result, rank) = match Union::union(left.rank, right.rank) {
            UnionResult::Left(l) => (UnionResult::Left(UnionByLevel { rank: l, level: left.level }), l),
            UnionResult::Right(r) => (UnionResult::Right(UnionByLevel { rank: r, level: left.level }), r)
        };
        match left.level.cmp(&right.level) {
            Ordering::Less => UnionResult::Left(UnionByLevel { rank: rank, level: left.level }),
            Ordering::Greater => UnionResult::Right(UnionByLevel { rank: rank, level: right.level }),
            Ordering::Equal => rank_result
        }
    }
}

impl <T: fmt::Debug> fmt::Debug for Substitution<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Substitution {{ map: {:?}, named_variables: {:?}, var_id: {:?} }}",
               self.map.borrow(), self.named_variables.borrow(), self.var_id())
    }
}

impl <T> Substitution<T> {
    pub fn var_id(&self) -> u32 {
        (self.variables.borrow().len() - 1) as u32
    }
}

impl <T: Substitutable> Substitution<T> {
    pub fn new() -> Substitution<T> {
        let variables = FixedVec::new();
        variables.push(T::new(0));
        Substitution {
            map: RefCell::new(QuickFindUf::new(1)),
            variables: variables,
            types: FixedMap::new(),
            named_variables: RefCell::new(HashMap::new()),
        }
    }

    pub fn clear(&mut self) {
        self.types.clear();
        self.variables.clear();
        self.variables.push(T::new(0));
        self.named_variables.borrow_mut().clear();
    }

    pub fn insert(&self, var: u32, t: T) {
        match t.get_var() {
            Some(_) => {
                panic!("Tried to insert variable which is not allowed as that would cause memory unsafety")
            }
            None => match self.types.try_insert(var, t) {
                Ok(()) => (),
                Err(_) => panic!("Expected variable to not have a type associated with it")
            }
        }
    }

    pub fn new_var(&self) -> T
    where T: Clone {
        let var_id = self.variables.len() as u32;
        let _id = self.map.borrow_mut().insert(UnionByLevel::default());
        assert_eq!(_id, self.variables.len());
        self.variables.push(T::new(var_id));
        let last = self.variables.len() - 1;
        self.variables[last].clone()
    }

    pub fn real<'r>(&'r self, typ: &'r T) -> &'r T {
        match typ.get_var() {
            Some(var) => match self.find_type_for_var(var.get_id()) {
                Some(t) => t,
                None => typ
            },
            _ => typ
        }
    }

    pub fn make_real(&self, typ: &mut T) {
        *typ = match typ.get_var() {
            Some(var) => match self.find_type_for_var(var.get_id()) {
                Some(t) => t.clone(),
                None => return
            },
            None => return
        };
    }

    pub fn find_type_for_var(&self, var: u32) -> Option<&T> {
        let index = self.map.borrow_mut().find(var as usize) as u32;
        self.types.get(&index)
            .or_else(|| if var == index { None } else { Some(&self.variables[index as usize]) })
    }

    pub fn variable_for(&self, id: InternedStr) -> T {
        let mut variables = self.named_variables.borrow_mut();
        match variables.entry(id) {
            Entry::Vacant(entry) => {
                let t = self.new_var();
                entry.insert(t).clone()
            }
            Entry::Occupied(entry) => entry.get().clone()
        }
    }

    pub fn update_level(&self, var: u32, other: u32) {
        let level = ::std::cmp::min(self.get_level(var), self.get_level(other));
        let mut map = self.map.borrow_mut();
        map.get_mut(other as usize).level = level;
    }

    pub fn get_level(&self, mut var: u32) -> u32 {
        if let Some(v) = self.find_type_for_var(var) {
            var = v.get_var().map(|v| v.get_id()).unwrap_or(var);
        }
        let mut map = self.map.borrow_mut();
        let level = &mut map.get_mut(var as usize).level;
        *level = ::std::cmp::min(*level, var);
        *level
    }

    pub fn union(&self, id: &T::Variable, typ: &T) -> Result<(), ()>
    where T::Variable: Clone {
        if typ.occurs(self, id) {
            return Err(())
        }
        {
            let id_type = self.find_type_for_var(id.get_id());
            let other_type = self.real(typ);
            if id_type.map(|x| x == other_type).unwrap_or(other_type.get_var().map(|y| y.get_id()) == Some(id.get_id())) {
                return Ok(())
            }
        }
        //Always make sure the mapping is from a higher variable to a lower
        //This way the resulting variables are always equal to any variables in the globals
        //declaration
        match typ.get_var() {
            Some(other_id) => {
                self.map.borrow_mut().union(id.get_id() as usize, other_id.get_id() as usize);
                self.update_level(id.get_id(), other_id.get_id());
                self.update_level(other_id.get_id(), id.get_id());
            }
            _ => {
                self.insert(id.get_id(), typ.clone());
            }
        };
        Ok(())
    }
}
<commit_msg>Commenting substitution.rs<commit_after>use std::cell::RefCell;
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::default::Default;
use std::fmt;
use union_find::{QuickFindUf, Union, UnionByRank, UnionFind, UnionResult};
use base::fixed::{FixedMap, FixedVec};
use base::interner::InternedStr;

pub struct Substitution<T> {
    ///Union-find data structure used to store the relationships of all variables in the
    ///substitution
    union: RefCell<QuickFindUf<UnionByLevel>>,
    ///Vector containing all created variables for this substitution. Needed for the `real` method
    ///which needs to always be able to return a `&T` reference
    variables: FixedVec<T>,
    ///For variables which have been infered to have a real type (not a variable) their types are
    ///stored here. As the type stored will never changed we use a `FixedMap` lets `real` return
    ///`&T` from this map safely.
    types: FixedMap<u32, T>,
    ///TODO Is this the wrong struct to hold this field?
    pub named_variables: RefCell<HashMap<InternedStr, T>>,
}

///Trait which variables need to implement to allow the substitution to get to the u32 identifying
///the variable
pub trait Variable {
    fn get_id(&self) -> u32;
}

impl Variable for u32 {
    fn get_id(&self) -> u32 {
        *self
    }
}

///Trait implemented on types which may contain substitutable variables
pub trait Substitutable: PartialEq + Clone {
    type Variable: Variable;
    fn new(x: u32) -> Self;
    ///Constructs a new object from its variable type
    fn from_variable(x: Self::Variable) -> Self;
    ///Retrieves the variable if `self` is a variable otherwise returns `None`
    fn get_var(&self) -> Option<&Self::Variable>;
    ///Returns whether `var` occurs somewhere in `self`
    fn occurs(&self, subs: &Substitution<Self>, var: &Self::Variable) -> bool;
}

#[derive(Debug)]
struct UnionByLevel {
    rank: UnionByRank,
    level: u32
}

impl Default for UnionByLevel {
    fn default() -> UnionByLevel {
        UnionByLevel { rank: UnionByRank::default(), level: ::std::u32::MAX }
    }
}

impl Union for UnionByLevel {
    #[inline]
    fn union(left: UnionByLevel, right: UnionByLevel) -> UnionResult<UnionByLevel> {
        use std::cmp::Ordering;
        let (rank_result, rank) = match Union::union(left.rank, right.rank) {
            UnionResult::Left(l) => (UnionResult::Left(UnionByLevel { rank: l, level: left.level }), l),
            UnionResult::Right(r) => (UnionResult::Right(UnionByLevel { rank: r, level: left.level }), r)
        };
        match left.level.cmp(&right.level) {
            Ordering::Less => UnionResult::Left(UnionByLevel { rank: rank, level: left.level }),
            Ordering::Greater => UnionResult::Right(UnionByLevel { rank: rank, level: right.level }),
            Ordering::Equal => rank_result
        }
    }
}

impl <T: fmt::Debug> fmt::Debug for Substitution<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Substitution {{ map: {:?}, named_variables: {:?}, var_id: {:?} }}",
               self.union.borrow(), self.named_variables.borrow(), self.var_id())
    }
}

impl <T> Substitution<T> {
    pub fn var_id(&self) -> u32 {
        (self.variables.borrow().len() - 1) as u32
    }
}

impl <T: Substitutable> Substitution<T> {
    pub fn new() -> Substitution<T> {
        let variables = FixedVec::new();
        //0 is the default, uninitialized variable so we add it to make sure that the first
        //variable we create through `new_var` is 1
        variables.push(T::new(0));
        Substitution {
            union: RefCell::new(QuickFindUf::new(1)),
            variables: variables,
            types: FixedMap::new(),
            named_variables: RefCell::new(HashMap::new()),
        }
    }

    pub fn clear(&mut self) {
        self.types.clear();
        self.variables.clear();
        self.variables.push(T::new(0));
        self.named_variables.borrow_mut().clear();
    }

    pub fn insert(&self, var: u32, t: T) {
        match t.get_var() {
            Some(_) => {
                panic!("Tried to insert variable which is not allowed as that would cause memory unsafety")
            }
            None => match self.types.try_insert(var, t) {
                Ok(()) => (),
                Err(_) => panic!("Expected variable to not have a type associated with it")
            }
        }
    }

    ///Creates a new variable
    pub fn new_var(&self) -> T
    where T: Clone {
        let var_id = self.variables.len() as u32;
        let _id = self.union.borrow_mut().insert(UnionByLevel::default());
        assert_eq!(_id, self.variables.len());
        self.variables.push(T::new(var_id));
        let last = self.variables.len() - 1;
        self.variables[last].clone()
    }

    ///If `typ` is a variable this returns the real unified value of that variable. Otherwise it
    ///just returns the type itself. Note that the returned type may contain terms which also need
    ///to have `real` called on them.
    pub fn real<'r>(&'r self, typ: &'r T) -> &'r T {
        match typ.get_var() {
            Some(var) => match self.find_type_for_var(var.get_id()) {
                Some(t) => t,
                None => typ
            },
            _ => typ
        }
    }

    pub fn make_real(&self, typ: &mut T) {
        *typ = self.real(typ).clone();
    }

    pub fn find_type_for_var(&self, var: u32) -> Option<&T> {
        let index = self.union.borrow_mut().find(var as usize) as u32;
        self.types.get(&index)
            .or_else(|| if var == index { None } else { Some(&self.variables[index as usize]) })
    }

    pub fn variable_for(&self, id: InternedStr) -> T {
        let mut variables = self.named_variables.borrow_mut();
        match variables.entry(id) {
            Entry::Vacant(entry) => {
                let t = self.new_var();
                entry.insert(t).clone()
            }
            Entry::Occupied(entry) => entry.get().clone()
        }
    }

    ///Updates the level of `other` to be the minimum level value of `var` and `other`
    pub fn update_level(&self, var: u32, other: u32) {
        let level = ::std::cmp::min(self.get_level(var), self.get_level(other));
        let mut union = self.union.borrow_mut();
        union.get_mut(other as usize).level = level;
    }

    pub fn get_level(&self, mut var: u32) -> u32 {
        if let Some(v) = self.find_type_for_var(var) {
            var = v.get_var().map(|v| v.get_id()).unwrap_or(var);
        }
        let mut union = self.union.borrow_mut();
        let level = &mut union.get_mut(var as usize).level;
        *level = ::std::cmp::min(*level, var);
        *level
    }

    ///Takes `id` and updates the substitution to say that it should have the same type as `typ`
    pub fn union(&self, id: &T::Variable, typ: &T) -> Result<(), ()>
    where T::Variable: Clone {
        if typ.occurs(self, id) {
            return Err(())
        }
        {
            let id_type = self.find_type_for_var(id.get_id());
            let other_type = self.real(typ);
            if id_type.map(|x| x == other_type).unwrap_or(other_type.get_var().map(|y| y.get_id()) == Some(id.get_id())) {
                return Ok(())
            }
        }
        match typ.get_var() {
            Some(other_id) => {
                self.union.borrow_mut().union(id.get_id() as usize, other_id.get_id() as usize);
                self.update_level(id.get_id(), other_id.get_id());
                self.update_level(other_id.get_id(), id.get_id());
            }
            _ => {
                self.insert(id.get_id(), typ.clone());
            }
        };
        Ok(())
    }
}
<|endoftext|>


<commit_before>//! Sensor related stuff.

use super::api;
use super::datastore::SafeDataStore;

/// A specification of a sensor.
///
/// The ``template`` field contains the static data of a sensor and
/// the ``data_key`` says how to find the sensor value in the datastore.
pub struct SensorSpec {
    pub template: Box<api::SensorTemplate>,
    pub data_key: String,
}

impl SensorSpec {

    /// Retrieve sensor value from the datastore.
    pub fn get_sensor_value(&self, datastore: &SafeDataStore) -> Option<String> {
        let datastore_lock = datastore.lock().unwrap();
        datastore_lock.retrieve(&self.data_key).map_err(|err| {
            warn!("Could not retrieve key '{}' from datastore, omiting the sensor", &self.data_key);
            err
        }).ok()
    }

}

<commit_msg>Log errors on debug level<commit_after>//! Sensor related stuff.

use super::api;
use super::datastore::SafeDataStore;

/// A specification of a sensor.
///
/// The ``template`` field contains the static data of a sensor and
/// the ``data_key`` says how to find the sensor value in the datastore.
pub struct SensorSpec {
    pub template: Box<api::SensorTemplate>,
    pub data_key: String,
}

impl SensorSpec {

    /// Retrieve sensor value from the datastore.
    pub fn get_sensor_value(&self, datastore: &SafeDataStore) -> Option<String> {
        let datastore_lock = datastore.lock().unwrap();
        datastore_lock.retrieve(&self.data_key).map_err(|err| {
            warn!("Could not retrieve key '{}' from datastore, omiting the sensor", &self.data_key);
            debug!("Error: {:?}", err);
            err
        }).ok()
    }

}

<|endoftext|>


<commit_before>use RegT;

const PAGE_SHIFT: usize = 10;       // 1 kByte page size = (1<<10)
const PAGE_SIZE: usize = (1<<PAGE_SHIFT);
const PAGE_MASK:  usize = PAGE_SIZE-1;
const HEAP_SIZE: usize = 512 * PAGE_SIZE;
const NUM_PAGES: usize = (1<<16) / PAGE_SIZE;
const NUM_LAYERS: usize = 4;

#[derive(Clone,Copy)]
struct Page {
    pub offset: usize,          // offset into heap
    pub writable : bool,        // true if the page is writable
    pub mapped: bool,           // true if currently mapped
}

impl Page {
    /// return a new, unmapped page
    pub fn new() -> Page {
        Page { offset: 0, writable: false, mapped: false }
    }
    /// map page to chunk of heap memory
    pub fn map(&mut self, offset: usize, writable: bool) {
        self.offset = offset;
        self.writable = writable;
        self.mapped = true;
    }
    /// unmap page
    pub fn unmap(&mut self) {
        self.offset = 0;
        self.writable = false;
        self.mapped = false;
    }
}

/// memory access (simplified, no memory mapping or bank switching)
pub struct Memory {
    pages: [Page; NUM_PAGES],                   // currently CPU-visible pages
    layers: [[Page; NUM_PAGES]; NUM_LAYERS],    // currently mapped layers
    heap: [u8; HEAP_SIZE],                      // all available physical memory
}

impl Memory {

    /// return new, unmapped memory object
    pub fn new_unmapped() -> Memory {
        Memory {
            pages: [Page::new(); NUM_PAGES],
            layers: [[Page::new(); NUM_PAGES]; NUM_LAYERS],
            heap: [0; HEAP_SIZE]
        }
    }

    /// return new memory object with 64 kByte mapped, writable memory (for testing)
    pub fn new() -> Memory {
        let mut mem = Memory::new_unmapped();
        mem.map(0, 0, (1<<16), 0, true);
        mem
    }

    /// map a chunk of heap memory to CPU-mapped memory
    pub fn map(&mut self, layer: usize, heap_offset: usize, size: usize, addr: usize, writable: bool) {
        assert!((size & PAGE_MASK) == 0);
        assert!((addr & PAGE_MASK) == 0);
        let num = size >> PAGE_SHIFT;
        for i in 0..num {
            let map_offset = i * PAGE_SIZE;
            let page_index = ((addr + map_offset) & 0xFFFF) >> PAGE_SHIFT;
            let page = &mut self.layers[layer][page_index];
            page.map(heap_offset + map_offset, writable);
        }
        self.update_mapping();
    }

    /// unmap a chunk heap memory
    pub fn unmap(&mut self, layer: usize, size: usize, addr: usize) {
        assert!((size & PAGE_MASK) == 0);
        assert!((addr & PAGE_MASK) == 0);
        let num = size >> PAGE_SHIFT;
        for i in 0..num {
            let map_offset = i * PAGE_SIZE;
            let page_index = ((addr + map_offset) & 0xFFFF) >> PAGE_SHIFT;
            let page = &mut self.layers[layer][page_index];
            page.unmap();
        }
        self.update_mapping();
    }

    /// unmap all pages in a layer
    pub fn unmap_layer(&mut self, layer: usize) {
        for page in self.layers[layer].iter_mut() {
            page.unmap();
        }
        self.update_mapping();
    }

    /// unmap all pages in all layers
    pub fn umap_all(&mut self) {
        for layer in self.layers.iter_mut() {
            for page in layer.iter_mut() {
                page.unmap();
            }
        }
        self.update_mapping();
    }

    /// private method to update internal CPU-visible mapping from mapped layers
    fn update_mapping(&mut self) {
        // for each cpu-visible page, find the highest-priority layer
        // which maps this memory range and copy it into the
        // cpu-visible page
        for page_index in 0..NUM_PAGES {
            let mut layer_page: Option<&Page> = None;
            for layer_index in 0..NUM_LAYERS {
                if self.layers[layer_index][page_index].mapped {
                    layer_page = Some(&self.layers[layer_index][page_index]);
                    break;
                }
            }
            match layer_page {
                Some(page) => self.pages[page_index] = *page,
                None => self.pages[page_index].unmap()
            }
        }
    }

    /// read unsigned byte from 16-bit address
    #[inline(always)]
    pub fn r8(&self, addr: RegT) -> RegT {
        let uaddr = (addr & 0xFFFF) as usize;
        let page = &self.pages[uaddr >> PAGE_SHIFT];
        if page.mapped {
            let heap_offset = page.offset + (uaddr & PAGE_MASK);
            self.heap[heap_offset] as RegT
        }
        else {
            0xFF
        }
    }

    /// read signed byte from 16-bit address
    #[inline(always)]
    pub fn rs8(&self, addr: RegT) -> RegT {
        let uaddr = (addr & 0xFFFF) as usize;
        let page = &self.pages[uaddr >> PAGE_SHIFT];
        if page.mapped {
            let heap_offset = page.offset + (uaddr & PAGE_MASK);
            self.heap[heap_offset] as i8 as RegT
        }
        else {
            0xFF
        }
    }

    /// write unsigned byte to 16-bit address
    #[inline(always)]
    pub fn w8(&mut self, addr: RegT, val: RegT) {
        let uaddr = (addr & 0xFFFF) as usize;
        let page = &self.pages[uaddr >> PAGE_SHIFT];
        if page.mapped && page.writable {
            let heap_offset = page.offset + (uaddr & PAGE_MASK);
            self.heap[heap_offset] = val as u8;
        }
    }

    /// read unsigned word from 16-bit address
    #[inline(always)]
    pub fn r16(&self, addr: RegT) -> RegT {
        let l = self.r8(addr);
        let h = self.r8(addr + 1);
        h<<8 | l
    }

    /// write unsigned word to 16-bit address
    #[inline(always)]
    pub fn w16(&mut self, addr: RegT, val: RegT) {
        let l = val & 0xff;
        let h = (val >> 8) & 0xff;
        self.w8(addr, l);
        self.w8(addr + 1, h);
    }

    /// write a whole chunk of memory
    pub fn write(&mut self, addr: RegT, data: &[u8]) {
        let mut offset = 0;
        for b in data {
            self.w8(addr+offset, *b as RegT);
            offset += 1;
        }
    }
}

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

    #[test]
    fn mem_readwrite() {
        let mut mem = Memory::new();
        mem.w8(0x1234, 0x12);
        assert!(mem.r8(0x1234) == 0x12);

        mem.w8(0x2345, 0x32);
        assert!(mem.r8(0x2345) == 0x32);

        mem.w16(0x1000, 0x1234);
        assert!(mem.r16(0x1000) == 0x1234);
        assert!(mem.r8(0x1000) == 0x34);
        assert!(mem.r8(0x1001) == 0x12);

        mem.w16(0xFFFF, 0x2233);
        assert!(mem.r16(0xFFFF) == 0x2233);
        assert!(mem.r8(0xFFFF) == 0x33);
        assert!(mem.r8(0x0000) == 0x22);
    }
}
<commit_msg>Minor coding style tweaks<commit_after>use RegT;

const PAGE_SHIFT: usize = 10;   // 1 kByte page size = (1<<10)
const PAGE_SIZE:  usize = (1<<PAGE_SHIFT);
const PAGE_MASK:  usize = PAGE_SIZE-1;
const HEAP_SIZE:  usize = 512 * PAGE_SIZE;
const NUM_PAGES:  usize = (1<<16) / PAGE_SIZE;
const NUM_LAYERS: usize = 4;

#[derive(Clone,Copy)]
struct Page {
    pub offset: usize,      // offset into heap
    pub writable: bool,     // true if the page is writable
    pub mapped: bool,       // true if currently mapped
}

impl Page {
    /// return a new, unmapped page
    pub fn new() -> Page {
        Page { offset: 0, writable: false, mapped: false }
    }
    /// map page to chunk of heap memory
    pub fn map(&mut self, offset: usize, writable: bool) {
        self.offset = offset;
        self.writable = writable;
        self.mapped = true;
    }
    /// unmap page
    pub fn unmap(&mut self) {
        self.offset = 0;
        self.writable = false;
        self.mapped = false;
    }
}

/// memory access (simplified, no memory mapping or bank switching)
pub struct Memory {
    pages: [Page; NUM_PAGES],                   // currently CPU-visible pages
    layers: [[Page; NUM_PAGES]; NUM_LAYERS],    // currently mapped layers
    heap: [u8; HEAP_SIZE],                      // all available physical memory
}

impl Memory {

    /// return new, unmapped memory object
    pub fn new_unmapped() -> Memory {
        Memory {
            pages: [Page::new(); NUM_PAGES],
            layers: [[Page::new(); NUM_PAGES]; NUM_LAYERS],
            heap: [0; HEAP_SIZE]
        }
    }

    /// return new memory object with 64 kByte mapped, writable memory (for testing)
    pub fn new() -> Memory {
        let mut mem = Memory::new_unmapped();
        mem.map(0, 0, (1<<16), 0, true);
        mem
    }

    /// map a chunk of heap memory to CPU-mapped memory
    pub fn map(&mut self, layer: usize, heap_offset: usize, size: usize, addr: usize, writable: bool) {
        assert!((size & PAGE_MASK) == 0);
        assert!((addr & PAGE_MASK) == 0);
        let num = size >> PAGE_SHIFT;
        for i in 0..num {
            let map_offset = i * PAGE_SIZE;
            let page_index = ((addr + map_offset) & 0xFFFF) >> PAGE_SHIFT;
            let page = &mut self.layers[layer][page_index];
            page.map(heap_offset + map_offset, writable);
        }
        self.update_mapping();
    }

    /// unmap a chunk heap memory
    pub fn unmap(&mut self, layer: usize, size: usize, addr: usize) {
        assert!((size & PAGE_MASK) == 0);
        assert!((addr & PAGE_MASK) == 0);
        let num = size >> PAGE_SHIFT;
        for i in 0..num {
            let map_offset = i * PAGE_SIZE;
            let page_index = ((addr + map_offset) & 0xFFFF) >> PAGE_SHIFT;
            let page = &mut self.layers[layer][page_index];
            page.unmap();
        }
        self.update_mapping();
    }

    /// unmap all pages in a layer
    pub fn unmap_layer(&mut self, layer: usize) {
        for page in self.layers[layer].iter_mut() {
            page.unmap();
        }
        self.update_mapping();
    }

    /// unmap all pages in all layers
    pub fn umap_all(&mut self) {
        for layer in self.layers.iter_mut() {
            for page in layer.iter_mut() {
                page.unmap();
            }
        }
        self.update_mapping();
    }

    /// private method to update internal CPU-visible mapping from mapped layers
    fn update_mapping(&mut self) {
        // for each cpu-visible page, find the highest-priority layer
        // which maps this memory range and copy it into the
        // cpu-visible page
        for page_index in 0..NUM_PAGES {
            let mut layer_page: Option<&Page> = None;
            for layer_index in 0..NUM_LAYERS {
                if self.layers[layer_index][page_index].mapped {
                    layer_page = Some(&self.layers[layer_index][page_index]);
                    break;
                }
            }
            match layer_page {
                Some(page) => self.pages[page_index] = *page,
                None => self.pages[page_index].unmap()
            }
        }
    }

    /// read unsigned byte from 16-bit address
    #[inline(always)]
    pub fn r8(&self, addr: RegT) -> RegT {
        let uaddr = (addr & 0xFFFF) as usize;
        let page = &self.pages[uaddr >> PAGE_SHIFT];
        if page.mapped {
            let heap_offset = page.offset + (uaddr & PAGE_MASK);
            self.heap[heap_offset] as RegT
        }
        else {
            0xFF
        }
    }

    /// read signed byte from 16-bit address
    #[inline(always)]
    pub fn rs8(&self, addr: RegT) -> RegT {
        let uaddr = (addr & 0xFFFF) as usize;
        let page = &self.pages[uaddr >> PAGE_SHIFT];
        if page.mapped {
            let heap_offset = page.offset + (uaddr & PAGE_MASK);
            self.heap[heap_offset] as i8 as RegT
        }
        else {
            0xFF
        }
    }

    /// write unsigned byte to 16-bit address
    #[inline(always)]
    pub fn w8(&mut self, addr: RegT, val: RegT) {
        let uaddr = (addr & 0xFFFF) as usize;
        let page = &self.pages[uaddr >> PAGE_SHIFT];
        if page.mapped && page.writable {
            let heap_offset = page.offset + (uaddr & PAGE_MASK);
            self.heap[heap_offset] = val as u8;
        }
    }

    /// read unsigned word from 16-bit address
    #[inline(always)]
    pub fn r16(&self, addr: RegT) -> RegT {
        let l = self.r8(addr);
        let h = self.r8(addr + 1);
        h<<8 | l
    }

    /// write unsigned word to 16-bit address
    #[inline(always)]
    pub fn w16(&mut self, addr: RegT, val: RegT) {
        let l = val & 0xff;
        let h = (val >> 8) & 0xff;
        self.w8(addr, l);
        self.w8(addr + 1, h);
    }

    /// write a whole chunk of memory
    pub fn write(&mut self, addr: RegT, data: &[u8]) {
        let mut offset = 0;
        for b in data {
            self.w8(addr+offset, *b as RegT);
            offset += 1;
        }
    }
}

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

    #[test]
    fn mem_readwrite() {
        let mut mem = Memory::new();
        mem.w8(0x1234, 0x12);
        assert!(mem.r8(0x1234) == 0x12);

        mem.w8(0x2345, 0x32);
        assert!(mem.r8(0x2345) == 0x32);

        mem.w16(0x1000, 0x1234);
        assert!(mem.r16(0x1000) == 0x1234);
        assert!(mem.r8(0x1000) == 0x34);
        assert!(mem.r8(0x1001) == 0x12);

        mem.w16(0xFFFF, 0x2233);
        assert!(mem.r16(0xFFFF) == 0x2233);
        assert!(mem.r8(0xFFFF) == 0x33);
        assert!(mem.r8(0x0000) == 0x22);
    }
}
<|endoftext|>