<commit_before>use btls::server_keys::LocalKeyPair;
use btls::jose_jws::{sign_jws, JsonNode};
use std::convert::From;
use btls::error::KeyReadError;
use time::get_time;
use std::collections::BTreeMap;
use std::io::Read;

const SIG_ECDSA_SHA256: u16 = 0x0403;

pub struct ApnsToken {
    signature: Option<String>,
    issued_at: Option<i64>,
    key_id: String,
    team_id: String,
    secret: LocalKeyPair,
}

#[derive(Debug)]
pub enum ApnsTokenError {
    SignError,
    KeyParseError(String),
    KeyOpenError(String),
    KeyReadError(String),
    KeyGenerationError,
    KeyError,
}

impl From<KeyReadError> for ApnsTokenError {
    fn from(e: KeyReadError) -> ApnsTokenError {
        match e {
            KeyReadError::ParseError(e, _) => ApnsTokenError::KeyParseError(e),
            KeyReadError::OpenError(e, _) => ApnsTokenError::KeyOpenError(e),
            KeyReadError::ReadError(e, _) => ApnsTokenError::KeyReadError(e),
            KeyReadError::KeyGenerationFailed => ApnsTokenError::KeyGenerationError,
            _ => ApnsTokenError::KeyError,
        }
    }
}

impl ApnsToken {
    pub fn new<S: Into<String>, R: Read>(pk_der: &mut R, key_id: S, team_id: S) -> Result<ApnsToken, ApnsTokenError> {
        let mut token = ApnsToken {
            signature: None,
            issued_at: None,
            key_id: key_id.into(),
            team_id: team_id.into(),
            secret: LocalKeyPair::new(pk_der, "apns_private_key")?,
        };

        match token.renew() {
            Err(e) => Err(e),
            _ => Ok(token),
        }
    }

    pub fn signature(&self) -> String {
        match self.signature {
            Some(ref sig) => sig.to_string(),
            None => "".to_string()
        }
    }

    pub fn renew(&mut self) -> Result<(), ApnsTokenError> {
        let issued_at = get_time().sec;

        let mut headers: BTreeMap<String, JsonNode> = BTreeMap::new();
        headers.insert("alg".to_string(), JsonNode::String("ES256".to_string()));
        headers.insert("kid".to_string(), JsonNode::String(self.key_id.to_string()));

        let mut payload: BTreeMap<String, JsonNode> = BTreeMap::new();
        payload.insert("iss".to_string(), JsonNode::String(self.team_id.to_string()));
        payload.insert("iat".to_string(), JsonNode::Number(issued_at));

        let jwt_headers = JsonNode::Dictionary(headers);
        let jwt_payload = JsonNode::Dictionary(payload).serialize();

        match sign_jws(&jwt_headers, jwt_payload.as_bytes(), &self.secret, SIG_ECDSA_SHA256).read() {
            Ok(Ok(token)) => {
                self.signature = Some(token.to_compact());
                self.issued_at = Some(issued_at);
                Ok(())
            }
            _ => Err(ApnsTokenError::SignError)
        }
    }

    pub fn is_expired(&self) -> bool {
        if let Some(issued_at) = self.issued_at {
            (get_time().sec - issued_at) > 3600
        } else {
            true
        }
    }
}
<commit_msg>Cosmetic stuff<commit_after>use btls::server_keys::LocalKeyPair;
use btls::jose_jws::{sign_jws, JsonNode};
use std::convert::From;
use btls::error::KeyReadError;
use time::get_time;
use std::collections::BTreeMap;
use std::io::Read;

const SIG_ECDSA_SHA256: u16 = 0x0403;

pub struct ApnsToken {
    signature: Option<String>,
    issued_at: Option<i64>,
    key_id: String,
    team_id: String,
    secret: LocalKeyPair,
}

#[derive(Debug)]
pub enum ApnsTokenError {
    SignError,
    KeyParseError(String),
    KeyOpenError(String),
    KeyReadError(String),
    KeyGenerationError,
    KeyError,
}

impl From<KeyReadError> for ApnsTokenError {
    fn from(e: KeyReadError) -> ApnsTokenError {
        match e {
            KeyReadError::ParseError(e, _) => ApnsTokenError::KeyParseError(e),
            KeyReadError::OpenError(e, _) => ApnsTokenError::KeyOpenError(e),
            KeyReadError::ReadError(e, _) => ApnsTokenError::KeyReadError(e),
            KeyReadError::KeyGenerationFailed => ApnsTokenError::KeyGenerationError,
            _ => ApnsTokenError::KeyError,
        }
    }
}

impl ApnsToken {
    pub fn new<S,R>(pk_der: &mut R, key_id: S, team_id: S) -> Result<ApnsToken, ApnsTokenError>
        where S: Into<String>, R: Read {

        let mut token = ApnsToken {
            signature: None,
            issued_at: None,
            key_id: key_id.into(),
            team_id: team_id.into(),
            secret: LocalKeyPair::new(pk_der, "apns_private_key")?,
        };

        match token.renew() {
            Err(e) => Err(e),
            _ => Ok(token),
        }
    }

    pub fn signature(&self) -> String {
        match self.signature {
            Some(ref sig) => sig.to_string(),
            None => "".to_string()
        }
    }

    pub fn renew(&mut self) -> Result<(), ApnsTokenError> {
        let issued_at = get_time().sec;

        let mut headers: BTreeMap<String, JsonNode> = BTreeMap::new();
        headers.insert("alg".to_string(), JsonNode::String("ES256".to_string()));
        headers.insert("kid".to_string(), JsonNode::String(self.key_id.to_string()));

        let mut payload: BTreeMap<String, JsonNode> = BTreeMap::new();
        payload.insert("iss".to_string(), JsonNode::String(self.team_id.to_string()));
        payload.insert("iat".to_string(), JsonNode::Number(issued_at));

        let jwt_headers = JsonNode::Dictionary(headers);
        let jwt_payload = JsonNode::Dictionary(payload).serialize();

        match sign_jws(&jwt_headers, jwt_payload.as_bytes(), &self.secret, SIG_ECDSA_SHA256).read() {
            Ok(Ok(token)) => {
                self.signature = Some(token.to_compact());
                self.issued_at = Some(issued_at);
                Ok(())
            }
            _ => Err(ApnsTokenError::SignError)
        }
    }

    pub fn is_expired(&self) -> bool {
        if let Some(issued_at) = self.issued_at {
            (get_time().sec - issued_at) > 3600
        } else {
            true
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 `multipart-async` Crate Developers
//
// 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.
//! The server-side abstraction for multipart requests. Enabled with the `server` feature (on by
//! default).
//!
//! Use this when you are implementing an HTTP server and want to
//! to accept, parse, and serve HTTP `multipart/form-data` requests (file uploads).
//!
//! See the `Multipart` struct for more info.
use futures::task::{self, Context};
use futures::{Future, Poll, Stream};

use std::cell::Cell;
use std::rc::Rc;

use self::boundary::BoundaryFinder;

use crate::{BodyChunk, StreamError};

macro_rules! try_opt (
    ($expr:expr) => (
        match $expr {
            Some(val) => val,
            None => return None,
        }
    )
);

macro_rules! ret_err (
    ($($args:tt)+) => (
            return fmt_err!($($args)+);
    )
);

macro_rules! fmt_err(
    ($string:expr) => (
        crate::helpers::error($string)
    );
    ($string:expr, $($args:tt)*) => (
        crate::helpers::error(format!($string, $($args)*))
    );
);

macro_rules! debug_panic(
    ($($args:tt)*) => {
        if cfg!(debug_assertions) {
            panic!($($args)*)
        } else {
            warn!($($args)*)
        }
    }
);

mod boundary;
mod field;

use crate::helpers::*;

use self::field::ReadHeaders;

pub use self::field::{Field, FieldData, FieldHeaders};
// pub use self::field::{ReadTextField, TextField};

#[cfg(feature = "hyper")]
mod hyper;

#[cfg(feature = "hyper")]
pub use self::hyper::{MinusBody, MultipartService};
use std::pin::Pin;

#[cfg(any(test, feature = "fuzzing"))]
pub(crate) mod fuzzing {
    pub(crate) use super::boundary::BoundaryFinder;
    pub(crate) use super::field::ReadHeaders;
}

/// The server-side implementation of `multipart/form-data` requests.
pub struct Multipart<S: TryStream> {
    inner: PushChunk<BoundaryFinder<S>, S::Ok>,
    read_hdr: ReadHeaders,
    consumed: bool,
}

// Q: why can't we just wrap up these bounds into a trait?
// A: https://github.com/rust-lang/rust/issues/24616#issuecomment-112065997
// (The workaround mentioned in a later comment doesn't seem to be worth the added complexity)
impl<S> Multipart<S>
where
    S: TryStream,
    S::Ok: BodyChunk,
    S::Error: StreamError,
{
    unsafe_pinned!(inner: PushChunk<BoundaryFinder<S>, S::Ok>);
    unsafe_unpinned!(read_hdr: ReadHeaders);
    unsafe_unpinned!(consumed: bool);

    /// Construct a new `Multipart` with the given body reader and boundary.
    ///
    /// This will add the requisite `--` and CRLF (`\r\n`) to the boundary as per
    /// [IETF RFC 7578 section 4.1](https://tools.ietf.org/html/rfc7578#section-4.1).
    pub fn with_body<B: Into<String>>(stream: S, boundary: B) -> Self {
        let mut boundary = boundary.into();
        boundary.insert_str(0, "--");

        debug!("Boundary: {}", boundary);

        Multipart {
            inner: PushChunk::new(BoundaryFinder::new(stream, boundary)),
            read_hdr: ReadHeaders::default(),
            consumed: false,
        }
    }

    pub fn poll_has_next_field(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
    ) -> Poll<Result<bool, S::Error>> {
        self.as_mut().inner().stream().consume_boundary(cx)
    }

    pub fn poll_field_headers(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
    ) -> PollOpt<FieldHeaders, S::Error> {
        unsafe {
            let this = self.as_mut().get_unchecked_mut();
            this.read_hdr
                .read_headers(Pin::new_unchecked(&mut this.inner), cx)
        }
    }

    pub fn poll_body_chunk(self: Pin<&mut Self>, cx: &mut Context) -> PollOpt<S::Ok, S::Error> {
        if !self.read_hdr.is_reading_headers() {
            self.inner().poll_next(cx)
        } else {
            Poll::Ready(None)
        }
    }
}

/// An extension trait for requests which may be multipart.
pub trait RequestExt: Sized {
    /// The success type, may contain `Multipart` or something else.
    type Multipart;

    /// Convert `Self` into `Self::Multipart` if applicable.
    fn into_multipart(self) -> Result<Self::Multipart, Self>;
}

/// Struct wrapping a stream which allows a chunk to be pushed back to it to be yielded next.
pub(crate) struct PushChunk<S, T> {
    stream: S,
    pushed: Option<T>,
}

impl<S, T> PushChunk<S, T> {
    unsafe_pinned!(stream: S);
    unsafe_unpinned!(pushed: Option<T>);

    pub(crate) fn new(stream: S) -> Self {
        PushChunk {
            stream,
            pushed: None,
        }
    }
}

impl<S: TryStream> PushChunk<S, S::Ok> where S::Ok: BodyChunk {
    fn push_chunk(mut self: Pin<&mut Self>, chunk: S::Ok) {
        if let Some(pushed) = self.as_mut().pushed() {
            debug_panic!(
                "pushing excess chunk: \"{}\" already pushed chunk: \"{}\"",
                show_bytes(chunk.as_slice()),
                show_bytes(pushed.as_slice())
            );
        }

        debug_assert!(!chunk.is_empty(), "pushing empty chunk");

        *self.as_mut().pushed() = Some(chunk);
    }
}

impl<S: TryStream> Stream for PushChunk<S, S::Ok> {
    type Item = Result<S::Ok, S::Error>;

    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
        if let Some(pushed) = self.as_mut().pushed().take() {
            return Poll::Ready(Some(Ok(pushed)));
        }

        self.stream().try_poll_next(cx)
    }
}

#[cfg(test)]
mod test {
    use futures::prelude::*;
    use super::Multipart;
    use crate::test_util::mock_stream;
    use crate::server::FieldHeaders;

    const BOUNDARY: &str = "boundary";

    #[test]
    fn test_empty_body() {
        let _ = ::env_logger::try_init();
        let multipart = Multipart::with_body(
            mock_stream(&[]),
            BOUNDARY
        );
        pin_mut!(multipart);
        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(false));
    }

    #[test]
    fn test_no_headers() {
        let _ = ::env_logger::try_init();
        let multipart = Multipart::with_body(
            mock_stream(&[b"--boundary", b"\r\n", b"\r\n", b"--boundary--"]),
            BOUNDARY
        );
        pin_mut!(multipart);
        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(false));
    }

    #[test]
    fn test_single_field() {
        let _ = ::env_logger::try_init();
        let multipart = Multipart::with_body(
            mock_stream(&[
                b"--boundary\r", b"\n",
                b"Content-Disposition:",
                b" form-data; name=",
                b"\"foo\"",
                b"\r\n\r\n",
                b"field data",
                b"\r", b"\n--boundary--"
            ]),
            BOUNDARY
        );
        pin_mut!(multipart);

        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(true));

        ready_assert_eq!(
            |cx| multipart.as_mut().poll_field_headers(cx),
            Some(Ok(FieldHeaders {
                name: "foo".into(),
                filename: None,
                content_type: None,
                ext_headers: Default::default(),
                _backcompat: (),
            }))
        );

        ready_assert_eq!(
            |cx| multipart.as_mut().poll_body_chunk(cx),
            Some(Ok(&b"field data"[..]))
        );

        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(false));
    }
}
<commit_msg>fix server::test_no_headers<commit_after>// Copyright 2017 `multipart-async` Crate Developers
//
// 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.
//! The server-side abstraction for multipart requests. Enabled with the `server` feature (on by
//! default).
//!
//! Use this when you are implementing an HTTP server and want to
//! to accept, parse, and serve HTTP `multipart/form-data` requests (file uploads).
//!
//! See the `Multipart` struct for more info.
use futures::task::{self, Context};
use futures::{Future, Poll, Stream};

use std::cell::Cell;
use std::rc::Rc;

use self::boundary::BoundaryFinder;

use crate::{BodyChunk, StreamError};

macro_rules! try_opt (
    ($expr:expr) => (
        match $expr {
            Some(val) => val,
            None => return None,
        }
    )
);

macro_rules! ret_err (
    ($($args:tt)+) => (
            return fmt_err!($($args)+);
    )
);

macro_rules! fmt_err(
    ($string:expr) => (
        crate::helpers::error($string)
    );
    ($string:expr, $($args:tt)*) => (
        crate::helpers::error(format!($string, $($args)*))
    );
);

macro_rules! debug_panic(
    ($($args:tt)*) => {
        if cfg!(debug_assertions) {
            panic!($($args)*)
        } else {
            warn!($($args)*)
        }
    }
);

mod boundary;
mod field;

use crate::helpers::*;

use self::field::ReadHeaders;

pub use self::field::{Field, FieldData, FieldHeaders};
// pub use self::field::{ReadTextField, TextField};

#[cfg(feature = "hyper")]
mod hyper;

#[cfg(feature = "hyper")]
pub use self::hyper::{MinusBody, MultipartService};
use std::pin::Pin;

#[cfg(any(test, feature = "fuzzing"))]
pub(crate) mod fuzzing {
    pub(crate) use super::boundary::BoundaryFinder;
    pub(crate) use super::field::ReadHeaders;
}

/// The server-side implementation of `multipart/form-data` requests.
pub struct Multipart<S: TryStream> {
    inner: PushChunk<BoundaryFinder<S>, S::Ok>,
    read_hdr: ReadHeaders,
    consumed: bool,
}

// Q: why can't we just wrap up these bounds into a trait?
// A: https://github.com/rust-lang/rust/issues/24616#issuecomment-112065997
// (The workaround mentioned in a later comment doesn't seem to be worth the added complexity)
impl<S> Multipart<S>
where
    S: TryStream,
    S::Ok: BodyChunk,
    S::Error: StreamError,
{
    unsafe_pinned!(inner: PushChunk<BoundaryFinder<S>, S::Ok>);
    unsafe_unpinned!(read_hdr: ReadHeaders);
    unsafe_unpinned!(consumed: bool);

    /// Construct a new `Multipart` with the given body reader and boundary.
    ///
    /// This will add the requisite `--` and CRLF (`\r\n`) to the boundary as per
    /// [IETF RFC 7578 section 4.1](https://tools.ietf.org/html/rfc7578#section-4.1).
    pub fn with_body<B: Into<String>>(stream: S, boundary: B) -> Self {
        let mut boundary = boundary.into();
        boundary.insert_str(0, "--");

        debug!("Boundary: {}", boundary);

        Multipart {
            inner: PushChunk::new(BoundaryFinder::new(stream, boundary)),
            read_hdr: ReadHeaders::default(),
            consumed: false,
        }
    }

    pub fn poll_has_next_field(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
    ) -> Poll<Result<bool, S::Error>> {
        self.as_mut().inner().stream().consume_boundary(cx)
    }

    pub fn poll_field_headers(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
    ) -> PollOpt<FieldHeaders, S::Error> {
        unsafe {
            let this = self.as_mut().get_unchecked_mut();
            this.read_hdr
                .read_headers(Pin::new_unchecked(&mut this.inner), cx)
        }
    }

    pub fn poll_body_chunk(self: Pin<&mut Self>, cx: &mut Context) -> PollOpt<S::Ok, S::Error> {
        if !self.read_hdr.is_reading_headers() {
            self.inner().poll_next(cx)
        } else {
            Poll::Ready(None)
        }
    }
}

/// An extension trait for requests which may be multipart.
pub trait RequestExt: Sized {
    /// The success type, may contain `Multipart` or something else.
    type Multipart;

    /// Convert `Self` into `Self::Multipart` if applicable.
    fn into_multipart(self) -> Result<Self::Multipart, Self>;
}

/// Struct wrapping a stream which allows a chunk to be pushed back to it to be yielded next.
pub(crate) struct PushChunk<S, T> {
    stream: S,
    pushed: Option<T>,
}

impl<S, T> PushChunk<S, T> {
    unsafe_pinned!(stream: S);
    unsafe_unpinned!(pushed: Option<T>);

    pub(crate) fn new(stream: S) -> Self {
        PushChunk {
            stream,
            pushed: None,
        }
    }
}

impl<S: TryStream> PushChunk<S, S::Ok> where S::Ok: BodyChunk {
    fn push_chunk(mut self: Pin<&mut Self>, chunk: S::Ok) {
        if let Some(pushed) = self.as_mut().pushed() {
            debug_panic!(
                "pushing excess chunk: \"{}\" already pushed chunk: \"{}\"",
                show_bytes(chunk.as_slice()),
                show_bytes(pushed.as_slice())
            );
        }

        debug_assert!(!chunk.is_empty(), "pushing empty chunk");

        *self.as_mut().pushed() = Some(chunk);
    }
}

impl<S: TryStream> Stream for PushChunk<S, S::Ok> {
    type Item = Result<S::Ok, S::Error>;

    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
        if let Some(pushed) = self.as_mut().pushed().take() {
            return Poll::Ready(Some(Ok(pushed)));
        }

        self.stream().try_poll_next(cx)
    }
}

#[cfg(test)]
mod test {
    use futures::prelude::*;
    use super::Multipart;
    use crate::test_util::mock_stream;
    use crate::server::FieldHeaders;

    const BOUNDARY: &str = "boundary";

    #[test]
    fn test_empty_body() {
        let _ = ::env_logger::try_init();
        let multipart = Multipart::with_body(
            mock_stream(&[]),
            BOUNDARY
        );
        pin_mut!(multipart);
        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(false));
    }

    #[test]
    fn test_no_headers() {
        let _ = ::env_logger::try_init();
        let multipart = Multipart::with_body(
            mock_stream(&[b"--boundary", b"\r\n", b"\r\n", b"--boundary--"]),
            BOUNDARY
        );
        pin_mut!(multipart);
        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(true));
        ready_assert_eq!(|cx| multipart.as_mut().poll_field_headers(cx), None);
        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(false));
    }

    #[test]
    fn test_single_field() {
        let _ = ::env_logger::try_init();
        let multipart = Multipart::with_body(
            mock_stream(&[
                b"--boundary\r", b"\n",
                b"Content-Disposition:",
                b" form-data; name=",
                b"\"foo\"",
                b"\r\n\r\n",
                b"field data",
                b"\r", b"\n--boundary--"
            ]),
            BOUNDARY
        );
        pin_mut!(multipart);

        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(true));

        ready_assert_eq!(
            |cx| multipart.as_mut().poll_field_headers(cx),
            Some(Ok(FieldHeaders {
                name: "foo".into(),
                filename: None,
                content_type: None,
                ext_headers: Default::default(),
                _backcompat: (),
            }))
        );

        ready_assert_eq!(
            |cx| multipart.as_mut().poll_body_chunk(cx),
            Some(Ok(&b"field data"[..]))
        );

        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(false));
    }
}
<|endoftext|>


<commit_before>mod store;
mod paxos;
mod server;
mod connset;
mod server_conn;
mod traffic_cop;

pub use server::server::Server;
pub use server::connset::ConnSet;
pub use server::server_conn::ServerConn;

use std::io::{Error, ErrorKind};
use std::io;
use std::net::SocketAddr;
use std::ops::{Add, Sub};
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{self, Sender, Receiver};
use std::thread;
use std::usize;

use bytes::{alloc, Buf, ByteBuf, MutByteBuf, SliceBuf};
use mio;
use mio::{EventLoop, EventSet, PollOpt, Handler, Token, TryWrite, TryRead};
use mio::tcp::{TcpListener, TcpStream, TcpSocket};
use mio::util::Slab;
use rand::{Rng, thread_rng};
use protobuf;
use protobuf::Message;

use time;

pub const SERVER_CLIENTS: Token = Token(0);
pub const SERVER_PEERS: Token = Token(1);
pub const PEER_BROADCAST: Token = Token(usize::MAX);

lazy_static! {
    pub static ref LEADER_DURATION: time::Duration = time::Duration::seconds(12);
    pub static ref LEADER_REFRESH: time::Duration = time::Duration::seconds(6);
}

pub struct Envelope {
    id: u64,
    tok: Token,
    msg: ByteBuf,
}

pub struct Peer {
    addr: SocketAddr,
    sock: Option<Token>,
}

#[derive(Debug)]
enum State {
    Leader {
        attempt: u64,
        have: Vec<Token>,
        need: u8,
        until: time::Timespec,
    },
    Candidate {
        attempt: u64,
        have: Vec<Token>,
        need: u8,
        until: time::Timespec,
    },
    Follower {
        attempt: u64,
        id: u64,
        tok: Token,
        until: time::Timespec,
    },
    Init,
}

impl State {
    fn valid_leader(&self) -> bool {
        match *self {
            State::Leader{attempt:_, have:_, need:_, until: until} =>
                time::now().to_timespec() < until,
            State::Follower{attempt:_, id:_, until: until, tok: _} =>
                time::now().to_timespec() < until,
            _ => false,
        }
    }

    fn valid_candidate(&self) -> bool {
        match *self {
            State::Candidate{attempt:_, until: until, have:_, need:_} =>
                time::now().to_timespec() < until,
            _ => false,
        }
    }

    fn is_leader(&self) -> bool {
        match *self {
            State::Leader{attempt:_, have:_, need:_, until:_} =>
                true,
            _ => false,
        }
    }

    fn is_candidate(&self) -> bool {
        match *self {
            State::Candidate{attempt:_, have:_, need:_, until:_} =>
                true,
            _ => false,
        }
    }

    fn should_extend_leadership(&self) -> bool {
        match *self {
            State::Leader{attempt:_, have:_, need:_, until: until} => {
                let now = time::now().to_timespec();
                let r =
                    now.add(*LEADER_REFRESH) >= until &&
                    now < until;
                info!("should_extend_leadership: {}", r);
                r
            },
            _ => false,
        }
    }

    fn can_extend_lead(&self) -> bool {
        match *self {
            State::Candidate{attempt:_, until:_, have: ref have, need: need} =>
                have.len() > need as usize,
            State::Leader{attempt:_, have: ref have, need: need, until:_} =>
                have.len() > need as usize,
            _ =>
                false,
        }
    }

    fn following(&self, id: u64) -> bool {
        match *self {
            State::Follower{attempt:_, id: fid, until: until, tok: _} =>
                id == fid,
            _ => false,
        }
    }

    fn until(&self) -> Option<time::Timespec> {
        match *self {
            State::Leader{attempt:_, have:_, need:_, until: until} =>
                Some(until),
            State::Candidate{attempt:_, until: until, have: _, need: _} =>
                Some(until),
            State::Follower{attempt:_, id:_, until: until, tok: _} =>
                Some(until),
            _ => None,
        }
    }

    fn attempt(&self) -> Option<u64> {
        match *self {
            State::Leader{attempt: attempt, have:_, need:_, until: _} =>
                Some(attempt),
            State::Candidate{attempt: attempt, until:_, have: _, need: _} =>
                Some(attempt),
            State::Follower{attempt: attempt, id:_, until: _, tok: _} =>
                Some(attempt),
            _ => None,
        }
    }
}

<commit_msg>small cleanup<commit_after>mod store;
mod paxos;
mod server;
mod connset;
mod server_conn;
mod traffic_cop;

pub use server::server::Server;
pub use server::connset::ConnSet;
pub use server::server_conn::ServerConn;

use std::io::{Error, ErrorKind};
use std::io;
use std::net::SocketAddr;
use std::ops::{Add, Sub};
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{self, Sender, Receiver};
use std::thread;
use std::usize;

use bytes::{alloc, Buf, ByteBuf, MutByteBuf, SliceBuf};
use mio;
use mio::{EventLoop, EventSet, PollOpt, Handler, Token, TryWrite, TryRead};
use mio::tcp::{TcpListener, TcpStream, TcpSocket};
use mio::util::Slab;
use rand::{Rng, thread_rng};
use protobuf;
use protobuf::Message;

use time;

pub const SERVER_CLIENTS: Token = Token(0);
pub const SERVER_PEERS: Token = Token(1);
pub const PEER_BROADCAST: Token = Token(usize::MAX);

lazy_static! {
    pub static ref LEADER_DURATION: time::Duration = time::Duration::seconds(12);
    pub static ref LEADER_REFRESH: time::Duration = time::Duration::seconds(6);
}

pub struct Envelope {
    id: u64,
    tok: Token,
    msg: ByteBuf,
}

pub struct Peer {
    addr: SocketAddr,
    sock: Option<Token>,
}

#[derive(Debug)]
enum State {
    Leader {
        attempt: u64,
        have: Vec<Token>,
        need: u8,
        until: time::Timespec,
    },
    Candidate {
        attempt: u64,
        have: Vec<Token>,
        need: u8,
        until: time::Timespec,
    },
    Follower {
        attempt: u64,
        id: u64,
        tok: Token,
        until: time::Timespec,
    },
    Init,
}

impl State {
    fn valid_leader(&self) -> bool {
        match *self {
            State::Leader{attempt:_, have:_, need:_, until: until} =>
                time::now().to_timespec() < until,
            State::Follower{attempt:_, id:_, until: until, tok: _} =>
                time::now().to_timespec() < until,
            _ => false,
        }
    }

    fn valid_candidate(&self) -> bool {
        match *self {
            State::Candidate{attempt:_, until: until, have:_, need:_} =>
                time::now().to_timespec() < until,
            _ => false,
        }
    }

    fn is_leader(&self) -> bool {
        match *self {
            State::Leader{attempt:_, have:_, need:_, until:_} =>
                true,
            _ => false,
        }
    }

    fn is_candidate(&self) -> bool {
        match *self {
            State::Candidate{attempt:_, have:_, need:_, until:_} =>
                true,
            _ => false,
        }
    }

    fn should_extend_leadership(&self) -> bool {
        match *self {
            State::Leader{attempt:_, have:_, need:_, until: until} => {
                let now = time::now().to_timespec();
                now.add(*LEADER_REFRESH) >= until && now < until
            },
            _ => false,
        }
    }

    fn can_extend_lead(&self) -> bool {
        match *self {
            State::Candidate{attempt:_, until:_, have: ref have, need: need} =>
                have.len() > need as usize,
            State::Leader{attempt:_, have: ref have, need: need, until:_} =>
                have.len() > need as usize,
            _ =>
                false,
        }
    }

    fn following(&self, id: u64) -> bool {
        match *self {
            State::Follower{attempt:_, id: fid, until: until, tok: _} =>
                id == fid,
            _ => false,
        }
    }

    fn until(&self) -> Option<time::Timespec> {
        match *self {
            State::Leader{attempt:_, have:_, need:_, until: until} =>
                Some(until),
            State::Candidate{attempt:_, until: until, have: _, need: _} =>
                Some(until),
            State::Follower{attempt:_, id:_, until: until, tok: _} =>
                Some(until),
            _ => None,
        }
    }

    fn attempt(&self) -> Option<u64> {
        match *self {
            State::Leader{attempt: attempt, have:_, need:_, until: _} =>
                Some(attempt),
            State::Candidate{attempt: attempt, until:_, have: _, need: _} =>
                Some(attempt),
            State::Follower{attempt: attempt, id:_, until: _, tok: _} =>
                Some(attempt),
            _ => None,
        }
    }
}

<|endoftext|>


<commit_before>// Copyright 2017 `multipart-async` Crate Developers
//
// 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.
//! The server-side abstraction for multipart requests. Enabled with the `server` feature (on by
//! default).
//!
//! Use this when you are implementing an HTTP server and want to
//! to accept, parse, and serve HTTP `multipart/form-data` requests (file uploads).
//!
//! See the `Multipart` struct for more info.
use futures::task::{self, Context};
use futures::{Future, Poll, Stream};

use std::cell::Cell;
use std::rc::Rc;

use self::boundary::BoundaryFinder;

use crate::{BodyChunk, StreamError};

macro_rules! try_opt (
    ($expr:expr) => (
        match $expr {
            Some(val) => val,
            None => return None,
        }
    )
);

macro_rules! ret_err (
    ($($args:tt)+) => (
            return fmt_err!($($args)+);
    )
);

macro_rules! fmt_err(
    ($string:expr) => (
        crate::helpers::error($string)
    );
    ($string:expr, $($args:tt)*) => (
        crate::helpers::error(format!($string, $($args)*))
    );
);

macro_rules! debug_panic(
    ($($args:tt)*) => {
        if cfg!(debug_assertions) {
            panic!($($args)*)
        } else {
            warn!($($args)*)
        }
    }
);

mod boundary;
mod field;

use crate::helpers::*;

use self::field::ReadHeaders;

pub use self::field::{Field, FieldData, FieldHeaders};
// pub use self::field::{ReadTextField, TextField};

#[cfg(feature = "hyper")]
mod hyper;

#[cfg(feature = "hyper")]
pub use self::hyper::{MinusBody, MultipartService};
use std::pin::Pin;

#[cfg(any(test, feature = "fuzzing"))]
pub(crate) mod fuzzing {
    pub(crate) use super::boundary::BoundaryFinder;
    pub(crate) use super::field::ReadHeaders;
}

/// The server-side implementation of `multipart/form-data` requests.
pub struct Multipart<S: TryStream> {
    inner: PushChunk<BoundaryFinder<S>, S::Ok>,
    read_hdr: ReadHeaders,
    consumed: bool,
}

// Q: why can't we just wrap up these bounds into a trait?
// A: https://github.com/rust-lang/rust/issues/24616#issuecomment-112065997
// (The workaround mentioned in a later comment doesn't seem to be worth the added complexity)
impl<S> Multipart<S>
where
    S: TryStream,
    S::Ok: BodyChunk,
    S::Error: StreamError,
{
    unsafe_pinned!(inner: PushChunk<BoundaryFinder<S>, S::Ok>);
    unsafe_unpinned!(read_hdr: ReadHeaders);
    unsafe_unpinned!(consumed: bool);

    /// Construct a new `Multipart` with the given body reader and boundary.
    ///
    /// This will add the requisite `--` and CRLF (`\r\n`) to the boundary as per
    /// [IETF RFC 7578 section 4.1](https://tools.ietf.org/html/rfc7578#section-4.1).
    pub fn with_body<B: Into<String>>(stream: S, boundary: B) -> Self {
        let mut boundary = boundary.into();
        boundary.insert_str(0, "--");

        debug!("Boundary: {}", boundary);

        Multipart {
            inner: PushChunk::new(BoundaryFinder::new(stream, boundary)),
            read_hdr: ReadHeaders::default(),
            consumed: false,
        }
    }

    pub fn poll_has_next_field(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
    ) -> Poll<Result<bool, S::Error>> {
        self.as_mut().inner().stream().consume_boundary(cx)
    }

    pub fn poll_field_headers(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
    ) -> PollOpt<FieldHeaders, S::Error> {
        unsafe {
            let this = self.as_mut().get_unchecked_mut();
            this.read_hdr
                .read_headers(Pin::new_unchecked(&mut this.inner), cx)
        }
    }

    pub fn poll_body_chunk(self: Pin<&mut Self>, cx: &mut Context) -> PollOpt<S::Ok, S::Error> {
        if !self.read_hdr.is_reading_headers() {
            self.inner().poll_next(cx)
        } else {
            Poll::Ready(None)
        }
    }
}

/// An extension trait for requests which may be multipart.
pub trait RequestExt: Sized {
    /// The success type, may contain `Multipart` or something else.
    type Multipart;

    /// Convert `Self` into `Self::Multipart` if applicable.
    fn into_multipart(self) -> Result<Self::Multipart, Self>;
}

/// Struct wrapping a stream which allows a chunk to be pushed back to it to be yielded next.
pub(crate) struct PushChunk<S, T> {
    stream: S,
    pushed: Option<T>,
}

impl<S, T> PushChunk<S, T> {
    unsafe_pinned!(stream: S);
    unsafe_unpinned!(pushed: Option<T>);

    pub(crate) fn new(stream: S) -> Self {
        PushChunk {
            stream,
            pushed: None,
        }
    }
}

impl<S: TryStream> PushChunk<S, S::Ok> where S::Ok: BodyChunk {
    fn push_chunk(mut self: Pin<&mut Self>, chunk: S::Ok) {
        if let Some(pushed) = self.as_mut().pushed() {
            debug_panic!(
                "pushing excess chunk: \"{}\" already pushed chunk: \"{}\"",
                show_bytes(chunk.as_slice()),
                show_bytes(pushed.as_slice())
            );
        }

        debug_assert!(!chunk.is_empty(), "pushing empty chunk");

        *self.as_mut().pushed() = Some(chunk);
    }
}

impl<S: TryStream> Stream for PushChunk<S, S::Ok> {
    type Item = Result<S::Ok, S::Error>;

    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
        if let Some(pushed) = self.as_mut().pushed().take() {
            return Poll::Ready(Some(Ok(pushed)));
        }

        self.stream().try_poll_next(cx)
    }
}

#[cfg(test)]
mod test {
    use futures::prelude::*;
    use super::Multipart;
    use crate::test_util::mock_stream;
    use crate::server::FieldHeaders;

    const BOUNDARY: &str = "boundary";

    #[test]
    fn test_empty_body() {
        let _ = ::env_logger::try_init();
        let multipart = Multipart::with_body(
            mock_stream(&[]),
            BOUNDARY
        );
        pin_mut!(multipart);
        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(false));
    }

    #[test]
    fn test_no_headers() {
        let _ = ::env_logger::try_init();
        let multipart = Multipart::with_body(
            mock_stream(&[b"--boundary", b"\r\n", b"\r\n", b"--boundary--"]),
            BOUNDARY
        );
        pin_mut!(multipart);
        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(true));
        ready_assert_eq!(|cx| multipart.as_mut().poll_field_headers(cx), None);
        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(false));
    }

    #[test]
    fn test_single_field() {
        let _ = ::env_logger::try_init();
        let multipart = Multipart::with_body(
            mock_stream(&[
                b"--boundary\r", b"\n",
                b"Content-Disposition:",
                b" form-data; name=",
                b"\"foo\"",
                b"\r\n\r\n",
                b"field data",
                b"\r", b"\n--boundary--"
            ]),
            BOUNDARY
        );
        pin_mut!(multipart);

        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(true));

        ready_assert_eq!(
            |cx| multipart.as_mut().poll_field_headers(cx),
            Some(Ok(FieldHeaders {
                name: "foo".into(),
                filename: None,
                content_type: None,
                ext_headers: Default::default(),
                _backcompat: (),
            }))
        );

        ready_assert_eq!(
            |cx| multipart.as_mut().poll_body_chunk(cx),
            Some(Ok(&b"field data"[..]))
        );

        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(false));
    }
}
<commit_msg>add server::test_two_fields<commit_after>// Copyright 2017 `multipart-async` Crate Developers
//
// 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.
//! The server-side abstraction for multipart requests. Enabled with the `server` feature (on by
//! default).
//!
//! Use this when you are implementing an HTTP server and want to
//! to accept, parse, and serve HTTP `multipart/form-data` requests (file uploads).
//!
//! See the `Multipart` struct for more info.
use futures::task::{self, Context};
use futures::{Future, Poll, Stream};

use std::cell::Cell;
use std::rc::Rc;

use self::boundary::BoundaryFinder;

use crate::{BodyChunk, StreamError};

macro_rules! try_opt (
    ($expr:expr) => (
        match $expr {
            Some(val) => val,
            None => return None,
        }
    )
);

macro_rules! ret_err (
    ($($args:tt)+) => (
            return fmt_err!($($args)+);
    )
);

macro_rules! fmt_err(
    ($string:expr) => (
        crate::helpers::error($string)
    );
    ($string:expr, $($args:tt)*) => (
        crate::helpers::error(format!($string, $($args)*))
    );
);

macro_rules! debug_panic(
    ($($args:tt)*) => {
        if cfg!(debug_assertions) {
            panic!($($args)*)
        } else {
            warn!($($args)*)
        }
    }
);

mod boundary;
mod field;

use crate::helpers::*;

use self::field::ReadHeaders;

pub use self::field::{Field, FieldData, FieldHeaders};
// pub use self::field::{ReadTextField, TextField};

#[cfg(feature = "hyper")]
mod hyper;

#[cfg(feature = "hyper")]
pub use self::hyper::{MinusBody, MultipartService};
use std::pin::Pin;

#[cfg(any(test, feature = "fuzzing"))]
pub(crate) mod fuzzing {
    pub(crate) use super::boundary::BoundaryFinder;
    pub(crate) use super::field::ReadHeaders;
}

/// The server-side implementation of `multipart/form-data` requests.
pub struct Multipart<S: TryStream> {
    inner: PushChunk<BoundaryFinder<S>, S::Ok>,
    read_hdr: ReadHeaders,
    consumed: bool,
}

// Q: why can't we just wrap up these bounds into a trait?
// A: https://github.com/rust-lang/rust/issues/24616#issuecomment-112065997
// (The workaround mentioned in a later comment doesn't seem to be worth the added complexity)
impl<S> Multipart<S>
where
    S: TryStream,
    S::Ok: BodyChunk,
    S::Error: StreamError,
{
    unsafe_pinned!(inner: PushChunk<BoundaryFinder<S>, S::Ok>);
    unsafe_unpinned!(read_hdr: ReadHeaders);
    unsafe_unpinned!(consumed: bool);

    /// Construct a new `Multipart` with the given body reader and boundary.
    ///
    /// This will add the requisite `--` and CRLF (`\r\n`) to the boundary as per
    /// [IETF RFC 7578 section 4.1](https://tools.ietf.org/html/rfc7578#section-4.1).
    pub fn with_body<B: Into<String>>(stream: S, boundary: B) -> Self {
        let mut boundary = boundary.into();
        boundary.insert_str(0, "--");

        debug!("Boundary: {}", boundary);

        Multipart {
            inner: PushChunk::new(BoundaryFinder::new(stream, boundary)),
            read_hdr: ReadHeaders::default(),
            consumed: false,
        }
    }

    pub fn poll_has_next_field(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
    ) -> Poll<Result<bool, S::Error>> {
        self.as_mut().inner().stream().consume_boundary(cx)
    }

    pub fn poll_field_headers(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
    ) -> PollOpt<FieldHeaders, S::Error> {
        unsafe {
            let this = self.as_mut().get_unchecked_mut();
            this.read_hdr
                .read_headers(Pin::new_unchecked(&mut this.inner), cx)
        }
    }

    pub fn poll_body_chunk(self: Pin<&mut Self>, cx: &mut Context) -> PollOpt<S::Ok, S::Error> {
        if !self.read_hdr.is_reading_headers() {
            self.inner().poll_next(cx)
        } else {
            Poll::Ready(None)
        }
    }
}

/// An extension trait for requests which may be multipart.
pub trait RequestExt: Sized {
    /// The success type, may contain `Multipart` or something else.
    type Multipart;

    /// Convert `Self` into `Self::Multipart` if applicable.
    fn into_multipart(self) -> Result<Self::Multipart, Self>;
}

/// Struct wrapping a stream which allows a chunk to be pushed back to it to be yielded next.
pub(crate) struct PushChunk<S, T> {
    stream: S,
    pushed: Option<T>,
}

impl<S, T> PushChunk<S, T> {
    unsafe_pinned!(stream: S);
    unsafe_unpinned!(pushed: Option<T>);

    pub(crate) fn new(stream: S) -> Self {
        PushChunk {
            stream,
            pushed: None,
        }
    }
}

impl<S: TryStream> PushChunk<S, S::Ok> where S::Ok: BodyChunk {
    fn push_chunk(mut self: Pin<&mut Self>, chunk: S::Ok) {
        if let Some(pushed) = self.as_mut().pushed() {
            debug_panic!(
                "pushing excess chunk: \"{}\" already pushed chunk: \"{}\"",
                show_bytes(chunk.as_slice()),
                show_bytes(pushed.as_slice())
            );
        }

        debug_assert!(!chunk.is_empty(), "pushing empty chunk");

        *self.as_mut().pushed() = Some(chunk);
    }
}

impl<S: TryStream> Stream for PushChunk<S, S::Ok> {
    type Item = Result<S::Ok, S::Error>;

    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
        if let Some(pushed) = self.as_mut().pushed().take() {
            return Poll::Ready(Some(Ok(pushed)));
        }

        self.stream().try_poll_next(cx)
    }
}

#[cfg(test)]
mod test {
    use futures::prelude::*;
    use super::Multipart;
    use crate::test_util::mock_stream;
    use crate::server::FieldHeaders;

    const BOUNDARY: &str = "boundary";

    #[test]
    fn test_empty_body() {
        let _ = ::env_logger::try_init();
        let multipart = Multipart::with_body(
            mock_stream(&[]),
            BOUNDARY
        );
        pin_mut!(multipart);
        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(false));
    }

    #[test]
    fn test_no_headers() {
        let _ = ::env_logger::try_init();
        let multipart = Multipart::with_body(
            mock_stream(&[b"--boundary", b"\r\n", b"\r\n", b"--boundary--"]),
            BOUNDARY
        );
        pin_mut!(multipart);
        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(true));
        ready_assert_eq!(|cx| multipart.as_mut().poll_field_headers(cx), None);
        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(false));
    }

    #[test]
    fn test_single_field() {
        let _ = ::env_logger::try_init();
        let multipart = Multipart::with_body(
            mock_stream(&[
                b"--boundary\r", b"\n",
                b"Content-Disposition:",
                b" form-data; name=",
                b"\"foo\"",
                b"\r\n\r\n",
                b"field data",
                b"\r", b"\n--boundary--"
            ]),
            BOUNDARY
        );
        pin_mut!(multipart);

        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(true));

        ready_assert_eq!(
            |cx| multipart.as_mut().poll_field_headers(cx),
            Some(Ok(FieldHeaders {
                name: "foo".into(),
                filename: None,
                content_type: None,
                ext_headers: Default::default(),
                _backcompat: (),
            }))
        );

        ready_assert_eq!(
            |cx| multipart.as_mut().poll_body_chunk(cx),
            Some(Ok(&b"field data"[..]))
        );

        ready_assert_eq!(|cx| multipart.as_mut().poll_body_chunk(cx), None);
        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(false));
    }

    #[test]
    fn test_two_fields() {
        let _ = ::env_logger::try_init();
        let multipart = Multipart::with_body(
            mock_stream(&[
                b"--boundary\r", b"\n",
                b"Content-Disposition:",
                b" form-data; name=",
                b"\"foo\"",
                b"\r\n\r\n",
                b"field data",
                b"\r", b"\n--boundary\r\n",
                b"Content-Disposition: form-data; name=", b"foo-", b"data",
                b"; filename=", b"\"foo.txt\"", b"\r\n",
                b"Content-Type: ", b"text/plain; charset", b"=utf-8", b"\r\n", b"\r\n",
                b"field data--2\r\n--data--field",
                b"\r\n--boundary--"
            ]),
            BOUNDARY
        );
        pin_mut!(multipart);

        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(true));

        ready_assert_eq!(
            |cx| multipart.as_mut().poll_field_headers(cx),
            Some(Ok(FieldHeaders {
                name: "foo".into(),
                filename: None,
                content_type: None,
                ext_headers: Default::default(),
                _backcompat: (),
            }))
        );

        ready_assert_eq!(
            |cx| multipart.as_mut().poll_body_chunk(cx),
            Some(Ok(&b"field data"[..]))
        );
        ready_assert_eq!(|cx| multipart.as_mut().poll_body_chunk(cx), None);

        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(true));

        ready_assert_eq!(
            |cx| multipart.as_mut().poll_field_headers(cx),
            Some(Ok(FieldHeaders {
                name: "foo-data".into(),
                filename: Some("foo.txt".into()),
                content_type: Some(mime::TEXT_PLAIN_UTF_8),
                ext_headers: Default::default(),
                _backcompat: (),
            }))
        );

        ready_assert_eq!(
            |cx| multipart.as_mut().poll_body_chunk(cx),
            Some(Ok(&b"field data--2\r\n--data--field"[..]))
        );
        ready_assert_eq!(|cx| multipart.as_mut().poll_body_chunk(cx), None);

        ready_assert_eq!(|cx| multipart.as_mut().poll_has_next_field(cx), Ok(false));
    }
}
<|endoftext|>


<commit_before>use compact::Compact;
use std::cell::Cell;

/// TODO: make this much more simple and just like a Box once we can move out of messages!

/// An owning reference to local state outside the actor system that can safely be embedded in
/// actor states and passed in messages, as long as they stay on one machine.
pub struct External<T> {
    maybe_owned: Cell<Option<Box<T>>>,
}

impl<T> External<T> {
    /// Allocate `content` on the heap and create a sharable `External` reference to it
    pub fn new(content: T) -> Self {
        External { maybe_owned: Cell::new(Some(Box::new(content))) }
    }

    /// To interface with traditional owned boxes
    pub fn from_box(content: Box<T>) -> Self {
        External { maybe_owned: Cell::new(Some(content)) }
    }

    /// Like `clone`, just to make the danger more clear
    pub fn steal(&self) -> Self {
        self.clone()
    }

    /// To interface with traditional owned boxes
    pub fn into_box(self) -> Box<T> {
        self.maybe_owned.into_inner().expect(
            "Tried to get Box from already taken external",
        )
    }
}

// TODO: this is _really_ screwy, see above
impl<T> Clone for External<T> {
    fn clone(&self) -> Self {
        External {
            maybe_owned: Cell::new(Some(self.maybe_owned.take().expect(
                "Tried to clone already taken external",
            ))),
        }
    }
}

impl<T> ::std::ops::Deref for External<T> {
    type Target = T;

    fn deref(&self) -> &T {
        let option_ref = unsafe { &(*self.maybe_owned.as_ptr()) };
        &**option_ref.as_ref().expect(
            "Tried to deref already taken external",
        )
    }
}

impl<T> ::std::ops::DerefMut for External<T> {
    fn deref_mut(&mut self) -> &mut T {
        &mut *self.maybe_owned.get_mut().as_mut().expect(
            "Tried to mut deref already taken external",
        )
    }
}

impl<T> Compact for External<T> {
    fn is_still_compact(&self) -> bool {
        true
    }
    fn dynamic_size_bytes(&self) -> usize {
        0
    }
    unsafe fn compact(source: *mut Self, dest: *mut Self, _new_dynamic_part: *mut u8) {
        ::std::ptr::copy_nonoverlapping(source, dest, 1)
    }
    unsafe fn decompact(source: *const Self) -> Self {
        ::std::ptr::read(source)
    }
}<commit_msg>dear rustfmt, thanks<commit_after>use compact::Compact;
use std::cell::Cell;

/// TODO: make this much more simple and just like a Box once we can move out of messages!

/// An owning reference to local state outside the actor system that can safely be embedded in
/// actor states and passed in messages, as long as they stay on one machine.
pub struct External<T> {
    maybe_owned: Cell<Option<Box<T>>>,
}

impl<T> External<T> {
    /// Allocate `content` on the heap and create a sharable `External` reference to it
    pub fn new(content: T) -> Self {
        External { maybe_owned: Cell::new(Some(Box::new(content))) }
    }

    /// To interface with traditional owned boxes
    pub fn from_box(content: Box<T>) -> Self {
        External { maybe_owned: Cell::new(Some(content)) }
    }

    /// Like `clone`, just to make the danger more clear
    pub fn steal(&self) -> Self {
        self.clone()
    }

    /// To interface with traditional owned boxes
    pub fn into_box(self) -> Box<T> {
        self.maybe_owned.into_inner().expect(
            "Tried to get Box from already taken external",
        )
    }
}

// TODO: this is _really_ screwy, see above
impl<T> Clone for External<T> {
    fn clone(&self) -> Self {
        External {
            maybe_owned: Cell::new(Some(self.maybe_owned.take().expect(
                "Tried to clone already taken external",
            ))),
        }
    }
}

impl<T> ::std::ops::Deref for External<T> {
    type Target = T;

    fn deref(&self) -> &T {
        let option_ref = unsafe { &(*self.maybe_owned.as_ptr()) };
        &**option_ref.as_ref().expect(
            "Tried to deref already taken external",
        )
    }
}

impl<T> ::std::ops::DerefMut for External<T> {
    fn deref_mut(&mut self) -> &mut T {
        &mut *self.maybe_owned.get_mut().as_mut().expect(
            "Tried to mut deref already taken external",
        )
    }
}

impl<T> Compact for External<T> {
    fn is_still_compact(&self) -> bool {
        true
    }
    fn dynamic_size_bytes(&self) -> usize {
        0
    }
    unsafe fn compact(source: *mut Self, dest: *mut Self, _new_dynamic_part: *mut u8) {
        ::std::ptr::copy_nonoverlapping(source, dest, 1)
    }
    unsafe fn decompact(source: *const Self) -> Self {
        ::std::ptr::read(source)
    }
}
<|endoftext|>


<commit_before>// Copyright 2018, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use std::mem;
use std::sync::atomic::{AtomicUsize, Ordering};

use futures;
use futures::prelude::*;
use futures::executor::{Executor, SpawnError};
use futures::task::{LocalMap, UnsafeWake, Waker};
use futures::{Async, Future, Never};

use MainContext;
use MainLoop;
use Source;
use Priority;

use get_thread_id;

use ::translate::{from_glib_none, from_glib_full, mut_override, ToGlib};
use ffi as glib_ffi;

// We can't use an enum here because we want to store this in an atomic variable
const INIT: usize = 0;
const NOT_READY: usize = 1;
const READY: usize = 2;
const DONE: usize = 3;

#[repr(C)]
struct TaskSource {
    source: glib_ffi::GSource,
    future: Option<(Box<Future<Item = (), Error = Never>>, Box<LocalMap>)>,
    thread: Option<usize>,
    state: AtomicUsize,
}

unsafe impl UnsafeWake for TaskSource {
    unsafe fn clone_raw(&self) -> Waker {
        Waker::new(glib_ffi::g_source_ref(mut_override(&self.source)) as *const TaskSource)
    }

    unsafe fn drop_raw(&self) {
        glib_ffi::g_source_unref(mut_override(&self.source));
    }

    unsafe fn wake(&self) {
        if self.state
            .compare_and_swap(NOT_READY, READY, Ordering::SeqCst) == NOT_READY
        {
            glib_ffi::g_source_set_ready_time(mut_override(&self.source), 0);
        }
    }
}

unsafe extern "C" fn prepare(
    source: *mut glib_ffi::GSource,
    timeout: *mut i32,
) -> glib_ffi::gboolean {
    let source = &mut *(source as *mut TaskSource);

    *timeout = -1;

    let mut cur = source
        .state
        .compare_and_swap(INIT, NOT_READY, Ordering::SeqCst);
    if cur == INIT {
        // XXX: This is not actually correct, we should not dispatch the
        // GSource here already but we need to know its current status so
        // that if it is not ready yet something can register to the waker
        if let Async::Ready(()) = source.poll() {
            source.state.store(DONE, Ordering::SeqCst);
            cur = DONE;
        } else {
            cur = NOT_READY;
        }
    }

    if cur == READY || cur == DONE {
        glib_ffi::GTRUE
    } else {
        glib_ffi::GFALSE
    }
}

unsafe extern "C" fn check(source: *mut glib_ffi::GSource) -> glib_ffi::gboolean {
    let source = &mut *(source as *mut TaskSource);

    let cur = source.state.load(Ordering::SeqCst);
    if cur == READY || cur == DONE {
        glib_ffi::GTRUE
    } else {
        glib_ffi::GFALSE
    }
}

unsafe extern "C" fn dispatch(
    source: *mut glib_ffi::GSource,
    callback: glib_ffi::GSourceFunc,
    _user_data: glib_ffi::gpointer,
) -> glib_ffi::gboolean {
    let source = &mut *(source as *mut TaskSource);
    assert!(callback.is_none());

    glib_ffi::g_source_set_ready_time(mut_override(&source.source), -1);
    let mut cur = source
        .state
        .compare_and_swap(READY, NOT_READY, Ordering::SeqCst);
    if cur == READY {
        if let Async::Ready(()) = source.poll() {
            source.state.store(DONE, Ordering::SeqCst);
            cur = DONE;
        } else {
            cur = NOT_READY;
        }
    }

    if cur == DONE {
        glib_ffi::G_SOURCE_REMOVE
    } else {
        glib_ffi::G_SOURCE_CONTINUE
    }
}

unsafe extern "C" fn finalize(source: *mut glib_ffi::GSource) {
    let source = source as *mut TaskSource;
    let _ = (*source).future.take();
}

static SOURCE_FUNCS: glib_ffi::GSourceFuncs = glib_ffi::GSourceFuncs {
    check: Some(check),
    prepare: Some(prepare),
    dispatch: Some(dispatch),
    finalize: Some(finalize),
    closure_callback: None,
    closure_marshal: None,
};

impl TaskSource {
    fn new(
        priority: Priority,
        future: Box<Future<Item = (), Error = Never> + 'static + Send>,
    ) -> Source {
        unsafe { Self::new_unsafe(priority, None, future) }
    }

    // NOTE: This does not have the Send bound and requires to be called from the same
    // thread where the main context is running
    unsafe fn new_unsafe(
        priority: Priority,
        thread: Option<usize>,
        future: Box<Future<Item = (), Error = Never> + 'static>,
    ) -> Source {
        let source = glib_ffi::g_source_new(
            mut_override(&SOURCE_FUNCS),
            mem::size_of::<TaskSource>() as u32,
        );
        {
            let source = &mut *(source as *mut TaskSource);
            source.future = Some((future, Box::new(LocalMap::new())));
            source.thread = thread;
            source.state = AtomicUsize::new(INIT);
        }

        glib_ffi::g_source_set_priority(source, priority.to_glib());

        from_glib_full(source)
    }

    fn poll(&mut self) -> Async<()> {
        // Make sure that the first time we're polled that the current thread is remembered
        // and from there one we ensure that we're always polled from exactly the same thread.
        //
        // In theory a GMainContext can be first run from one thread and later from another
        // thread, but we allow spawning non-Send futures and must not ever use them from
        // any other thread.
        match &mut self.thread {
            thread @ &mut None => {
                *thread = Some(get_thread_id());
            }
            &mut Some(thread_id) => {
                assert_eq!(get_thread_id(), thread_id,
                           "Task polled on a different thread than before");
            }
        }

        let waker = unsafe { self.clone_raw() };
        let source = &self.source as *const _;
        if let Some(ref mut future) = self.future {
            let (ref mut future, ref mut local_map) = *future;

            let mut executor: MainContext = unsafe {
                from_glib_none(glib_ffi::g_source_get_context(mut_override(source)))
            };

            assert!(executor.is_owner(), "Polling futures only allowed if the thread is owning the MainContext");

            // Clone that we store in the task local data so that
            // it can be retrieved as needed
            executor.push_thread_default();

            let res = {
                let enter = futures::executor::enter().unwrap();
                let mut context =
                    futures::task::Context::new(local_map, &waker, &mut executor);

                let res = future.poll(&mut context).unwrap_or(Async::Ready(()));

                drop(enter);

                res
            };

            executor.pop_thread_default();
            res
        } else {
            Async::Ready(())
        }
    }
}

impl MainContext {
    /// Spawn a new infallible `Future` on the main context.
    ///
    /// This can be called from any thread and will execute the future from the thread
    /// where main context is running, e.g. via a `MainLoop`.
    pub fn spawn<F: Future<Item = (), Error = Never> + Send + 'static>(&self, f: F) {
        self.spawn_with_priority(::PRIORITY_DEFAULT, f);
    }

    /// Spawn a new infallible `Future` on the main context.
    ///
    /// The given `Future` does not have to be `Send`.
    ///
    /// This can be called only from the thread where the main context is running, e.g.
    /// from any other `Future` that is executed on this main context, or after calling
    /// `push_thread_default` or `acquire` on the main context.
    pub fn spawn_local<F: Future<Item = (), Error = Never> + 'static>(&self, f: F) {
        self.spawn_local_with_priority(::PRIORITY_DEFAULT, f);
    }

    /// Spawn a new infallible `Future` on the main context, with a non-default priority.
    ///
    /// This can be called from any thread and will execute the future from the thread
    /// where main context is running, e.g. via a `MainLoop`.
    pub fn spawn_with_priority<F: Future<Item = (), Error = Never> + Send + 'static>(&self, priority: Priority, f: F) {
        let f = Box::new(f);
        let source = TaskSource::new(priority, f);
        source.attach(Some(&*self));
    }

    /// Spawn a new infallible `Future` on the main context, with a non-default priority.
    ///
    /// The given `Future` does not have to be `Send`.
    ///
    /// This can be called only from the thread where the main context is running, e.g.
    /// from any other `Future` that is executed on this main context, or after calling
    /// `push_thread_default` or `acquire` on the main context.
    pub fn spawn_local_with_priority<F: Future<Item = (), Error = Never> + 'static>(&self, priority: Priority, f: F) {
        assert!(self.is_owner(), "Spawning local futures only allowed on the thread owning the MainContext");
        let f = Box::new(f);
        unsafe {
            // Ensure that this task is never polled on another thread
            // than this one where it was spawned now.
            let source = TaskSource::new_unsafe(priority, Some(get_thread_id()), f);
            source.attach(Some(&*self));
        }
    }

    /// Runs a new, infallible `Future` on the main context and block until it finished, returning
    /// the result of the `Future`.
    ///
    /// The given `Future` does not have to be `Send` or `'static`.
    ///
    /// This must only be called if no `MainLoop` or anything else is running on this specific main
    /// context.
    pub fn block_on<F: Future>(&self, f: F) -> Result<F::Item, F::Error> {
        let mut res = None;
        let l = MainLoop::new(Some(&*self), false);
        let l_clone = l.clone();

        unsafe {
            let f = f.then(|r| {
                res = Some(r);
                l_clone.quit();
                Ok::<(), Never>(())
            });

            let f: *mut Future<Item = (), Error = Never> = Box::into_raw(Box::new(f));
            // XXX: Transmute to get a 'static lifetime here, super unsafe
            let f: *mut (Future<Item = (), Error = Never> + 'static) = mem::transmute(f);
            let f: Box<Future<Item = (), Error = Never> + 'static> = Box::from_raw(f);

            // Ensure that this task is never polled on another thread
            // than this one where it was spawned now.
            let source = TaskSource::new_unsafe(::PRIORITY_DEFAULT, Some(get_thread_id()), f);
            source.attach(Some(&*self));
        }

        l.run();

        res.unwrap()
    }
}

impl Executor for MainContext {
    fn spawn(&mut self, f: Box<Future<Item = (), Error = Never> + Send>) -> Result<(), SpawnError> {
        let f = Box::new(f);
        let source = TaskSource::new(::PRIORITY_DEFAULT, f);
        source.attach(Some(&*self));
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::thread;
    use std::sync::mpsc;
    use futures_channel::oneshot;
    use futures_util::future;

    #[test]
    fn test_spawn() {
        let c = MainContext::new();
        let l = ::MainLoop::new(Some(&c), false);

        let (sender, receiver) = mpsc::channel();
        let (o_sender, o_receiver) = oneshot::channel();

        let l_clone = l.clone();
        c.spawn(o_receiver
                .map_err(|_| unimplemented!())
                .and_then(move |()| {
                    sender.send(()).unwrap();
                    l_clone.quit();

                    Ok(())
                })
        );

        thread::spawn(move || {
            l.run();
        });

        o_sender.send(()).unwrap();

        let _ = receiver.recv().unwrap();
    }

    #[test]
    fn test_spawn_local() {
        let c = MainContext::new();
        let l = ::MainLoop::new(Some(&c), false);

        c.push_thread_default();
        let l_clone = l.clone();
        c.spawn_local(future::lazy(move |_ctx| {
            l_clone.quit();

            Ok(())
        }));

        l.run();

        c.pop_thread_default();
    }

    #[test]
    fn test_block_on() {
        let c = MainContext::new();

        let mut v = None;
        {
            let v = &mut v;

            let future = future::lazy(|_ctx| {
                *v = Some(123);
                Ok::<i32, ()>(123)
            });

            let res = c.block_on(future);
            assert_eq!(res, Ok(123));
        }

        assert_eq!(v, Some(123));
    }
}
<commit_msg>Fix build of futures 0.2 tests<commit_after>// Copyright 2018, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use std::mem;
use std::sync::atomic::{AtomicUsize, Ordering};

use futures;
use futures::prelude::*;
use futures::executor::{Executor, SpawnError};
use futures::task::{LocalMap, UnsafeWake, Waker};
use futures::{Async, Future, Never};

use MainContext;
use MainLoop;
use Source;
use Priority;

use get_thread_id;

use ::translate::{from_glib_none, from_glib_full, mut_override, ToGlib};
use ffi as glib_ffi;

// We can't use an enum here because we want to store this in an atomic variable
const INIT: usize = 0;
const NOT_READY: usize = 1;
const READY: usize = 2;
const DONE: usize = 3;

#[repr(C)]
struct TaskSource {
    source: glib_ffi::GSource,
    future: Option<(Box<Future<Item = (), Error = Never>>, Box<LocalMap>)>,
    thread: Option<usize>,
    state: AtomicUsize,
}

unsafe impl UnsafeWake for TaskSource {
    unsafe fn clone_raw(&self) -> Waker {
        Waker::new(glib_ffi::g_source_ref(mut_override(&self.source)) as *const TaskSource)
    }

    unsafe fn drop_raw(&self) {
        glib_ffi::g_source_unref(mut_override(&self.source));
    }

    unsafe fn wake(&self) {
        if self.state
            .compare_and_swap(NOT_READY, READY, Ordering::SeqCst) == NOT_READY
        {
            glib_ffi::g_source_set_ready_time(mut_override(&self.source), 0);
        }
    }
}

unsafe extern "C" fn prepare(
    source: *mut glib_ffi::GSource,
    timeout: *mut i32,
) -> glib_ffi::gboolean {
    let source = &mut *(source as *mut TaskSource);

    *timeout = -1;

    let mut cur = source
        .state
        .compare_and_swap(INIT, NOT_READY, Ordering::SeqCst);
    if cur == INIT {
        // XXX: This is not actually correct, we should not dispatch the
        // GSource here already but we need to know its current status so
        // that if it is not ready yet something can register to the waker
        if let Async::Ready(()) = source.poll() {
            source.state.store(DONE, Ordering::SeqCst);
            cur = DONE;
        } else {
            cur = NOT_READY;
        }
    }

    if cur == READY || cur == DONE {
        glib_ffi::GTRUE
    } else {
        glib_ffi::GFALSE
    }
}

unsafe extern "C" fn check(source: *mut glib_ffi::GSource) -> glib_ffi::gboolean {
    let source = &mut *(source as *mut TaskSource);

    let cur = source.state.load(Ordering::SeqCst);
    if cur == READY || cur == DONE {
        glib_ffi::GTRUE
    } else {
        glib_ffi::GFALSE
    }
}

unsafe extern "C" fn dispatch(
    source: *mut glib_ffi::GSource,
    callback: glib_ffi::GSourceFunc,
    _user_data: glib_ffi::gpointer,
) -> glib_ffi::gboolean {
    let source = &mut *(source as *mut TaskSource);
    assert!(callback.is_none());

    glib_ffi::g_source_set_ready_time(mut_override(&source.source), -1);
    let mut cur = source
        .state
        .compare_and_swap(READY, NOT_READY, Ordering::SeqCst);
    if cur == READY {
        if let Async::Ready(()) = source.poll() {
            source.state.store(DONE, Ordering::SeqCst);
            cur = DONE;
        } else {
            cur = NOT_READY;
        }
    }

    if cur == DONE {
        glib_ffi::G_SOURCE_REMOVE
    } else {
        glib_ffi::G_SOURCE_CONTINUE
    }
}

unsafe extern "C" fn finalize(source: *mut glib_ffi::GSource) {
    let source = source as *mut TaskSource;
    let _ = (*source).future.take();
}

static SOURCE_FUNCS: glib_ffi::GSourceFuncs = glib_ffi::GSourceFuncs {
    check: Some(check),
    prepare: Some(prepare),
    dispatch: Some(dispatch),
    finalize: Some(finalize),
    closure_callback: None,
    closure_marshal: None,
};

impl TaskSource {
    fn new(
        priority: Priority,
        future: Box<Future<Item = (), Error = Never> + 'static + Send>,
    ) -> Source {
        unsafe { Self::new_unsafe(priority, None, future) }
    }

    // NOTE: This does not have the Send bound and requires to be called from the same
    // thread where the main context is running
    unsafe fn new_unsafe(
        priority: Priority,
        thread: Option<usize>,
        future: Box<Future<Item = (), Error = Never> + 'static>,
    ) -> Source {
        let source = glib_ffi::g_source_new(
            mut_override(&SOURCE_FUNCS),
            mem::size_of::<TaskSource>() as u32,
        );
        {
            let source = &mut *(source as *mut TaskSource);
            source.future = Some((future, Box::new(LocalMap::new())));
            source.thread = thread;
            source.state = AtomicUsize::new(INIT);
        }

        glib_ffi::g_source_set_priority(source, priority.to_glib());

        from_glib_full(source)
    }

    fn poll(&mut self) -> Async<()> {
        // Make sure that the first time we're polled that the current thread is remembered
        // and from there one we ensure that we're always polled from exactly the same thread.
        //
        // In theory a GMainContext can be first run from one thread and later from another
        // thread, but we allow spawning non-Send futures and must not ever use them from
        // any other thread.
        match &mut self.thread {
            thread @ &mut None => {
                *thread = Some(get_thread_id());
            }
            &mut Some(thread_id) => {
                assert_eq!(get_thread_id(), thread_id,
                           "Task polled on a different thread than before");
            }
        }

        let waker = unsafe { self.clone_raw() };
        let source = &self.source as *const _;
        if let Some(ref mut future) = self.future {
            let (ref mut future, ref mut local_map) = *future;

            let mut executor: MainContext = unsafe {
                from_glib_none(glib_ffi::g_source_get_context(mut_override(source)))
            };

            assert!(executor.is_owner(), "Polling futures only allowed if the thread is owning the MainContext");

            // Clone that we store in the task local data so that
            // it can be retrieved as needed
            executor.push_thread_default();

            let res = {
                let enter = futures::executor::enter().unwrap();
                let mut context =
                    futures::task::Context::new(local_map, &waker, &mut executor);

                let res = future.poll(&mut context).unwrap_or(Async::Ready(()));

                drop(enter);

                res
            };

            executor.pop_thread_default();
            res
        } else {
            Async::Ready(())
        }
    }
}

impl MainContext {
    /// Spawn a new infallible `Future` on the main context.
    ///
    /// This can be called from any thread and will execute the future from the thread
    /// where main context is running, e.g. via a `MainLoop`.
    pub fn spawn<F: Future<Item = (), Error = Never> + Send + 'static>(&self, f: F) {
        self.spawn_with_priority(::PRIORITY_DEFAULT, f);
    }

    /// Spawn a new infallible `Future` on the main context.
    ///
    /// The given `Future` does not have to be `Send`.
    ///
    /// This can be called only from the thread where the main context is running, e.g.
    /// from any other `Future` that is executed on this main context, or after calling
    /// `push_thread_default` or `acquire` on the main context.
    pub fn spawn_local<F: Future<Item = (), Error = Never> + 'static>(&self, f: F) {
        self.spawn_local_with_priority(::PRIORITY_DEFAULT, f);
    }

    /// Spawn a new infallible `Future` on the main context, with a non-default priority.
    ///
    /// This can be called from any thread and will execute the future from the thread
    /// where main context is running, e.g. via a `MainLoop`.
    pub fn spawn_with_priority<F: Future<Item = (), Error = Never> + Send + 'static>(&self, priority: Priority, f: F) {
        let f = Box::new(f);
        let source = TaskSource::new(priority, f);
        source.attach(Some(&*self));
    }

    /// Spawn a new infallible `Future` on the main context, with a non-default priority.
    ///
    /// The given `Future` does not have to be `Send`.
    ///
    /// This can be called only from the thread where the main context is running, e.g.
    /// from any other `Future` that is executed on this main context, or after calling
    /// `push_thread_default` or `acquire` on the main context.
    pub fn spawn_local_with_priority<F: Future<Item = (), Error = Never> + 'static>(&self, priority: Priority, f: F) {
        assert!(self.is_owner(), "Spawning local futures only allowed on the thread owning the MainContext");
        let f = Box::new(f);
        unsafe {
            // Ensure that this task is never polled on another thread
            // than this one where it was spawned now.
            let source = TaskSource::new_unsafe(priority, Some(get_thread_id()), f);
            source.attach(Some(&*self));
        }
    }

    /// Runs a new, infallible `Future` on the main context and block until it finished, returning
    /// the result of the `Future`.
    ///
    /// The given `Future` does not have to be `Send` or `'static`.
    ///
    /// This must only be called if no `MainLoop` or anything else is running on this specific main
    /// context.
    pub fn block_on<F: Future>(&self, f: F) -> Result<F::Item, F::Error> {
        let mut res = None;
        let l = MainLoop::new(Some(&*self), false);
        let l_clone = l.clone();

        unsafe {
            let f = f.then(|r| {
                res = Some(r);
                l_clone.quit();
                Ok::<(), Never>(())
            });

            let f: *mut Future<Item = (), Error = Never> = Box::into_raw(Box::new(f));
            // XXX: Transmute to get a 'static lifetime here, super unsafe
            let f: *mut (Future<Item = (), Error = Never> + 'static) = mem::transmute(f);
            let f: Box<Future<Item = (), Error = Never> + 'static> = Box::from_raw(f);

            // Ensure that this task is never polled on another thread
            // than this one where it was spawned now.
            let source = TaskSource::new_unsafe(::PRIORITY_DEFAULT, Some(get_thread_id()), f);
            source.attach(Some(&*self));
        }

        l.run();

        res.unwrap()
    }
}

impl Executor for MainContext {
    fn spawn(&mut self, f: Box<Future<Item = (), Error = Never> + Send>) -> Result<(), SpawnError> {
        let f = Box::new(f);
        let source = TaskSource::new(::PRIORITY_DEFAULT, f);
        source.attach(Some(&*self));
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::thread;
    use std::sync::mpsc;
    use futures::future;
    use futures::channel::oneshot;

    #[test]
    fn test_spawn() {
        let c = MainContext::new();
        let l = ::MainLoop::new(Some(&c), false);

        let (sender, receiver) = mpsc::channel();
        let (o_sender, o_receiver) = oneshot::channel();

        let l_clone = l.clone();
        c.spawn(o_receiver
                .map_err(|_| unimplemented!())
                .and_then(move |()| {
                    sender.send(()).unwrap();
                    l_clone.quit();

                    Ok(())
                })
        );

        thread::spawn(move || {
            l.run();
        });

        o_sender.send(()).unwrap();

        let _ = receiver.recv().unwrap();
    }

    #[test]
    fn test_spawn_local() {
        let c = MainContext::new();
        let l = ::MainLoop::new(Some(&c), false);

        c.push_thread_default();
        let l_clone = l.clone();
        c.spawn_local(future::lazy(move |_ctx| {
            l_clone.quit();

            Ok(())
        }));

        l.run();

        c.pop_thread_default();
    }

    #[test]
    fn test_block_on() {
        let c = MainContext::new();

        let mut v = None;
        {
            let v = &mut v;

            let future = future::lazy(|_ctx| {
                *v = Some(123);
                Ok::<i32, ()>(123)
            });

            let res = c.block_on(future);
            assert_eq!(res, Ok(123));
        }

        assert_eq!(v, Some(123));
    }
}
<|endoftext|>


<commit_before>use std::fmt::Debug;
use std::hash::Hash;
use std::rc::Rc;
use std::mem::replace;

use adapton_syntax::* ;
use adapton_sigs::* ;

pub trait ListT<A:Adapton,Hd> : Debug+Hash+PartialEq+Eq+Clone {
    type List : Debug+Hash+PartialEq+Eq+Clone ;

    fn nil  (&mut A) -> Self::List ;
    fn cons (&mut A, Hd, Box<Self::List>) -> Self::List ;
    fn rc   (&mut A, Rc<Self::List>) -> Self::List ;

    // requisite "adaptonic" constructors: `name` and `art`:
    fn name (&mut A, A::Name, Box<Self::List>) -> Self::List ;
    fn art  (&mut A, Art<Self::List,A::Loc>) -> Self::List ;

    fn elim<Res,Nil,Cons,Name> (self:&Self, &mut A, &Self::List, Nil, Cons, Name) -> Res
        where Nil:FnOnce(&mut A) -> Res
        ,    Cons:FnOnce(&mut A, &Hd, &Box<Self::List>) -> Res
        ,    Name:FnOnce(&mut A, &A::Name, &Box<Self::List>) -> Res ;

    // Derived from above:
    fn is_empty (self:&Self, st:&mut A, list:&Self::List) -> bool {
        self.elim(st, &list, |_|true, |_,_,_|false, |_,_,_|false)
    }

    fn elim2<Res,Nil,Cons,Name> (&mut A, &Self::List, Nil, Cons, Name) -> Res
        where Nil:FnOnce(&mut A) -> Res
        ,    Cons:FnOnce(&mut A, &Hd, &Box<Self::List>) -> Res
        ,    Name:FnOnce(&mut A, &A::Name, &Box<Self::List>) -> Res ;

    // Derived from above:
    fn is_empty2 (st:&mut A, list:&Self::List) -> bool {
        ListT::elim2(st, &list, |_|true, |_,_,_|false, |_,_,_|false)
    }
}

// Questions:
//  - Should `Name`s always be passed by reference?
//  - Do these Fn argss for fold need to be passed in `Rc<Box<_>>`s ?

pub trait TreeT<A:Adapton,Leaf,Bin:Hash> : Debug+Hash+PartialEq+Eq+Clone {
    type Tree : Debug+Hash+PartialEq+Eq+Clone ;

    fn nil  (&mut A) -> Self::Tree ;
    fn leaf (&mut A, Leaf) -> Self::Tree ;
    fn bin  (&mut A, Bin, Box<Self::Tree>, Box<Self::Tree>) -> Self::Tree ;

    // requisite "adaptonic" constructors: `name` and `art`:
    fn name (&mut A, A::Name, Box<Self::Tree>, Box<Self::Tree>) -> Self::Tree ;
    fn art  (&mut A, Art<Self::Tree,A::Loc>) -> Self::Tree ;

    fn fold<Res,LeafC,BinC> (&mut A, Self::Tree, Res, LeafC, BinC) -> Res
        where LeafC:Fn(&mut A, Res, Leaf) -> Res
        ,      BinC:Fn(&mut A, Res, Bin ) -> Res ;

    fn fold_up<Arg,Res,LeafC,BinC> (&mut A, Self::Tree, LeafC, BinC) -> Res
        where LeafC:Fn(&mut A, Leaf) -> Res
        ,      BinC:Fn(&mut A, Bin, Res, Res ) -> Res ;

    // TODO: Add derived operations (max, min, sum, etc.) for fold_up.
}

#[derive(Debug,PartialEq,Eq,Hash,Clone)]
enum List<A:Adapton,Hd> {
    Nil,
    Cons(Hd,      Box<List<A,Hd>>),
    Rc(           Rc<List<A,Hd>>),
    Name(A::Name, Box<List<A,Hd>>),
    Art(          Art<List<A,Hd>, A::Loc>),
}

// TODO: Why Does Adapton have to implement all of these?
//       It's not actually *contained* within the List structure; it cannot be ecountered there.
//       It's only ever present in a negative position (as a function parameter).
impl<A:Adapton+Debug+Hash+PartialEq+Eq+Clone,Hd:Debug+Hash+PartialEq+Eq+Clone> ListT<A,Hd> for List<A,Hd> {
    type List = List<A,Hd>;

    fn nil  (_:&mut A)                                  -> Self::List { List::Nil }
    fn cons (_:&mut A, hd:Hd, tl:Box<Self::List>)       -> Self::List { List::Cons(hd,tl) }
    fn name (_:&mut A, nm:A::Name, tl:Box<Self::List>)  -> Self::List { List::Name(nm, tl) }
    fn rc   (_:&mut A, rc:Rc<List<A,Hd>>)               -> Self::List { List::Rc(rc) }
    fn art  (_:&mut A, art:Art<List<A,Hd>,A::Loc>)      -> Self::List { List::Art(art) }

    fn elim<Res,Nil,Cons,Name> (self:&Self, st:&mut A, list:&Self::List, nilf:Nil, consf:Cons, namef:Name) -> Res
        where Nil:FnOnce(&mut A) -> Res
        ,    Cons:FnOnce(&mut A, &Hd, &Box<Self::List>) -> Res
        ,    Name:FnOnce(&mut A, &A::Name, &Box<Self::List>) -> Res
    {
        match *list {
            List::Nil => nilf(st),
            List::Cons(ref hd, ref tl) => consf(st, hd, tl),
            List::Name(ref nm, ref tl) => namef(st, nm, tl),
            List::Rc(ref rc) => self.elim(st, &*rc, nilf, consf, namef),
            List::Art(ref art) => {
                let list = st.force(art);
                self.elim(st, &list, nilf, consf, namef)
            }
        }
    }

    fn elim2<Res,Nil,Cons,Name> (st:&mut A, list:&Self::List, nilf:Nil, consf:Cons, namef:Name) -> Res
        where Nil:FnOnce(&mut A) -> Res
        ,    Cons:FnOnce(&mut A, &Hd, &Box<Self::List>) -> Res
        ,    Name:FnOnce(&mut A, &A::Name, &Box<Self::List>) -> Res
    {
        match *list {
            List::Nil => nilf(st),
            List::Cons(ref hd, ref tl) => consf(st, hd, tl),
            List::Name(ref nm, ref tl) => namef(st, nm, tl),
            List::Rc(ref rc) => List::elim2(st, &*rc, nilf, consf, namef),
            List::Art(ref art) => {
                let list = st.force(art);
                ListT::elim2(st, &list, nilf, consf, namef)
            }
        }
    }

}

fn tree_of_list_rec_memo <A:Adapton, X:Hash+Clone, T:TreeT<A,X,X>, L:ListT<A,X>>
    (st:&mut A, l:&L, list:&L::List, left_tree:&T::Tree, left_tree_lev:u32, parent_lev:u32) ->
    (T::Tree, L::List)
{
    let t = st.thunk (ArtId::Eager,
                      prog_pt!(tree_of_list_rec),
                      Rc::new(Box::new(|st, args|{
                          let (l, list, left_tree, left_tree_lev, parent_lev) = args ;
                          tree_of_list_rec::<A,X,T,L>
                              (st, l, list, left_tree, left_tree_lev, parent_lev)
                      })),
                      (l, list, left_tree, left_tree_lev, parent_lev)
                      ) ;
    st.force( &t )
}

fn tree_of_list_rec <A:Adapton, X:Hash+Clone, T:TreeT<A,X,X>, L:ListT<A,X>>
    (st:&mut A, l:&L, list:&L::List, left_tree:&T::Tree, left_tree_lev:u32, parent_lev:u32)
     -> (T::Tree, L::List)
{
    l.elim (
        st, &list,
        /* Nil */  |st| ( T::nil(st), L::nil(st) ),
        /* Cons */ |st, hd, rest| {
            let lev_hd = (1 + (my_hash(hd).leading_zeros())) as u32 ;
            if left_tree_lev <= lev_hd && lev_hd <= parent_lev {
                let nil = T::nil(st) ;
                let (right_tree, rest) = tree_of_list_rec::<A,X,T,L> ( st, l, rest, &nil, 0 as u32, lev_hd ) ;
                let tree = T::bin ( st, hd.clone(), Box::new(left_tree.clone()), Box::new(right_tree) ) ;
                tree_of_list_rec::<A,X,T,L> ( st, l, &rest, &tree, lev_hd, parent_lev )
            }
            else {
                let rest = L::cons(st, hd.clone(), rest.clone()) ;
                (left_tree.clone(), rest)
            }},
        /* Name */ |st, nm, rest| {
            let lev_nm = (1 + 64 + (my_hash(nm).leading_zeros())) as u32 ;
            if left_tree_lev <= lev_nm && lev_nm <= parent_lev {
                let nil = T::nil(st) ;
                // Done: Memoized the recursive calls to tree_of_list_rec.
                let (right_tree, rest) = tree_of_list_rec_memo::<A,X,T,L> ( st, l, rest, &nil, 0 as u32, lev_nm ) ;
                // TODO: Place left_ and right_ trees into articulations (not Boxes), named by name.
                let tree = T::name( st, nm.clone(), Box::new(left_tree.clone()), Box::new(right_tree) ) ;
                tree_of_list_rec_memo::<A,X,T,L> ( st, l, &rest, &tree, lev_nm, parent_lev )
            }
            else {
                let rest = L::name(st, nm.clone(), rest.clone()) ;
                (left_tree.clone(), rest)
            }}
        )
}

pub fn tree_of_list <A:Adapton, X:Hash+Clone, T:TreeT<A,X,X>, L:ListT<A,X>>
    (l:&L, st:&mut A, list:&L::List) -> T::Tree
{
    let nil = T::nil(st) ;
    let (tree, rest) = tree_of_list_rec::<A,X,T,L> (st, l, list, &nil, 0 as u32, u32::max_value()) ;
    assert!( l.is_empty( st, &rest ) );
    tree
}
<commit_msg>removed tangent code<commit_after>use std::fmt::Debug;
use std::hash::Hash;
use std::rc::Rc;
use std::mem::replace;

use adapton_syntax::* ;
use adapton_sigs::* ;

pub trait ListT<A:Adapton,Hd> : Debug+Hash+PartialEq+Eq+Clone {
    type List : Debug+Hash+PartialEq+Eq+Clone ;

    fn nil  (&mut A) -> Self::List ;
    fn cons (&mut A, Hd, Box<Self::List>) -> Self::List ;
    fn rc   (&mut A, Rc<Self::List>) -> Self::List ;

    // requisite "adaptonic" constructors: `name` and `art`:
    fn name (&mut A, A::Name, Box<Self::List>) -> Self::List ;
    fn art  (&mut A, Art<Self::List,A::Loc>) -> Self::List ;

    fn elim<Res,Nil,Cons,Name> (self:&Self, &mut A, &Self::List, Nil, Cons, Name) -> Res
        where Nil:FnOnce(&mut A) -> Res
        ,    Cons:FnOnce(&mut A, &Hd, &Box<Self::List>) -> Res
        ,    Name:FnOnce(&mut A, &A::Name, &Box<Self::List>) -> Res ;

    // Derived from above:
    fn is_empty (self:&Self, st:&mut A, list:&Self::List) -> bool {
        self.elim(st, &list, |_|true, |_,_,_|false, |_,_,_|false)
    }
}

// Questions:
//  - Should `Name`s always be passed by reference?
//  - Do these Fn argss for fold need to be passed in `Rc<Box<_>>`s ?

pub trait TreeT<A:Adapton,Leaf,Bin:Hash> : Debug+Hash+PartialEq+Eq+Clone {
    type Tree : Debug+Hash+PartialEq+Eq+Clone ;

    fn nil  (&mut A) -> Self::Tree ;
    fn leaf (&mut A, Leaf) -> Self::Tree ;
    fn bin  (&mut A, Bin, Box<Self::Tree>, Box<Self::Tree>) -> Self::Tree ;

    // requisite "adaptonic" constructors: `name` and `art`:
    fn name (&mut A, A::Name, Box<Self::Tree>, Box<Self::Tree>) -> Self::Tree ;
    fn art  (&mut A, Art<Self::Tree,A::Loc>) -> Self::Tree ;

    fn fold<Res,LeafC,BinC> (&mut A, Self::Tree, Res, LeafC, BinC) -> Res
        where LeafC:Fn(&mut A, Res, Leaf) -> Res
        ,      BinC:Fn(&mut A, Res, Bin ) -> Res ;

    fn fold_up<Arg,Res,LeafC,BinC> (&mut A, Self::Tree, LeafC, BinC) -> Res
        where LeafC:Fn(&mut A, Leaf) -> Res
        ,      BinC:Fn(&mut A, Bin, Res, Res ) -> Res ;

    // TODO: Add derived operations (max, min, sum, etc.) for fold_up.
}

#[derive(Debug,PartialEq,Eq,Hash,Clone)]
enum List<A:Adapton,Hd> {
    Nil,
    Cons(Hd,      Box<List<A,Hd>>),
    Rc(           Rc<List<A,Hd>>),
    Name(A::Name, Box<List<A,Hd>>),
    Art(          Art<List<A,Hd>, A::Loc>),
}

// TODO: Why Does Adapton have to implement all of these?
//       It's not actually *contained* within the List structure; it cannot be ecountered there.
//       It's only ever present in a negative position (as a function parameter).
impl<A:Adapton+Debug+Hash+PartialEq+Eq+Clone,Hd:Debug+Hash+PartialEq+Eq+Clone> ListT<A,Hd> for List<A,Hd> {
    type List = List<A,Hd>;

    fn nil  (_:&mut A)                                  -> Self::List { List::Nil }
    fn cons (_:&mut A, hd:Hd, tl:Box<Self::List>)       -> Self::List { List::Cons(hd,tl) }
    fn name (_:&mut A, nm:A::Name, tl:Box<Self::List>)  -> Self::List { List::Name(nm, tl) }
    fn rc   (_:&mut A, rc:Rc<List<A,Hd>>)               -> Self::List { List::Rc(rc) }
    fn art  (_:&mut A, art:Art<List<A,Hd>,A::Loc>)      -> Self::List { List::Art(art) }

    fn elim<Res,Nil,Cons,Name> (self:&Self, st:&mut A, list:&Self::List, nilf:Nil, consf:Cons, namef:Name) -> Res
        where Nil:FnOnce(&mut A) -> Res
        ,    Cons:FnOnce(&mut A, &Hd, &Box<Self::List>) -> Res
        ,    Name:FnOnce(&mut A, &A::Name, &Box<Self::List>) -> Res
    {
        match *list {
            List::Nil => nilf(st),
            List::Cons(ref hd, ref tl) => consf(st, hd, tl),
            List::Name(ref nm, ref tl) => namef(st, nm, tl),
            List::Rc(ref rc) => self.elim(st, &*rc, nilf, consf, namef),
            List::Art(ref art) => {
                let list = st.force(art);
                self.elim(st, &list, nilf, consf, namef)
            }
        }
    }
}

fn tree_of_list_rec_memo <A:Adapton, X:Hash+Clone, T:TreeT<A,X,X>, L:ListT<A,X>>
    (st:&mut A, l:&L, list:&L::List, left_tree:&T::Tree, left_tree_lev:u32, parent_lev:u32) ->
    (T::Tree, L::List)
{
    let t = st.thunk (ArtId::Eager,
                      prog_pt!(tree_of_list_rec),
                      Rc::new(Box::new(|st, args|{
                          let (l, list, left_tree, left_tree_lev, parent_lev) = args ;
                          tree_of_list_rec::<A,X,T,L>
                              (st, l, list, left_tree, left_tree_lev, parent_lev)
                      })),
                      (l, list, left_tree, left_tree_lev, parent_lev)
                      ) ;
    st.force( &t )
}

fn tree_of_list_rec <A:Adapton, X:Hash+Clone, T:TreeT<A,X,X>, L:ListT<A,X>>
    (st:&mut A, l:&L, list:&L::List, left_tree:&T::Tree, left_tree_lev:u32, parent_lev:u32)
     -> (T::Tree, L::List)
{
    l.elim (
        st, &list,
        /* Nil */  |st| ( T::nil(st), L::nil(st) ),
        /* Cons */ |st, hd, rest| {
            let lev_hd = (1 + (my_hash(hd).leading_zeros())) as u32 ;
            if left_tree_lev <= lev_hd && lev_hd <= parent_lev {
                let nil = T::nil(st) ;
                let (right_tree, rest) = tree_of_list_rec::<A,X,T,L> ( st, l, rest, &nil, 0 as u32, lev_hd ) ;
                let tree = T::bin ( st, hd.clone(), Box::new(left_tree.clone()), Box::new(right_tree) ) ;
                tree_of_list_rec::<A,X,T,L> ( st, l, &rest, &tree, lev_hd, parent_lev )
            }
            else {
                let rest = L::cons(st, hd.clone(), rest.clone()) ;
                (left_tree.clone(), rest)
            }},
        /* Name */ |st, nm, rest| {
            let lev_nm = (1 + 64 + (my_hash(nm).leading_zeros())) as u32 ;
            if left_tree_lev <= lev_nm && lev_nm <= parent_lev {
                let nil = T::nil(st) ;
                // Done: Memoized the recursive calls to tree_of_list_rec.
                let (right_tree, rest) = tree_of_list_rec_memo::<A,X,T,L> ( st, l, rest, &nil, 0 as u32, lev_nm ) ;
                // TODO: Place left_ and right_ trees into articulations (not Boxes), named by name.
                let tree = T::name( st, nm.clone(), Box::new(left_tree.clone()), Box::new(right_tree) ) ;
                tree_of_list_rec_memo::<A,X,T,L> ( st, l, &rest, &tree, lev_nm, parent_lev )
            }
            else {
                let rest = L::name(st, nm.clone(), rest.clone()) ;
                (left_tree.clone(), rest)
            }}
        )
}

pub fn tree_of_list <A:Adapton, X:Hash+Clone, T:TreeT<A,X,X>, L:ListT<A,X>>
    (l:&L, st:&mut A, list:&L::List) -> T::Tree
{
    let nil = T::nil(st) ;
    let (tree, rest) = tree_of_list_rec::<A,X,T,L> (st, l, list, &nil, 0 as u32, u32::max_value()) ;
    assert!( l.is_empty( st, &rest ) );
    tree
}
<|endoftext|>


<commit_before>extern crate ctrlc;

extern crate lulzvm;

extern crate env_logger;

#[macro_use]
extern crate clap;

use clap::{ArgGroup, ArgMatches, App};
use lulzvm::vm::VM;
use std::env;
use std::fs::File;
use std::io::{stdin, stdout, Read, Result};
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};

fn main() {
    let matches = App::new("LulzVM")
        .args_from_usage("[FILE] 'Bytecode executable'
                            -d, --debug 'Enable debug messages'")
        .group(ArgGroup::with_name("required")
            .args(&["FILE"])
            .required(true))
        .get_matches();

    match do_checked_main(matches) {
        Ok(_) => (),
        Err(e) => println!("Error: {:?}", e),
    }
}

fn do_checked_main(matches: ArgMatches) -> Result<()> {
    let executable_filename = matches.value_of("FILE").unwrap();

    let mut executable = Vec::new();
    let mut executable_file = try!(File::open(executable_filename));
    let _ = try!(executable_file.read_to_end(&mut executable));

    if matches.is_present("debug") {
        env::set_var("RUST_LOG", "lulzvm::vm=debug");
        let _ = env_logger::init().unwrap();
    }

    let terminating = Arc::new(AtomicBool::new(false));
    let r = terminating.clone();
    ctrlc::set_handler(move || {
        r.store(true, Ordering::Relaxed);
    });

    let mut vm = VM::new(stdin(), stdout(), executable, terminating);
    vm.run();

    Ok(())
}
<commit_msg>add more logging details<commit_after>extern crate ctrlc;

extern crate lulzvm;

#[macro_use]
extern crate log;
extern crate env_logger;

#[macro_use]
extern crate clap;

use clap::{ArgGroup, ArgMatches, App};
use lulzvm::vm::VM;
use std::env;
use std::fs::File;
use std::io::{stdin, stdout, Read, Result};
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};

fn main() {
    let matches = App::new("LulzVM")
        .args_from_usage("[FILE] 'Bytecode executable'
                            -d, --debug 'Enable debug messages'")
        .group(ArgGroup::with_name("required")
            .args(&["FILE"])
            .required(true))
        .get_matches();

    match do_checked_main(matches) {
        Ok(_) => (),
        Err(e) => println!("Error: {:?}", e),
    }
}

fn do_checked_main(matches: ArgMatches) -> Result<()> {
    let executable_filename = matches.value_of("FILE").unwrap();

    let mut executable = Vec::new();
    let mut executable_file = try!(File::open(executable_filename));
    let _ = try!(executable_file.read_to_end(&mut executable));

    if matches.is_present("debug") {
        env::set_var("RUST_LOG", "lulzvm::vm=debug,error,info,warn,trace");
        let _ = env_logger::init().unwrap();
    }

    let terminating = Arc::new(AtomicBool::new(false));
    let r = terminating.clone();
    ctrlc::set_handler(move || {
        info!("Terminating...");
        r.store(true, Ordering::Relaxed);
    });

    let mut vm = VM::new(stdin(), stdout(), executable, terminating);
    vm.run();

    Ok(())
}
<|endoftext|>