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

extern crate winit;
extern crate xcb;
extern crate vk_sys as vk;
extern crate gfx_core;
extern crate gfx_device_vulkan;

use std::{mem, ptr};

pub fn init_winit(builder: winit::WindowBuilder) -> (winit::Window, gfx_device_vulkan::GraphicsQueue, gfx_device_vulkan::Factory) {
    let (device, factory, _backend) = gfx_device_vulkan::create(&builder.window.title, 1, &[],
        &["VK_KHR_surface", "VK_KHR_xcb_surface"], &["VK_KHR_swapchain"]);
    let win = builder.build().unwrap();
    (win, device, factory)
}

pub struct Window {
    connection: xcb::Connection,
    _foreground: u32,
    window: u32,
    _swapchain: vk::SwapchainKHR,
    _images: Vec<vk::Image>,
}

impl Window {
    pub fn wait_draw(&mut self) -> Option<bool> {
        let ev = match self.connection.wait_for_event() {
            Some(ev) => ev,
            None => return None,
        };
        //self.connection.flush();
        match ev.response_type() & 0x80 {
            xcb::EXPOSE => Some(true),
            xcb::KEY_PRESS => None,
            _ => Some(false)
        }
    }
}

impl Drop for Window {
    fn drop(&mut self) {
        xcb::unmap_window(&self.connection, self.window);
        xcb::destroy_window(&self.connection, self.window);
        self.connection.flush();
    }
}

pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vulkan::GraphicsQueue, gfx_device_vulkan::Factory) {
    let (device, factory, backend) = gfx_device_vulkan::create(title, 1, &[],
        &["VK_KHR_surface", "VK_KHR_xcb_surface"], &["VK_KHR_swapchain"]);

    let (conn, screen_num) = xcb::Connection::connect(None).unwrap();
    let (window, foreground) = {
        let setup = conn.get_setup();
        let screen = setup.roots().nth(screen_num as usize).unwrap();

        let foreground = conn.generate_id();
        xcb::create_gc(&conn, foreground, screen.root(), &[
                (xcb::GC_FOREGROUND, screen.black_pixel()),
                (xcb::GC_GRAPHICS_EXPOSURES, 0),
        ]);

        let win = conn.generate_id();
        xcb::create_window(&conn,
            xcb::COPY_FROM_PARENT as u8,
            win,
            screen.root(),
            0, 0,
            width as u16, height as u16,
            10,
            xcb::WINDOW_CLASS_INPUT_OUTPUT as u16,
            screen.root_visual(), &[
                (xcb::CW_BACK_PIXEL, screen.black_pixel()),
                (xcb::CW_EVENT_MASK, xcb::EVENT_MASK_KEY_PRESS | xcb::EVENT_MASK_EXPOSURE),
            ]
        );
        (win, foreground)
    };

    xcb::map_window(&conn, window);
    xcb::change_property(&conn, xcb::PROP_MODE_REPLACE as u8, window,
        xcb::ATOM_WM_NAME, xcb::ATOM_STRING, 8, title.as_bytes());
    conn.flush();

    let surface = {
        let (inst, vk) = backend.get_instance();
        let info = vk::XcbSurfaceCreateInfoKHR {
            sType: vk::STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR,
            pNext: ptr::null(),
            flags: 0,
            connection: conn.get_raw_conn() as *const _,
            window: window as *const _, //HACK! TODO: fix the bindings
        };

        unsafe {
            let mut out = mem::zeroed();
            assert_eq!(vk::SUCCESS, vk.CreateXcbSurfaceKHR(inst, &info, ptr::null(), &mut out));
            out
        }
    };

    let (dev, vk) = backend.get_device();
    let mut images: [vk::Image; 2] = [0; 2];
    let mut num = images.len() as u32;

    let info = vk::SwapchainCreateInfoKHR {
        sType: vk::STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
        pNext: ptr::null(),
        flags: 0,
        surface: surface,
        minImageCount: num,
        imageFormat: vk::FORMAT_R8G8B8A8_UNORM,
        imageColorSpace: vk::COLORSPACE_SRGB_NONLINEAR_KHR,
        imageExtent: vk::Extent2D { width: width, height: height },
        imageArrayLayers: 1,
        imageUsage: vk::IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
        imageSharingMode: vk::SHARING_MODE_EXCLUSIVE,
        queueFamilyIndexCount: 1,
        pQueueFamilyIndices: &0,
        preTransform: vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
        compositeAlpha: vk::COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
        presentMode: vk::PRESENT_MODE_FIFO_RELAXED_KHR,
        clipped: vk::TRUE,
        oldSwapchain: 0,
    };

    let swapchain = unsafe {
        let mut out = mem::zeroed();
        assert_eq!(vk::SUCCESS, vk.CreateSwapchainKHR(dev, &info, ptr::null(), &mut out));
        out
    };

    assert_eq!(vk::SUCCESS, unsafe {
        vk.GetSwapchainImagesKHR(dev, swapchain, &mut num, images.as_mut_ptr())
    });

    let win = Window {
        connection: conn,
        _foreground: foreground,
        window: window,
        _swapchain: swapchain,
        _images: images[..num as usize].to_vec(),
    };
    (win, device, factory)
}
<commit_msg>[vk] creating swapchain target views<commit_after>// Copyright 2016 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate winit;
extern crate xcb;
extern crate vk_sys as vk;
extern crate gfx_core;
extern crate gfx_device_vulkan;

use std::{mem, ptr};
use gfx_core::format;

pub fn init_winit(builder: winit::WindowBuilder) -> (winit::Window, gfx_device_vulkan::GraphicsQueue, gfx_device_vulkan::Factory) {
    let (device, factory, _backend) = gfx_device_vulkan::create(&builder.window.title, 1, &[],
        &["VK_KHR_surface", "VK_KHR_xcb_surface"], &["VK_KHR_swapchain"]);
    let win = builder.build().unwrap();
    (win, device, factory)
}

pub struct Window {
    connection: xcb::Connection,
    _foreground: u32,
    window: u32,
    _swapchain: vk::SwapchainKHR,
    _targets: Vec<gfx_core::handle::RenderTargetView<gfx_device_vulkan::Resources, format::Rgba8>>,
}

impl Window {
    pub fn wait_draw(&mut self) -> Option<bool> {
        let ev = match self.connection.wait_for_event() {
            Some(ev) => ev,
            None => return None,
        };
        //self.connection.flush();
        match ev.response_type() & 0x80 {
            xcb::EXPOSE => Some(true),
            xcb::KEY_PRESS => None,
            _ => Some(false)
        }
    }
}

impl Drop for Window {
    fn drop(&mut self) {
        xcb::unmap_window(&self.connection, self.window);
        xcb::destroy_window(&self.connection, self.window);
        self.connection.flush();
    }
}

pub fn init_xcb(title: &str, width: u32, height: u32) -> (Window, gfx_device_vulkan::GraphicsQueue, gfx_device_vulkan::Factory) {
    let (device, mut factory, backend) = gfx_device_vulkan::create(title, 1, &[],
        &["VK_KHR_surface", "VK_KHR_xcb_surface"], &["VK_KHR_swapchain"]);

    let (conn, screen_num) = xcb::Connection::connect(None).unwrap();
    let (window, foreground) = {
        let setup = conn.get_setup();
        let screen = setup.roots().nth(screen_num as usize).unwrap();

        let foreground = conn.generate_id();
        xcb::create_gc(&conn, foreground, screen.root(), &[
                (xcb::GC_FOREGROUND, screen.black_pixel()),
                (xcb::GC_GRAPHICS_EXPOSURES, 0),
        ]);

        let win = conn.generate_id();
        xcb::create_window(&conn,
            xcb::COPY_FROM_PARENT as u8,
            win,
            screen.root(),
            0, 0,
            width as u16, height as u16,
            10,
            xcb::WINDOW_CLASS_INPUT_OUTPUT as u16,
            screen.root_visual(), &[
                (xcb::CW_BACK_PIXEL, screen.black_pixel()),
                (xcb::CW_EVENT_MASK, xcb::EVENT_MASK_KEY_PRESS | xcb::EVENT_MASK_EXPOSURE),
            ]
        );
        (win, foreground)
    };

    xcb::map_window(&conn, window);
    xcb::change_property(&conn, xcb::PROP_MODE_REPLACE as u8, window,
        xcb::ATOM_WM_NAME, xcb::ATOM_STRING, 8, title.as_bytes());
    conn.flush();

    let surface = {
        let (inst, vk) = backend.get_instance();
        let info = vk::XcbSurfaceCreateInfoKHR {
            sType: vk::STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR,
            pNext: ptr::null(),
            flags: 0,
            connection: conn.get_raw_conn() as *const _,
            window: window as *const _, //HACK! TODO: fix the bindings
        };

        unsafe {
            let mut out = mem::zeroed();
            assert_eq!(vk::SUCCESS, vk.CreateXcbSurfaceKHR(inst, &info, ptr::null(), &mut out));
            out
        }
    };

    let (dev, vk) = backend.get_device();
    let mut images: [vk::Image; 2] = [0; 2];
    let mut num = images.len() as u32;

    let swapchain_info = vk::SwapchainCreateInfoKHR {
        sType: vk::STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
        pNext: ptr::null(),
        flags: 0,
        surface: surface,
        minImageCount: num,
        imageFormat: vk::FORMAT_R8G8B8A8_UNORM,
        imageColorSpace: vk::COLORSPACE_SRGB_NONLINEAR_KHR,
        imageExtent: vk::Extent2D { width: width, height: height },
        imageArrayLayers: 1,
        imageUsage: vk::IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
        imageSharingMode: vk::SHARING_MODE_EXCLUSIVE,
        queueFamilyIndexCount: 1,
        pQueueFamilyIndices: &0,
        preTransform: vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
        compositeAlpha: vk::COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
        presentMode: vk::PRESENT_MODE_FIFO_RELAXED_KHR,
        clipped: vk::TRUE,
        oldSwapchain: 0,
    };

    let swapchain = unsafe {
        let mut out = mem::zeroed();
        assert_eq!(vk::SUCCESS, vk.CreateSwapchainKHR(dev, &swapchain_info, ptr::null(), &mut out));
        out
    };

    assert_eq!(vk::SUCCESS, unsafe {
        vk.GetSwapchainImagesKHR(dev, swapchain, &mut num, images.as_mut_ptr())
    });

    let format = format::Format(format::SurfaceType::R8_G8_B8_A8, format::ChannelType::Unorm);
    let targets = images[.. num as usize].iter().map(|image| {
        use gfx_core::factory::Typed;
        let raw_view = factory.view_swapchain_image(*image, format, (width, height)).unwrap();
        Typed::new(raw_view)
    }).collect();

    let win = Window {
        connection: conn,
        _foreground: foreground,
        window: window,
        _swapchain: swapchain,
        _targets: targets,
    };
    (win, device, factory)
}
<|endoftext|>


<commit_before>//! A batteries included runtime for applications using Tokio.
//!
//! Applications using Tokio require some runtime support in order to work:
//!
//! * A [reactor] to drive I/O resources.
//! * An [executor] to execute tasks that use these I/O resources.
//! * A [timer] for scheduling work to run after a set period of time.
//!
//! While it is possible to setup each component manually, this involves a bunch
//! of boilerplate.
//!
//! [`Runtime`] bundles all of these various runtime components into a single
//! handle that can be started and shutdown together, eliminating the necessary
//! boilerplate to run a Tokio application.
//!
//! Most applications wont need to use [`Runtime`] directly. Instead, they will
//! use the [`run`] function, which uses [`Runtime`] under the hood.
//!
//! Creating a [`Runtime`] does the following:
//!
//! * Spawn a background thread running a [`Reactor`] instance.
//! * Start a [`ThreadPool`] for executing futures.
//! * Run an instance of [`Timer`] **per** thread pool worker thread.
//!
//! The thread pool uses a work-stealing strategy and is configured to start a
//! worker thread for each CPU core available on the system. This tends to be
//! the ideal setup for Tokio applications.
//!
//! A timer per thread pool worker thread is used to minimize the amount of
//! synchronization that is required for working with the timer.
//!
//! # Usage
//!
//! Most applications will use the [`run`] function. This takes a future to
//! "seed" the application, blocking the thread until the runtime becomes
//! [idle].
//!
//! ```rust
//! # extern crate tokio;
//! # extern crate futures;
//! # use futures::{Future, Stream};
//! use tokio::net::TcpListener;
//!
//! # fn process<T>(_: T) -> Box<Future<Item = (), Error = ()> + Send> {
//! # unimplemented!();
//! # }
//! # fn dox() {
//! # let addr = "127.0.0.1:8080".parse().unwrap();
//! let listener = TcpListener::bind(&addr).unwrap();
//!
//! let server = listener.incoming()
//!     .map_err(|e| println!("error = {:?}", e))
//!     .for_each(|socket| {
//!         tokio::spawn(process(socket))
//!     });
//!
//! tokio::run(server);
//! # }
//! # pub fn main() {}
//! ```
//!
//! In this function, the `run` function blocks until the runtime becomes idle.
//! See [`shutdown_on_idle`][idle] for more shutdown details.
//!
//! From within the context of the runtime, additional tasks are spawned using
//! the [`tokio::spawn`] function. Futures spawned using this function will be
//! executed on the same thread pool used by the [`Runtime`].
//!
//! A [`Runtime`] instance can also be used directly.
//!
//! ```rust
//! # extern crate tokio;
//! # extern crate futures;
//! # use futures::{Future, Stream};
//! use tokio::runtime::Runtime;
//! use tokio::net::TcpListener;
//!
//! # fn process<T>(_: T) -> Box<Future<Item = (), Error = ()> + Send> {
//! # unimplemented!();
//! # }
//! # fn dox() {
//! # let addr = "127.0.0.1:8080".parse().unwrap();
//! let listener = TcpListener::bind(&addr).unwrap();
//!
//! let server = listener.incoming()
//!     .map_err(|e| println!("error = {:?}", e))
//!     .for_each(|socket| {
//!         tokio::spawn(process(socket))
//!     });
//!
//! // Create the runtime
//! let mut rt = Runtime::new().unwrap();
//!
//! // Spawn the server task
//! rt.spawn(server);
//!
//! // Wait until the runtime becomes idle and shut it down.
//! rt.shutdown_on_idle()
//!     .wait().unwrap();
//! # }
//! # pub fn main() {}
//! ```
//!
//! [reactor]: ../reactor/struct.Reactor.html
//! [executor]: https://tokio.rs/docs/getting-started/runtime-model/#executors
//! [timer]: ../timer/index.html
//! [`Runtime`]: struct.Runtime.html
//! [`Reactor`]: ../reactor/struct.Reactor.html
//! [`ThreadPool`]: ../executor/thread_pool/struct.ThreadPool.html
//! [`run`]: fn.run.html
//! [idle]: struct.Runtime.html#method.shutdown_on_idle
//! [`tokio::spawn`]: ../executor/fn.spawn.html
//! [`Timer`]: https://docs.rs/tokio-timer/0.2/tokio_timer/timer/struct.Timer.html

mod builder;
pub mod current_thread;
mod shutdown;
mod task_executor;

pub use self::builder::Builder;
pub use self::shutdown::Shutdown;
pub use self::task_executor::TaskExecutor;

use reactor::{Background, Handle};

use std::io;

use tokio_threadpool as threadpool;

use futures::future::Future;
#[cfg(feature = "unstable-futures")]
use futures2;

/// Handle to the Tokio runtime.
///
/// The Tokio runtime includes a reactor as well as an executor for running
/// tasks.
///
/// Instances of `Runtime` can be created using [`new`] or [`Builder`]. However,
/// most users will use [`tokio::run`], which uses a `Runtime` internally.
///
/// See [module level][mod] documentation for more details.
///
/// [mod]: index.html
/// [`new`]: #method.new
/// [`Builder`]: struct.Builder.html
/// [`tokio::run`]: fn.run.html
#[derive(Debug)]
pub struct Runtime {
    inner: Option<Inner>,
}

#[derive(Debug)]
struct Inner {
    /// Reactor running on a background thread.
    reactor: Background,

    /// Task execution pool.
    pool: threadpool::ThreadPool,
}

// ===== impl Runtime =====

/// Start the Tokio runtime using the supplied future to bootstrap execution.
///
/// This function is used to bootstrap the execution of a Tokio application. It
/// does the following:
///
/// * Start the Tokio runtime using a default configuration.
/// * Spawn the given future onto the thread pool.
/// * Block the current thread until the runtime shuts down.
///
/// Note that the function will not return immediately once `future` has
/// completed. Instead it waits for the entire runtime to become idle.
///
/// See the [module level][mod] documentation for more details.
///
/// # Examples
///
/// ```rust
/// # extern crate tokio;
/// # extern crate futures;
/// # use futures::{Future, Stream};
/// use tokio::net::TcpListener;
///
/// # fn process<T>(_: T) -> Box<Future<Item = (), Error = ()> + Send> {
/// # unimplemented!();
/// # }
/// # fn dox() {
/// # let addr = "127.0.0.1:8080".parse().unwrap();
/// let listener = TcpListener::bind(&addr).unwrap();
///
/// let server = listener.incoming()
///     .map_err(|e| println!("error = {:?}", e))
///     .for_each(|socket| {
///         tokio::spawn(process(socket))
///     });
///
/// tokio::run(server);
/// # }
/// # pub fn main() {}
/// ```
///
/// # Panics
///
/// This function panics if called from the context of an executor.
///
/// [mod]: ../index.html
pub fn run<F>(future: F)
where F: Future<Item = (), Error = ()> + Send + 'static,
{
    let mut runtime = Runtime::new().unwrap();
    runtime.spawn(future);
    runtime.shutdown_on_idle().wait().unwrap();
}

/// Start the Tokio runtime using the supplied future to bootstrap execution.
///
/// Identical to `run` but works with futures 0.2-style futures.
#[cfg(feature = "unstable-futures")]
pub fn run2<F>(future: F)
    where F: futures2::Future<Item = (), Error = futures2::Never> + Send + 'static,
{
    let mut runtime = Runtime::new().unwrap();
    runtime.spawn2(future);
    runtime.shutdown_on_idle().wait().unwrap();
}

impl Runtime {
    /// Create a new runtime instance with default configuration values.
    ///
    /// This results in a reactor, thread pool, and timer being initialized. The
    /// thread pool will not spawn any worker threads until it needs to, i.e.
    /// tasks are scheduled to run.
    ///
    /// Most users will not need to call this function directly, instead they
    /// will use [`tokio::run`][fn.run.html].
    ///
    /// See [module level][mod] documentation for more details.
    ///
    /// # Examples
    ///
    /// Creating a new `Runtime` with default configuration values.
    ///
    /// ```
    /// use tokio::runtime::Runtime;
    /// use tokio::prelude::*;
    ///
    /// let rt = Runtime::new()
    ///     .unwrap();
    ///
    /// // Use the runtime...
    ///
    /// // Shutdown the runtime
    /// rt.shutdown_now()
    ///     .wait().unwrap();
    /// ```
    ///
    /// [mod]: index.html
    pub fn new() -> io::Result<Self> {
        Builder::new().build()
    }

    #[deprecated(since = "0.1.5", note = "use `reactor` instead")]
    #[doc(hidden)]
    pub fn handle(&self) -> &Handle {
        self.reactor()
    }

    /// Return a reference to the reactor handle for this runtime instance.
    ///
    /// The returned handle reference can be cloned in order to get an owned
    /// value of the handle. This handle can be used to initialize I/O resources
    /// (like TCP or UDP sockets) that will not be used on the runtime.
    ///
    /// # Examples
    ///
    /// ```
    /// use tokio::runtime::Runtime;
    ///
    /// let rt = Runtime::new()
    ///     .unwrap();
    ///
    /// let reactor_handle = rt.reactor().clone();
    ///
    /// // use `reactor_handle`
    /// ```
    pub fn reactor(&self) -> &Handle {
        self.inner().reactor.handle()
    }

    /// Return a handle to the runtime's executor.
    ///
    /// The returned handle can be used to spawn tasks that run on this runtime.
    ///
    /// # Examples
    ///
    /// ```
    /// use tokio::runtime::Runtime;
    ///
    /// let rt = Runtime::new()
    ///     .unwrap();
    ///
    /// let executor_handle = rt.executor();
    ///
    /// // use `executor_handle`
    /// ```
    pub fn executor(&self) -> TaskExecutor {
        let inner = self.inner().pool.sender().clone();
        TaskExecutor { inner }
    }

    /// Spawn a future onto the Tokio runtime.
    ///
    /// This spawns the given future onto the runtime's executor, usually a
    /// thread pool. The thread pool is then responsible for polling the future
    /// until it completes.
    ///
    /// See [module level][mod] documentation for more details.
    ///
    /// [mod]: index.html
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate tokio;
    /// # extern crate futures;
    /// # use futures::{future, Future, Stream};
    /// use tokio::runtime::Runtime;
    ///
    /// # fn dox() {
    /// // Create the runtime
    /// let mut rt = Runtime::new().unwrap();
    ///
    /// // Spawn a future onto the runtime
    /// rt.spawn(future::lazy(|| {
    ///     println!("now running on a worker thread");
    ///     Ok(())
    /// }));
    /// # }
    /// # pub fn main() {}
    /// ```
    ///
    /// # Panics
    ///
    /// This function panics if the spawn fails. Failure occurs if the executor
    /// is currently at capacity and is unable to spawn a new future.
    pub fn spawn<F>(&mut self, future: F) -> &mut Self
    where F: Future<Item = (), Error = ()> + Send + 'static,
    {
        self.inner_mut().pool.sender().spawn(future).unwrap();
        self
    }

    /// Spawn a futures 0.2-style future onto the Tokio runtime.
    ///
    /// Otherwise identical to `spawn`
    #[cfg(feature = "unstable-futures")]
    pub fn spawn2<F>(&mut self, future: F) -> &mut Self
        where F: futures2::Future<Item = (), Error = futures2::Never> + Send + 'static,
    {
        futures2::executor::Executor::spawn(
            self.inner_mut().pool.sender_mut(), Box::new(future)
        ).unwrap();
        self
    }

    /// Signals the runtime to shutdown once it becomes idle.
    ///
    /// Returns a future that completes once the shutdown operation has
    /// completed.
    ///
    /// This function can be used to perform a graceful shutdown of the runtime.
    ///
    /// The runtime enters an idle state once **all** of the following occur.
    ///
    /// * The thread pool has no tasks to execute, i.e., all tasks that were
    ///   spawned have completed.
    /// * The reactor is not managing any I/O resources.
    ///
    /// See [module level][mod] documentation for more details.
    ///
    /// # Examples
    ///
    /// ```
    /// use tokio::runtime::Runtime;
    /// use tokio::prelude::*;
    ///
    /// let rt = Runtime::new()
    ///     .unwrap();
    ///
    /// // Use the runtime...
    ///
    /// // Shutdown the runtime
    /// rt.shutdown_on_idle()
    ///     .wait().unwrap();
    /// ```
    ///
    /// [mod]: index.html
    pub fn shutdown_on_idle(mut self) -> Shutdown {
        let inner = self.inner.take().unwrap();

        let inner = Box::new({
            let pool = inner.pool;
            let reactor = inner.reactor;

            pool.shutdown_on_idle().and_then(|_| {
                reactor.shutdown_on_idle()
            })
        });

        Shutdown { inner }
    }

    /// Signals the runtime to shutdown immediately.
    ///
    /// Returns a future that completes once the shutdown operation has
    /// completed.
    ///
    /// This function will forcibly shutdown the runtime, causing any
    /// in-progress work to become canceled. The shutdown steps are:
    ///
    /// * Drain any scheduled work queues.
    /// * Drop any futures that have not yet completed.
    /// * Drop the reactor.
    ///
    /// Once the reactor has dropped, any outstanding I/O resources bound to
    /// that reactor will no longer function. Calling any method on them will
    /// result in an error.
    ///
    /// See [module level][mod] documentation for more details.
    ///
    /// # Examples
    ///
    /// ```
    /// use tokio::runtime::Runtime;
    /// use tokio::prelude::*;
    ///
    /// let rt = Runtime::new()
    ///     .unwrap();
    ///
    /// // Use the runtime...
    ///
    /// // Shutdown the runtime
    /// rt.shutdown_now()
    ///     .wait().unwrap();
    /// ```
    ///
    /// [mod]: index.html
    pub fn shutdown_now(mut self) -> Shutdown {
        let inner = self.inner.take().unwrap();
        Shutdown::shutdown_now(inner)
    }

    fn inner(&self) -> &Inner {
        self.inner.as_ref().unwrap()
    }

    fn inner_mut(&mut self) -> &mut Inner {
        self.inner.as_mut().unwrap()
    }
}

impl Drop for Runtime {
    fn drop(&mut self) {
        if let Some(inner) = self.inner.take() {
            let shutdown = Shutdown::shutdown_now(inner);
            let _ = shutdown.wait();
        }
    }
}
<commit_msg>Fix Runtime::new's doc link to tokio::run (#371)<commit_after>//! A batteries included runtime for applications using Tokio.
//!
//! Applications using Tokio require some runtime support in order to work:
//!
//! * A [reactor] to drive I/O resources.
//! * An [executor] to execute tasks that use these I/O resources.
//! * A [timer] for scheduling work to run after a set period of time.
//!
//! While it is possible to setup each component manually, this involves a bunch
//! of boilerplate.
//!
//! [`Runtime`] bundles all of these various runtime components into a single
//! handle that can be started and shutdown together, eliminating the necessary
//! boilerplate to run a Tokio application.
//!
//! Most applications wont need to use [`Runtime`] directly. Instead, they will
//! use the [`run`] function, which uses [`Runtime`] under the hood.
//!
//! Creating a [`Runtime`] does the following:
//!
//! * Spawn a background thread running a [`Reactor`] instance.
//! * Start a [`ThreadPool`] for executing futures.
//! * Run an instance of [`Timer`] **per** thread pool worker thread.
//!
//! The thread pool uses a work-stealing strategy and is configured to start a
//! worker thread for each CPU core available on the system. This tends to be
//! the ideal setup for Tokio applications.
//!
//! A timer per thread pool worker thread is used to minimize the amount of
//! synchronization that is required for working with the timer.
//!
//! # Usage
//!
//! Most applications will use the [`run`] function. This takes a future to
//! "seed" the application, blocking the thread until the runtime becomes
//! [idle].
//!
//! ```rust
//! # extern crate tokio;
//! # extern crate futures;
//! # use futures::{Future, Stream};
//! use tokio::net::TcpListener;
//!
//! # fn process<T>(_: T) -> Box<Future<Item = (), Error = ()> + Send> {
//! # unimplemented!();
//! # }
//! # fn dox() {
//! # let addr = "127.0.0.1:8080".parse().unwrap();
//! let listener = TcpListener::bind(&addr).unwrap();
//!
//! let server = listener.incoming()
//!     .map_err(|e| println!("error = {:?}", e))
//!     .for_each(|socket| {
//!         tokio::spawn(process(socket))
//!     });
//!
//! tokio::run(server);
//! # }
//! # pub fn main() {}
//! ```
//!
//! In this function, the `run` function blocks until the runtime becomes idle.
//! See [`shutdown_on_idle`][idle] for more shutdown details.
//!
//! From within the context of the runtime, additional tasks are spawned using
//! the [`tokio::spawn`] function. Futures spawned using this function will be
//! executed on the same thread pool used by the [`Runtime`].
//!
//! A [`Runtime`] instance can also be used directly.
//!
//! ```rust
//! # extern crate tokio;
//! # extern crate futures;
//! # use futures::{Future, Stream};
//! use tokio::runtime::Runtime;
//! use tokio::net::TcpListener;
//!
//! # fn process<T>(_: T) -> Box<Future<Item = (), Error = ()> + Send> {
//! # unimplemented!();
//! # }
//! # fn dox() {
//! # let addr = "127.0.0.1:8080".parse().unwrap();
//! let listener = TcpListener::bind(&addr).unwrap();
//!
//! let server = listener.incoming()
//!     .map_err(|e| println!("error = {:?}", e))
//!     .for_each(|socket| {
//!         tokio::spawn(process(socket))
//!     });
//!
//! // Create the runtime
//! let mut rt = Runtime::new().unwrap();
//!
//! // Spawn the server task
//! rt.spawn(server);
//!
//! // Wait until the runtime becomes idle and shut it down.
//! rt.shutdown_on_idle()
//!     .wait().unwrap();
//! # }
//! # pub fn main() {}
//! ```
//!
//! [reactor]: ../reactor/struct.Reactor.html
//! [executor]: https://tokio.rs/docs/getting-started/runtime-model/#executors
//! [timer]: ../timer/index.html
//! [`Runtime`]: struct.Runtime.html
//! [`Reactor`]: ../reactor/struct.Reactor.html
//! [`ThreadPool`]: ../executor/thread_pool/struct.ThreadPool.html
//! [`run`]: fn.run.html
//! [idle]: struct.Runtime.html#method.shutdown_on_idle
//! [`tokio::spawn`]: ../executor/fn.spawn.html
//! [`Timer`]: https://docs.rs/tokio-timer/0.2/tokio_timer/timer/struct.Timer.html

mod builder;
pub mod current_thread;
mod shutdown;
mod task_executor;

pub use self::builder::Builder;
pub use self::shutdown::Shutdown;
pub use self::task_executor::TaskExecutor;

use reactor::{Background, Handle};

use std::io;

use tokio_threadpool as threadpool;

use futures::future::Future;
#[cfg(feature = "unstable-futures")]
use futures2;

/// Handle to the Tokio runtime.
///
/// The Tokio runtime includes a reactor as well as an executor for running
/// tasks.
///
/// Instances of `Runtime` can be created using [`new`] or [`Builder`]. However,
/// most users will use [`tokio::run`], which uses a `Runtime` internally.
///
/// See [module level][mod] documentation for more details.
///
/// [mod]: index.html
/// [`new`]: #method.new
/// [`Builder`]: struct.Builder.html
/// [`tokio::run`]: fn.run.html
#[derive(Debug)]
pub struct Runtime {
    inner: Option<Inner>,
}

#[derive(Debug)]
struct Inner {
    /// Reactor running on a background thread.
    reactor: Background,

    /// Task execution pool.
    pool: threadpool::ThreadPool,
}

// ===== impl Runtime =====

/// Start the Tokio runtime using the supplied future to bootstrap execution.
///
/// This function is used to bootstrap the execution of a Tokio application. It
/// does the following:
///
/// * Start the Tokio runtime using a default configuration.
/// * Spawn the given future onto the thread pool.
/// * Block the current thread until the runtime shuts down.
///
/// Note that the function will not return immediately once `future` has
/// completed. Instead it waits for the entire runtime to become idle.
///
/// See the [module level][mod] documentation for more details.
///
/// # Examples
///
/// ```rust
/// # extern crate tokio;
/// # extern crate futures;
/// # use futures::{Future, Stream};
/// use tokio::net::TcpListener;
///
/// # fn process<T>(_: T) -> Box<Future<Item = (), Error = ()> + Send> {
/// # unimplemented!();
/// # }
/// # fn dox() {
/// # let addr = "127.0.0.1:8080".parse().unwrap();
/// let listener = TcpListener::bind(&addr).unwrap();
///
/// let server = listener.incoming()
///     .map_err(|e| println!("error = {:?}", e))
///     .for_each(|socket| {
///         tokio::spawn(process(socket))
///     });
///
/// tokio::run(server);
/// # }
/// # pub fn main() {}
/// ```
///
/// # Panics
///
/// This function panics if called from the context of an executor.
///
/// [mod]: ../index.html
pub fn run<F>(future: F)
where F: Future<Item = (), Error = ()> + Send + 'static,
{
    let mut runtime = Runtime::new().unwrap();
    runtime.spawn(future);
    runtime.shutdown_on_idle().wait().unwrap();
}

/// Start the Tokio runtime using the supplied future to bootstrap execution.
///
/// Identical to `run` but works with futures 0.2-style futures.
#[cfg(feature = "unstable-futures")]
pub fn run2<F>(future: F)
    where F: futures2::Future<Item = (), Error = futures2::Never> + Send + 'static,
{
    let mut runtime = Runtime::new().unwrap();
    runtime.spawn2(future);
    runtime.shutdown_on_idle().wait().unwrap();
}

impl Runtime {
    /// Create a new runtime instance with default configuration values.
    ///
    /// This results in a reactor, thread pool, and timer being initialized. The
    /// thread pool will not spawn any worker threads until it needs to, i.e.
    /// tasks are scheduled to run.
    ///
    /// Most users will not need to call this function directly, instead they
    /// will use [`tokio::run`](fn.run.html).
    ///
    /// See [module level][mod] documentation for more details.
    ///
    /// # Examples
    ///
    /// Creating a new `Runtime` with default configuration values.
    ///
    /// ```
    /// use tokio::runtime::Runtime;
    /// use tokio::prelude::*;
    ///
    /// let rt = Runtime::new()
    ///     .unwrap();
    ///
    /// // Use the runtime...
    ///
    /// // Shutdown the runtime
    /// rt.shutdown_now()
    ///     .wait().unwrap();
    /// ```
    ///
    /// [mod]: index.html
    pub fn new() -> io::Result<Self> {
        Builder::new().build()
    }

    #[deprecated(since = "0.1.5", note = "use `reactor` instead")]
    #[doc(hidden)]
    pub fn handle(&self) -> &Handle {
        self.reactor()
    }

    /// Return a reference to the reactor handle for this runtime instance.
    ///
    /// The returned handle reference can be cloned in order to get an owned
    /// value of the handle. This handle can be used to initialize I/O resources
    /// (like TCP or UDP sockets) that will not be used on the runtime.
    ///
    /// # Examples
    ///
    /// ```
    /// use tokio::runtime::Runtime;
    ///
    /// let rt = Runtime::new()
    ///     .unwrap();
    ///
    /// let reactor_handle = rt.reactor().clone();
    ///
    /// // use `reactor_handle`
    /// ```
    pub fn reactor(&self) -> &Handle {
        self.inner().reactor.handle()
    }

    /// Return a handle to the runtime's executor.
    ///
    /// The returned handle can be used to spawn tasks that run on this runtime.
    ///
    /// # Examples
    ///
    /// ```
    /// use tokio::runtime::Runtime;
    ///
    /// let rt = Runtime::new()
    ///     .unwrap();
    ///
    /// let executor_handle = rt.executor();
    ///
    /// // use `executor_handle`
    /// ```
    pub fn executor(&self) -> TaskExecutor {
        let inner = self.inner().pool.sender().clone();
        TaskExecutor { inner }
    }

    /// Spawn a future onto the Tokio runtime.
    ///
    /// This spawns the given future onto the runtime's executor, usually a
    /// thread pool. The thread pool is then responsible for polling the future
    /// until it completes.
    ///
    /// See [module level][mod] documentation for more details.
    ///
    /// [mod]: index.html
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate tokio;
    /// # extern crate futures;
    /// # use futures::{future, Future, Stream};
    /// use tokio::runtime::Runtime;
    ///
    /// # fn dox() {
    /// // Create the runtime
    /// let mut rt = Runtime::new().unwrap();
    ///
    /// // Spawn a future onto the runtime
    /// rt.spawn(future::lazy(|| {
    ///     println!("now running on a worker thread");
    ///     Ok(())
    /// }));
    /// # }
    /// # pub fn main() {}
    /// ```
    ///
    /// # Panics
    ///
    /// This function panics if the spawn fails. Failure occurs if the executor
    /// is currently at capacity and is unable to spawn a new future.
    pub fn spawn<F>(&mut self, future: F) -> &mut Self
    where F: Future<Item = (), Error = ()> + Send + 'static,
    {
        self.inner_mut().pool.sender().spawn(future).unwrap();
        self
    }

    /// Spawn a futures 0.2-style future onto the Tokio runtime.
    ///
    /// Otherwise identical to `spawn`
    #[cfg(feature = "unstable-futures")]
    pub fn spawn2<F>(&mut self, future: F) -> &mut Self
        where F: futures2::Future<Item = (), Error = futures2::Never> + Send + 'static,
    {
        futures2::executor::Executor::spawn(
            self.inner_mut().pool.sender_mut(), Box::new(future)
        ).unwrap();
        self
    }

    /// Signals the runtime to shutdown once it becomes idle.
    ///
    /// Returns a future that completes once the shutdown operation has
    /// completed.
    ///
    /// This function can be used to perform a graceful shutdown of the runtime.
    ///
    /// The runtime enters an idle state once **all** of the following occur.
    ///
    /// * The thread pool has no tasks to execute, i.e., all tasks that were
    ///   spawned have completed.
    /// * The reactor is not managing any I/O resources.
    ///
    /// See [module level][mod] documentation for more details.
    ///
    /// # Examples
    ///
    /// ```
    /// use tokio::runtime::Runtime;
    /// use tokio::prelude::*;
    ///
    /// let rt = Runtime::new()
    ///     .unwrap();
    ///
    /// // Use the runtime...
    ///
    /// // Shutdown the runtime
    /// rt.shutdown_on_idle()
    ///     .wait().unwrap();
    /// ```
    ///
    /// [mod]: index.html
    pub fn shutdown_on_idle(mut self) -> Shutdown {
        let inner = self.inner.take().unwrap();

        let inner = Box::new({
            let pool = inner.pool;
            let reactor = inner.reactor;

            pool.shutdown_on_idle().and_then(|_| {
                reactor.shutdown_on_idle()
            })
        });

        Shutdown { inner }
    }

    /// Signals the runtime to shutdown immediately.
    ///
    /// Returns a future that completes once the shutdown operation has
    /// completed.
    ///
    /// This function will forcibly shutdown the runtime, causing any
    /// in-progress work to become canceled. The shutdown steps are:
    ///
    /// * Drain any scheduled work queues.
    /// * Drop any futures that have not yet completed.
    /// * Drop the reactor.
    ///
    /// Once the reactor has dropped, any outstanding I/O resources bound to
    /// that reactor will no longer function. Calling any method on them will
    /// result in an error.
    ///
    /// See [module level][mod] documentation for more details.
    ///
    /// # Examples
    ///
    /// ```
    /// use tokio::runtime::Runtime;
    /// use tokio::prelude::*;
    ///
    /// let rt = Runtime::new()
    ///     .unwrap();
    ///
    /// // Use the runtime...
    ///
    /// // Shutdown the runtime
    /// rt.shutdown_now()
    ///     .wait().unwrap();
    /// ```
    ///
    /// [mod]: index.html
    pub fn shutdown_now(mut self) -> Shutdown {
        let inner = self.inner.take().unwrap();
        Shutdown::shutdown_now(inner)
    }

    fn inner(&self) -> &Inner {
        self.inner.as_ref().unwrap()
    }

    fn inner_mut(&mut self) -> &mut Inner {
        self.inner.as_mut().unwrap()
    }
}

impl Drop for Runtime {
    fn drop(&mut self) {
        if let Some(inner) = self.inner.take() {
            let shutdown = Shutdown::shutdown_now(inner);
            let _ = shutdown.wait();
        }
    }
}
<|endoftext|>


<commit_before>//! Integration with the [Iron](https://ironframework.io) framework, enabled with the `iron` feature (optional). Includes a `BeforeMiddleware` implementation.
//!
//! Not shown here: `impl `[`HttpRequest`](../trait.HttpRequest.html#implementors)` for
//! iron::Request`.

use iron::headers::ContentType;
use iron::mime::{Mime, TopLevel, SubLevel};
use iron::request::{Body as IronBody, Request as IronRequest};
use iron::typemap::Key;
use iron::{BeforeMiddleware, IronError, IronResult};

use std::path::PathBuf;
use std::{error, fmt};

use super::{Entries, HttpRequest, Multipart, MultipartData};

impl<'r, 'a, 'b> HttpRequest for &'r mut IronRequest<'a, 'b> {
    type Body = &'r mut IronBody<'a, 'b>;

    fn multipart_boundary(&self) -> Option<&str> {
        let content_type = try_opt!(self.headers.get::<ContentType>());
        if let Mime(TopLevel::Multipart, SubLevel::FormData, _) = **content_type {
            content_type.get_param("boundary").map(|b| b.as_str())
        } else {
            None
        }
    }

    fn body(self) -> &'r mut IronBody<'a, 'b> {
        &mut self.body
    }
}

/// The default file size limit for [`Intercept`](struct.Intercept.html), in bytes.
pub const DEFAULT_FILE_SIZE_LIMIT: u64 = 2 * 1024 * 1024;

/// The default file count limit for [`Intercept`](struct.Intercept.html).
pub const DEFAULT_FILE_COUNT_LIMIT: u32 = 16;

/// A `BeforeMiddleware` for Iron which will intercept and read-out multipart requests and store
/// the result in the request.
///
/// Successful reads will be placed in the `extensions: TypeMap` field of `iron::Request` as an
/// [`Entries`](../struct.Entries.html) instance (as both key-type and value):
///
/// ```no_run
/// extern crate iron;
/// extern crate multipart;
///
/// use iron::prelude::*;
///
/// use multipart::server::Entries;
/// use multipart::server::iron::Intercept;
///
/// fn main() {
///     Iron::new(Chain::new(|req: &mut Request| if let Some(entries) =
///         req.extensions.get::<Entries>() {
///
///         Ok(Response::with(format!("{:?}", entries)))
///     } else {
///         Ok(Response::with("Not a multipart request"))
///     })).http("localhost:80").unwrap();
/// }
/// ```
///
/// Any errors during which occur during reading will be passed on as `IronError`.
#[derive(Debug)]
pub struct Intercept {
    /// The parent directory for all temporary directories created by this middleware.
    /// Will be created if it doesn't exist (lazy).
    ///
    /// If omitted, uses the OS temporary directory.
    ///
    /// Default value: `None`.
    pub temp_dir_path: Option<PathBuf>,
    /// The size limit of uploaded files, in bytes.
    ///
    /// Files which exceed this size will be rejected.
    /// See the `limit_behavior` field for more info.
    ///
    /// Default value: [`DEFAULT_FILE_SIZE_LIMIT`](constant.default_file_size_limit.html)
    pub file_size_limit: u64,
    /// The limit on the number of files which will be saved from
    /// the request. Requests which exceed this count will be rejected.
    ///
    /// Default value: [`DEFAULT_FILE_COUNT_LIMT`](constant.default_file_count_limit.html)
    pub file_count_limit: u32,
    /// What to do when a file count or size limit has been exceeded.
    ///
    /// See [`LimitBehavior`](enum.limitbehavior.html) for more info.
    pub limit_behavior: LimitBehavior,
}

impl Intercept {
    /// Set the `temp_dir_path` for this middleware.
    pub fn temp_dir_path<P: Into<PathBuf>>(self, path: P) -> Self {
        Intercept { temp_dir_path: Some(path.into()), .. self }
    }

    /// Set the `file_size_limit` for this middleware.
    pub fn file_size_limit(self, limit: u64) -> Self {
        Intercept { file_size_limit: limit, .. self }
    }

    /// Set the `file_count_limit` for this middleware.
    pub fn file_count_limit(self, limit: u32) -> Self {
        Intercept { file_count_limit: limit, .. self }
    }

    /// Set the `limit_behavior` for this middleware.
    pub fn limit_behavior(self, behavior: LimitBehavior) -> Self {
        Intercept { limit_behavior: behavior, .. self }
    }

    fn read_request(&self, req: &mut IronRequest) -> IronResult<Option<Entries>> {
        macro_rules! try_iron(
            ($try:expr; $($fmt_args:tt)+) => (
                match $try {
                    Ok(ok) => ok,
                    Err(err) => return Err(IronError::new(err, format!($($fmt_args)*))),
                }
            );
            ($try:expr; $err_msg:expr) => (
                match $try {
                    Ok(ok) => ok,
                    Err(err) => return Err(IronError::new(err, $err_msg)),
                }
            );
            ($try:expr) => (
                try_iron!($try; "");
            )
        );

        let mut multipart = match Multipart::from_request(req) {
            Ok(multipart) => multipart,
            Err(_) => return Ok(None),
        };

        let mut entries = try_iron!(
            self.temp_dir_path.as_ref()
                .map_or_else(Entries::new_tempdir, Entries::new_tempdir_in);
            "Error opening temporary directory for request."
        );

        let mut file_count = 0;

        while let Some(field) = try_iron!(multipart.read_entry()) {
            match field.data {
                MultipartData::File(mut file) => {
                    if self.limit_behavior.throw_error() && file_count >= self.file_count_limit {
                        return Err(FileCountLimitError(self.file_count_limit).into());
                    }

                    let file = try_iron!(
                        file.save_in_limited(&entries.dir, self.file_size_limit);
                        "Error reading field: \"{}\" (filename: \"{}\")",
                        field.name,
                        file.filename.as_ref().map_or("(none)", String::as_ref)
                    );

                    if file.size == self.file_size_limit {
                        if self.limit_behavior.throw_error() {
                            return Err(FileSizeLimitError::new(field.name, file.filename).into());
                        } else {
                            warn!(
                                "File size limit reached for field {:?} (filename: {:?})",
                                field.name, file.filename
                            );
                        }
                    }

                    entries.files.insert(field.name, file);
                    file_count += 1;
                },
                MultipartData::Text(text) => {
                    entries.fields.insert(field.name, text.into());
                },
            }
        }

        Ok(Some(entries))
    }
}

impl Default for Intercept {
    fn default() -> Self {
        Intercept {
            temp_dir_path: None,
            file_size_limit: DEFAULT_FILE_SIZE_LIMIT,
            file_count_limit: DEFAULT_FILE_COUNT_LIMIT,
            limit_behavior: LimitBehavior::ThrowError,
        }
    }
}

impl BeforeMiddleware for Intercept {
    fn before(&self, req: &mut IronRequest) -> IronResult<()> {
        try!(self.read_request(req))
            .map(|entries| req.extensions.insert::<Entries>(entries));

        Ok(())
    }
}

impl Key for Entries {
    type Value = Self;
}

/// The behavior of `Intercept` when a file size or count limit is exceeded.
#[derive(Clone, Copy, Debug)]
#[repr(u32)]
pub enum LimitBehavior {
    /// Return an error from the middleware describing the issue.
    ThrowError,
    /// Ignore the limit.
    ///
    /// In the case of file size limits, the offending file will be truncated
    /// in the result.
    ///
    /// In the case of file count limits, the request will be completed.
    Continue,
}

impl LimitBehavior {
    fn throw_error(self) -> bool {
        use self::LimitBehavior::*;

        match self {
            ThrowError => true,
            Continue => false,
        }
    }
}

/// An error returned from `Intercept` when the size limit
/// for an individual file is exceeded.
#[derive(Debug)]
pub struct FileSizeLimitError {
    /// The field where the error occurred.
    pub field: String,
    /// The filename of the oversize file, if it was provided.
    pub filename: Option<String>,
}

impl FileSizeLimitError {
    fn new(field: String, filename: Option<String>) -> Self {
        FileSizeLimitError {
            field: field,
            filename: filename
        }
    }
}

impl error::Error for FileSizeLimitError {
    fn description(&self) -> &str {
        "file size limit reached"
    }
}

impl fmt::Display for FileSizeLimitError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.filename {
            Some(ref filename) => write!(f, "File size limit reached for field \"{}\" (filename: \"{}\")", self.field, filename),
            None => write!(f, "File size limit reached for field \"{}\" (no filename)", self.field),
        }
    }
}

impl Into<IronError> for FileSizeLimitError {
    fn into(self) -> IronError {
        let desc_str = self.to_string();
        IronError::new(self, desc_str)
    }
}

/// An error returned from `Intercept` when the file count limit
/// for a single request was exceeded.
#[derive(Debug)]
pub struct FileCountLimitError(u32);

impl error::Error for FileCountLimitError {
    fn description(&self) -> &str {
        "file count limit reached"
    }
}

impl fmt::Display for FileCountLimitError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "File count limit reached for request. Limit: {}", self.0)
    }
}

impl Into<IronError> for FileCountLimitError {
    fn into(self) -> IronError {
        let desc_string = self.to_string();
        IronError::new(self, desc_string)
    }
}
<commit_msg>Fix iron example; remove superfluous macro variant<commit_after>//! Integration with the [Iron](https://ironframework.io) framework, enabled with the `iron` feature (optional). Includes a `BeforeMiddleware` implementation.
//!
//! Not shown here: `impl `[`HttpRequest`](../trait.HttpRequest.html#implementors)` for
//! iron::Request`.

use iron::headers::ContentType;
use iron::mime::{Mime, TopLevel, SubLevel};
use iron::request::{Body as IronBody, Request as IronRequest};
use iron::typemap::Key;
use iron::{BeforeMiddleware, IronError, IronResult};

use std::path::PathBuf;
use std::{error, fmt};

use super::{Entries, HttpRequest, Multipart, MultipartData};

impl<'r, 'a, 'b> HttpRequest for &'r mut IronRequest<'a, 'b> {
    type Body = &'r mut IronBody<'a, 'b>;

    fn multipart_boundary(&self) -> Option<&str> {
        let content_type = try_opt!(self.headers.get::<ContentType>());
        if let Mime(TopLevel::Multipart, SubLevel::FormData, _) = **content_type {
            content_type.get_param("boundary").map(|b| b.as_str())
        } else {
            None
        }
    }

    fn body(self) -> &'r mut IronBody<'a, 'b> {
        &mut self.body
    }
}

/// The default file size limit for [`Intercept`](struct.Intercept.html), in bytes.
pub const DEFAULT_FILE_SIZE_LIMIT: u64 = 2 * 1024 * 1024;

/// The default file count limit for [`Intercept`](struct.Intercept.html).
pub const DEFAULT_FILE_COUNT_LIMIT: u32 = 16;

/// A `BeforeMiddleware` for Iron which will intercept and read-out multipart requests and store
/// the result in the request.
///
/// Successful reads will be placed in the `extensions: TypeMap` field of `iron::Request` as an
/// [`Entries`](../struct.Entries.html) instance (as both key-type and value):
///
/// ```no_run
/// extern crate iron;
/// extern crate multipart;
///
/// use iron::prelude::*;
///
/// use multipart::server::Entries;
/// use multipart::server::iron::Intercept;
///
/// fn main() {
///     let mut chain = Chain::new(|req: &mut Request| if let Some(entries) =
///         req.extensions.get::<Entries>() {
///
///         Ok(Response::with(format!("{:?}", entries)))
///     } else {
///         Ok(Response::with("Not a multipart request"))
///     });
///
///     chain.link_before(Intercept::default());
///
///     Iron::new(chain).http("localhost:80").unwrap();
/// }
/// ```
///
/// Any errors during which occur during reading will be passed on as `IronError`.
#[derive(Debug)]
pub struct Intercept {
    /// The parent directory for all temporary directories created by this middleware.
    /// Will be created if it doesn't exist (lazy).
    ///
    /// If omitted, uses the OS temporary directory.
    ///
    /// Default value: `None`.
    pub temp_dir_path: Option<PathBuf>,
    /// The size limit of uploaded files, in bytes.
    ///
    /// Files which exceed this size will be rejected.
    /// See the `limit_behavior` field for more info.
    ///
    /// Default value: [`DEFAULT_FILE_SIZE_LIMIT`](constant.default_file_size_limit.html)
    pub file_size_limit: u64,
    /// The limit on the number of files which will be saved from
    /// the request. Requests which exceed this count will be rejected.
    ///
    /// Default value: [`DEFAULT_FILE_COUNT_LIMT`](constant.default_file_count_limit.html)
    pub file_count_limit: u32,
    /// What to do when a file count or size limit has been exceeded.
    ///
    /// See [`LimitBehavior`](enum.limitbehavior.html) for more info.
    pub limit_behavior: LimitBehavior,
}

impl Intercept {
    /// Set the `temp_dir_path` for this middleware.
    pub fn temp_dir_path<P: Into<PathBuf>>(self, path: P) -> Self {
        Intercept { temp_dir_path: Some(path.into()), .. self }
    }

    /// Set the `file_size_limit` for this middleware.
    pub fn file_size_limit(self, limit: u64) -> Self {
        Intercept { file_size_limit: limit, .. self }
    }

    /// Set the `file_count_limit` for this middleware.
    pub fn file_count_limit(self, limit: u32) -> Self {
        Intercept { file_count_limit: limit, .. self }
    }

    /// Set the `limit_behavior` for this middleware.
    pub fn limit_behavior(self, behavior: LimitBehavior) -> Self {
        Intercept { limit_behavior: behavior, .. self }
    }

    fn read_request(&self, req: &mut IronRequest) -> IronResult<Option<Entries>> {
        macro_rules! try_iron(
            ($try:expr; $($fmt_args:tt)+) => (
                match $try {
                    Ok(ok) => ok,
                    Err(err) => return Err(IronError::new(err, format!($($fmt_args)*))),
                }
            );
            ($try:expr) => (
                try_iron!($try; "");
            )
        );

        let mut multipart = match Multipart::from_request(req) {
            Ok(multipart) => multipart,
            Err(_) => return Ok(None),
        };

        let mut entries = try_iron!(
            self.temp_dir_path.as_ref()
                .map_or_else(Entries::new_tempdir, Entries::new_tempdir_in);
            "Error opening temporary directory for request."
        );

        let mut file_count = 0;

        while let Some(field) = try_iron!(multipart.read_entry()) {
            match field.data {
                MultipartData::File(mut file) => {
                    if self.limit_behavior.throw_error() && file_count >= self.file_count_limit {
                        return Err(FileCountLimitError(self.file_count_limit).into());
                    }

                    let file = try_iron!(
                        file.save_in_limited(&entries.dir, self.file_size_limit);
                        "Error reading field: \"{}\" (filename: \"{}\")",
                        field.name,
                        file.filename.as_ref().map_or("(none)", String::as_ref)
                    );

                    if file.size == self.file_size_limit {
                        if self.limit_behavior.throw_error() {
                            return Err(FileSizeLimitError::new(field.name, file.filename).into());
                        } else {
                            warn!(
                                "File size limit reached for field {:?} (filename: {:?})",
                                field.name, file.filename
                            );
                        }
                    }

                    entries.files.insert(field.name, file);
                    file_count += 1;
                },
                MultipartData::Text(text) => {
                    entries.fields.insert(field.name, text.into());
                },
            }
        }

        Ok(Some(entries))
    }
}

impl Default for Intercept {
    fn default() -> Self {
        Intercept {
            temp_dir_path: None,
            file_size_limit: DEFAULT_FILE_SIZE_LIMIT,
            file_count_limit: DEFAULT_FILE_COUNT_LIMIT,
            limit_behavior: LimitBehavior::ThrowError,
        }
    }
}

impl BeforeMiddleware for Intercept {
    fn before(&self, req: &mut IronRequest) -> IronResult<()> {
        try!(self.read_request(req))
            .map(|entries| req.extensions.insert::<Entries>(entries));

        Ok(())
    }
}

impl Key for Entries {
    type Value = Self;
}

/// The behavior of `Intercept` when a file size or count limit is exceeded.
#[derive(Clone, Copy, Debug)]
#[repr(u32)]
pub enum LimitBehavior {
    /// Return an error from the middleware describing the issue.
    ThrowError,
    /// Ignore the limit.
    ///
    /// In the case of file size limits, the offending file will be truncated
    /// in the result.
    ///
    /// In the case of file count limits, the request will be completed.
    Continue,
}

impl LimitBehavior {
    fn throw_error(self) -> bool {
        use self::LimitBehavior::*;

        match self {
            ThrowError => true,
            Continue => false,
        }
    }
}

/// An error returned from `Intercept` when the size limit
/// for an individual file is exceeded.
#[derive(Debug)]
pub struct FileSizeLimitError {
    /// The field where the error occurred.
    pub field: String,
    /// The filename of the oversize file, if it was provided.
    pub filename: Option<String>,
}

impl FileSizeLimitError {
    fn new(field: String, filename: Option<String>) -> Self {
        FileSizeLimitError {
            field: field,
            filename: filename
        }
    }
}

impl error::Error for FileSizeLimitError {
    fn description(&self) -> &str {
        "file size limit reached"
    }
}

impl fmt::Display for FileSizeLimitError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.filename {
            Some(ref filename) => write!(f, "File size limit reached for field \"{}\" (filename: \"{}\")", self.field, filename),
            None => write!(f, "File size limit reached for field \"{}\" (no filename)", self.field),
        }
    }
}

impl Into<IronError> for FileSizeLimitError {
    fn into(self) -> IronError {
        let desc_str = self.to_string();
        IronError::new(self, desc_str)
    }
}

/// An error returned from `Intercept` when the file count limit
/// for a single request was exceeded.
#[derive(Debug)]
pub struct FileCountLimitError(u32);

impl error::Error for FileCountLimitError {
    fn description(&self) -> &str {
        "file count limit reached"
    }
}

impl fmt::Display for FileCountLimitError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "File count limit reached for request. Limit: {}", self.0)
    }
}

impl Into<IronError> for FileCountLimitError {
    fn into(self) -> IronError {
        let desc_string = self.to_string();
        IronError::new(self, desc_string)
    }
}
<|endoftext|>


<commit_before>extern crate dbus;

use self::dbus::{Connection, BusType, Message, Path, Props};
use std::{thread, time};
use general::ServiceState;

/// Enables the Network Manager service.
///
/// # Examples
///
/// ```
/// let state = network_manager::service::enable(10).unwrap();
/// println!("{:?}", state);
/// ```
pub fn enable(to: i32) -> Result<ServiceState, String> {
    let c = Connection::get_private(BusType::System).unwrap();

    let mut m = Message::new_method_call("org.freedesktop.systemd1",
                                         "/org/freedesktop/systemd1",
                                         "org.freedesktop.systemd1.Manager",
                                         "StartUnit")
        .unwrap();
    m.append_items(&["NetworkManager.service".into(), "fail".into()]);
    c.send_with_reply_and_block(m, 2000).unwrap();

    let mut s = state().unwrap();
    let mut t = 0;
    while t < to {
        thread::sleep(time::Duration::from_secs(1));
        t = t + 1;

        s = state().unwrap();
        if s == ServiceState::Active {
            break;
        }
    }

    Ok(s)
}

// bus.getInterfaceAsync(SERVICE, MANAGER_OBJECT, MANAGER_INTERFACE)
//     .then (manager) ->
//         manager.StartUnitAsync(unit, mode)
//     .then ->
//         waitUntilState(unit, 'active')

/// Disables the Network Manager service.
///
/// # Examples
///
/// ```
/// let state = network_manager::service::disable(10).unwrap();
/// println!("{:?}", state);
/// ```
pub fn disable(t: i32) -> Result<ServiceState, String> {
    // Disable service

    if t != 0 {
        // Wait until service has stopped or
        // until the time has elapsed
    }

    Ok(ServiceState::Inactive)
}

/// Gets the state of the Network Manager service.
///
/// # Examples
///
/// ```
/// let state = network_manager::service::state().unwrap();
/// println!("{:?}", state);
/// ```
pub fn state() -> Result<ServiceState, String> {
    let c = Connection::get_private(BusType::System).unwrap();

    let mut m = Message::new_method_call("org.freedesktop.systemd1",
                                         "/org/freedesktop/systemd1",
                                         "org.freedesktop.systemd1.Manager",
                                         "GetUnit")
        .unwrap();
    m.append_items(&["NetworkManager.service".into()]);
    let r = c.send_with_reply_and_block(m, 2000).unwrap();
    let p: Path = r.get1().unwrap();

    let m = Props::new(&c,
                       "org.freedesktop.systemd1",
                       p,
                       "org.freedesktop.systemd1.Unit",
                       2000);
    let r = m.get("ActiveState").unwrap();
    let v: &String = r.inner().unwrap();
    let s: ServiceState = v.parse().unwrap();

    Ok(s)
}
<commit_msg>Implementing function to stop the Network Manager service<commit_after>extern crate dbus;

use self::dbus::{Connection, BusType, Message, Path, Props};
use std::{thread, time};
use general::ServiceState;

/// Enables the Network Manager service.
///
/// # Examples
///
/// ```
/// let state = network_manager::service::enable(10).unwrap();
/// println!("{:?}", state);
/// ```
pub fn enable(to: i32) -> Result<ServiceState, String> {
    let c = Connection::get_private(BusType::System).unwrap();

    let mut m = Message::new_method_call("org.freedesktop.systemd1",
                                         "/org/freedesktop/systemd1",
                                         "org.freedesktop.systemd1.Manager",
                                         "StartUnit")
        .unwrap();
    m.append_items(&["NetworkManager.service".into(), "fail".into()]);
    c.send_with_reply_and_block(m, 2000).unwrap();

    let mut s = state().unwrap();
    let mut t = 0;
    while t < to {
        thread::sleep(time::Duration::from_secs(1));
        t = t + 1;

        s = state().unwrap();
        if s == ServiceState::Active {
            break;
        }
    }

    Ok(s)
}

/// Disables the Network Manager service.
///
/// # Examples
///
/// ```
/// let state = network_manager::service::disable(10).unwrap();
/// println!("{:?}", state);
/// ```
pub fn disable(to: i32) -> Result<ServiceState, String> {
    let c = Connection::get_private(BusType::System).unwrap();

    let mut m = Message::new_method_call("org.freedesktop.systemd1",
                                         "/org/freedesktop/systemd1",
                                         "org.freedesktop.systemd1.Manager",
                                         "StopUnit")
        .unwrap();
    m.append_items(&["NetworkManager.service".into(), "fail".into()]);
    c.send_with_reply_and_block(m, 2000).unwrap();

    let mut s = state().unwrap();
    let mut t = 0;
    while t < to {
        thread::sleep(time::Duration::from_secs(1));
        t = t + 1;

        s = state().unwrap();
        if s == ServiceState::Inactive {
            break;
        }
    }

    Ok(s)
}

/// Gets the state of the Network Manager service.
///
/// # Examples
///
/// ```
/// let state = network_manager::service::state().unwrap();
/// println!("{:?}", state);
/// ```
pub fn state() -> Result<ServiceState, String> {
    let c = Connection::get_private(BusType::System).unwrap();

    let mut m = Message::new_method_call("org.freedesktop.systemd1",
                                         "/org/freedesktop/systemd1",
                                         "org.freedesktop.systemd1.Manager",
                                         "GetUnit")
        .unwrap();
    m.append_items(&["NetworkManager.service".into()]);
    let r = c.send_with_reply_and_block(m, 2000).unwrap();
    let p: Path = r.get1().unwrap();

    let m = Props::new(&c,
                       "org.freedesktop.systemd1",
                       p,
                       "org.freedesktop.systemd1.Unit",
                       2000);
    let r = m.get("ActiveState").unwrap();
    let v: &String = r.inner().unwrap();
    let s: ServiceState = v.parse().unwrap();

    Ok(s)
}
<|endoftext|>


<commit_before>//! generate series virtual table.
//! Port of C [generate series "function"](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/series.c).
use std::default::Default;
use std::os::raw::{c_char, c_int, c_void};

use {Connection, Error, Result};
use ffi;
use vtab::{self, declare_vtab, Context, IndexInfo, Values, VTab, VTabCursor};

/// Register the "generate_series" module.
pub fn load_module(conn: &Connection) -> Result<()> {
    let aux: Option<()> = None;
    conn.create_module("generate_series", &SERIES_MODULE, aux)
}

init_module!(SERIES_MODULE,
             SeriesTab,
             SeriesTabCursor,
             None,
             series_connect,
             series_best_index,
             series_disconnect,
             None,
             series_open,
             series_close,
             series_filter,
             series_next,
             series_eof,
             series_column,
             series_rowid);

// Column numbers
// const SERIES_COLUMN_VALUE : c_int = 0;
const SERIES_COLUMN_START: c_int = 1;
const SERIES_COLUMN_STOP: c_int = 2;
const SERIES_COLUMN_STEP: c_int = 3;

bitflags! {
    #[repr(C)]
    struct QueryPlanFlags: ::std::os::raw::c_int {
        // start = $value  -- constraint exists
        const START = 1;
        // stop = $value   -- constraint exists
        const STOP  = 2;
        // step = $value   -- constraint exists
        const STEP  = 4;
        // output in descending order
        const DESC  = 8;
        // Both start and stop
        const BOTH  = START.bits | STOP.bits;
    }
}

/// An instance of the Series virtual table
#[repr(C)]
struct SeriesTab {
    /// Base class. Must be first
    base: ffi::sqlite3_vtab,
}

impl VTab<SeriesTabCursor> for SeriesTab {
    fn connect(db: *mut ffi::sqlite3,
               _aux: *mut c_void,
               _args: &[&[u8]])
               -> Result<SeriesTab> {
        let vtab = SeriesTab { base: Default::default() };
        try!(declare_vtab(db,
                          "CREATE TABLE x(value,start hidden,stop hidden,step hidden)"));
        Ok(vtab)
    }

    fn best_index(&self, info: &mut IndexInfo) -> Result<()> {
        // The query plan bitmask
        let mut idx_num: QueryPlanFlags = QueryPlanFlags::empty();
        // Index of the start= constraint
        let mut start_idx = None;
        // Index of the stop= constraint
        let mut stop_idx = None;
        // Index of the step= constraint
        let mut step_idx = None;
        for (i, constraint) in info.constraints().enumerate() {
            if !constraint.is_usable() {
                continue;
            }
            if constraint.operator() != vtab::SQLITE_INDEX_CONSTRAINT_EQ {
                continue;
            }
            match constraint.column() {
                SERIES_COLUMN_START => {
                    start_idx = Some(i);
                    idx_num |= START;
                }
                SERIES_COLUMN_STOP => {
                    stop_idx = Some(i);
                    idx_num |= STOP;
                }
                SERIES_COLUMN_STEP => {
                    step_idx = Some(i);
                    idx_num |= STEP;
                }
                _ => {}
            };
        }

        let mut num_of_arg = 0;
        if let Some(start_idx) = start_idx {
            num_of_arg += 1;
            let mut constraint_usage = info.constraint_usage(start_idx);
            constraint_usage.set_argv_index(num_of_arg);
            constraint_usage.set_omit(true);
        }
        if let Some(stop_idx) = stop_idx {
            num_of_arg += 1;
            let mut constraint_usage = info.constraint_usage(stop_idx);
            constraint_usage.set_argv_index(num_of_arg);
            constraint_usage.set_omit(true);
        }
        if let Some(step_idx) = step_idx {
            num_of_arg += 1;
            let mut constraint_usage = info.constraint_usage(step_idx);
            constraint_usage.set_argv_index(num_of_arg);
            constraint_usage.set_omit(true);
        }
        if idx_num.contains(BOTH) {
            // Both start= and stop= boundaries are available.
            info.set_estimated_cost((2 - if idx_num.contains(STEP) { 1 } else { 0 }) as f64);
            info.set_estimated_rows(1000);
            if info.num_of_order_by() == 1 {
                if info.is_order_by_desc(0) {
                    idx_num |= DESC;
                }
                info.set_order_by_consumed(true);
            }
        } else {
            info.set_estimated_cost(2147483647f64);
            info.set_estimated_rows(2147483647);
        }
        info.set_idx_num(idx_num.bits());
        Ok(())
    }

    fn open(&self) -> Result<SeriesTabCursor> {
        Ok(SeriesTabCursor::new())
    }
}

/// A cursor for the Series virtual table
#[derive(Default)]
#[repr(C)]
struct SeriesTabCursor {
    /// Base class. Must be first
    base: ffi::sqlite3_vtab_cursor,
    /// True to count down rather than up
    is_desc: bool,
    /// The rowid
    row_id: i64,
    /// Current value ("value")
    value: i64,
    /// Mimimum value ("start")
    min_value: i64,
    /// Maximum value ("stop")
    max_value: i64,
    /// Increment ("step")
    step: i64,
}

impl SeriesTabCursor {
    fn new() -> SeriesTabCursor {
        Default::default()
    }
}
impl VTabCursor<SeriesTab> for SeriesTabCursor {
    fn vtab(&self) -> &mut SeriesTab {
        unsafe { &mut *(self.base.pVtab as *mut SeriesTab) }
    }
    fn filter(&mut self,
              idx_num: c_int,
              _idx_str: Option<&str>,
              args: &Values)
              -> Result<()> {
        let idx_num = QueryPlanFlags::from_bits_truncate(idx_num);
        let mut i = 0;
        if idx_num.contains(START) {
            self.min_value = try!(args.get(i));
            i += 1;
        } else {
            self.min_value = 0;
        }
        if idx_num.contains(STOP) {
            self.max_value = try!(args.get(i));
            i += 1;
        } else {
            self.max_value = 0xffffffff;
        }
        if idx_num.contains(STEP) {
            self.step = try!(args.get(i));
            if self.step < 1 {
                self.step = 1;
            }
        } else {
            self.step = 1;
        };
        self.is_desc = idx_num.contains(DESC);
        if self.is_desc {
            self.value = self.max_value;
            if self.step > 1 {
                self.value -= (self.max_value - self.min_value) % self.step;
            }
        } else {
            self.value = self.min_value;
        }
        self.row_id = 0;
        Ok(())
    }
    fn next(&mut self) -> Result<()> {
        if self.is_desc {
            self.value -= self.step;
        } else {
            self.value += self.step;
        }
        self.row_id += 1;
        Ok(())
    }
    fn eof(&self) -> bool {
        if self.is_desc {
            self.value < self.min_value
        } else {
            self.value > self.max_value
        }
    }
    fn column(&self, ctx: &mut Context, i: c_int) -> Result<()> {
        let x = match i {
            SERIES_COLUMN_START => self.min_value,
            SERIES_COLUMN_STOP => self.max_value,
            SERIES_COLUMN_STEP => self.step,
            _ => self.value,
        };
        ctx.set_result(&x);
        Ok(())
    }
    fn rowid(&self) -> Result<i64> {
        Ok(self.row_id)
    }
}

#[cfg(test)]
mod test {
    use Connection;
    use vtab::series;
    use ffi;

    #[test]
    fn test_series_module() {
        let version = unsafe { ffi::sqlite3_libversion_number() };
        if version < 3008012 {
            return;
        }

        let db = Connection::open_in_memory().unwrap();
        series::load_module(&db).unwrap();

        let mut s = db.prepare("SELECT * FROM generate_series(0,20,5)").unwrap();

        let series = s.query_map(&[], |row| row.get::<i32, i32>(0))
            .unwrap();

        let mut expected = 0;
        for value in series {
            assert_eq!(expected, value.unwrap());
            expected += 5;
        }
    }
}
<commit_msg>Fix build errors related to bitflags<commit_after>//! generate series virtual table.
//! Port of C [generate series "function"](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/series.c).
use std::default::Default;
use std::os::raw::{c_char, c_int, c_void};

use {Connection, Error, Result};
use ffi;
use vtab::{self, declare_vtab, Context, IndexInfo, Values, VTab, VTabCursor};

/// Register the "generate_series" module.
pub fn load_module(conn: &Connection) -> Result<()> {
    let aux: Option<()> = None;
    conn.create_module("generate_series", &SERIES_MODULE, aux)
}

init_module!(SERIES_MODULE,
             SeriesTab,
             SeriesTabCursor,
             None,
             series_connect,
             series_best_index,
             series_disconnect,
             None,
             series_open,
             series_close,
             series_filter,
             series_next,
             series_eof,
             series_column,
             series_rowid);

// Column numbers
// const SERIES_COLUMN_VALUE : c_int = 0;
const SERIES_COLUMN_START: c_int = 1;
const SERIES_COLUMN_STOP: c_int = 2;
const SERIES_COLUMN_STEP: c_int = 3;

bitflags! {
    #[repr(C)]
    struct QueryPlanFlags: ::std::os::raw::c_int {
        // start = $value  -- constraint exists
        const START = 1;
        // stop = $value   -- constraint exists
        const STOP  = 2;
        // step = $value   -- constraint exists
        const STEP  = 4;
        // output in descending order
        const DESC  = 8;
        // Both start and stop
        const BOTH  = QueryPlanFlags::START.bits | QueryPlanFlags::STOP.bits;
    }
}

/// An instance of the Series virtual table
#[repr(C)]
struct SeriesTab {
    /// Base class. Must be first
    base: ffi::sqlite3_vtab,
}

impl VTab<SeriesTabCursor> for SeriesTab {
    fn connect(db: *mut ffi::sqlite3,
               _aux: *mut c_void,
               _args: &[&[u8]])
               -> Result<SeriesTab> {
        let vtab = SeriesTab { base: Default::default() };
        try!(declare_vtab(db,
                          "CREATE TABLE x(value,start hidden,stop hidden,step hidden)"));
        Ok(vtab)
    }

    fn best_index(&self, info: &mut IndexInfo) -> Result<()> {
        // The query plan bitmask
        let mut idx_num: QueryPlanFlags = QueryPlanFlags::empty();
        // Index of the start= constraint
        let mut start_idx = None;
        // Index of the stop= constraint
        let mut stop_idx = None;
        // Index of the step= constraint
        let mut step_idx = None;
        for (i, constraint) in info.constraints().enumerate() {
            if !constraint.is_usable() {
                continue;
            }
            if constraint.operator() != vtab::IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_EQ {
                continue;
            }
            match constraint.column() {
                SERIES_COLUMN_START => {
                    start_idx = Some(i);
                    idx_num |= QueryPlanFlags::START;
                }
                SERIES_COLUMN_STOP => {
                    stop_idx = Some(i);
                    idx_num |= QueryPlanFlags::STOP;
                }
                SERIES_COLUMN_STEP => {
                    step_idx = Some(i);
                    idx_num |= QueryPlanFlags::STEP;
                }
                _ => {}
            };
        }

        let mut num_of_arg = 0;
        if let Some(start_idx) = start_idx {
            num_of_arg += 1;
            let mut constraint_usage = info.constraint_usage(start_idx);
            constraint_usage.set_argv_index(num_of_arg);
            constraint_usage.set_omit(true);
        }
        if let Some(stop_idx) = stop_idx {
            num_of_arg += 1;
            let mut constraint_usage = info.constraint_usage(stop_idx);
            constraint_usage.set_argv_index(num_of_arg);
            constraint_usage.set_omit(true);
        }
        if let Some(step_idx) = step_idx {
            num_of_arg += 1;
            let mut constraint_usage = info.constraint_usage(step_idx);
            constraint_usage.set_argv_index(num_of_arg);
            constraint_usage.set_omit(true);
        }
        if idx_num.contains(QueryPlanFlags::BOTH) {
            // Both start= and stop= boundaries are available.
            info.set_estimated_cost((2 - if idx_num.contains(QueryPlanFlags::STEP) { 1 } else { 0 }) as f64);
            info.set_estimated_rows(1000);
            if info.num_of_order_by() == 1 {
                if info.is_order_by_desc(0) {
                    idx_num |= QueryPlanFlags::DESC;
                }
                info.set_order_by_consumed(true);
            }
        } else {
            info.set_estimated_cost(2147483647f64);
            info.set_estimated_rows(2147483647);
        }
        info.set_idx_num(idx_num.bits());
        Ok(())
    }

    fn open(&self) -> Result<SeriesTabCursor> {
        Ok(SeriesTabCursor::new())
    }
}

/// A cursor for the Series virtual table
#[derive(Default)]
#[repr(C)]
struct SeriesTabCursor {
    /// Base class. Must be first
    base: ffi::sqlite3_vtab_cursor,
    /// True to count down rather than up
    is_desc: bool,
    /// The rowid
    row_id: i64,
    /// Current value ("value")
    value: i64,
    /// Mimimum value ("start")
    min_value: i64,
    /// Maximum value ("stop")
    max_value: i64,
    /// Increment ("step")
    step: i64,
}

impl SeriesTabCursor {
    fn new() -> SeriesTabCursor {
        Default::default()
    }
}
impl VTabCursor<SeriesTab> for SeriesTabCursor {
    fn vtab(&self) -> &mut SeriesTab {
        unsafe { &mut *(self.base.pVtab as *mut SeriesTab) }
    }
    fn filter(&mut self,
              idx_num: c_int,
              _idx_str: Option<&str>,
              args: &Values)
              -> Result<()> {
        let idx_num = QueryPlanFlags::from_bits_truncate(idx_num);
        let mut i = 0;
        if idx_num.contains(QueryPlanFlags::START) {
            self.min_value = try!(args.get(i));
            i += 1;
        } else {
            self.min_value = 0;
        }
        if idx_num.contains(QueryPlanFlags::STOP) {
            self.max_value = try!(args.get(i));
            i += 1;
        } else {
            self.max_value = 0xffffffff;
        }
        if idx_num.contains(QueryPlanFlags::STEP) {
            self.step = try!(args.get(i));
            if self.step < 1 {
                self.step = 1;
            }
        } else {
            self.step = 1;
        };
        self.is_desc = idx_num.contains(QueryPlanFlags::DESC);
        if self.is_desc {
            self.value = self.max_value;
            if self.step > 1 {
                self.value -= (self.max_value - self.min_value) % self.step;
            }
        } else {
            self.value = self.min_value;
        }
        self.row_id = 0;
        Ok(())
    }
    fn next(&mut self) -> Result<()> {
        if self.is_desc {
            self.value -= self.step;
        } else {
            self.value += self.step;
        }
        self.row_id += 1;
        Ok(())
    }
    fn eof(&self) -> bool {
        if self.is_desc {
            self.value < self.min_value
        } else {
            self.value > self.max_value
        }
    }
    fn column(&self, ctx: &mut Context, i: c_int) -> Result<()> {
        let x = match i {
            SERIES_COLUMN_START => self.min_value,
            SERIES_COLUMN_STOP => self.max_value,
            SERIES_COLUMN_STEP => self.step,
            _ => self.value,
        };
        ctx.set_result(&x);
        Ok(())
    }
    fn rowid(&self) -> Result<i64> {
        Ok(self.row_id)
    }
}

#[cfg(test)]
mod test {
    use Connection;
    use vtab::series;
    use ffi;

    #[test]
    fn test_series_module() {
        let version = unsafe { ffi::sqlite3_libversion_number() };
        if version < 3008012 {
            return;
        }

        let db = Connection::open_in_memory().unwrap();
        series::load_module(&db).unwrap();

        let mut s = db.prepare("SELECT * FROM generate_series(0,20,5)").unwrap();

        let series = s.query_map(&[], |row| row.get::<i32, i32>(0))
            .unwrap();

        let mut expected = 0;
        for value in series {
            assert_eq!(expected, value.unwrap());
            expected += 5;
        }
    }
}
<|endoftext|>


<commit_before>//! Simple hashed wheel timer with bounded interval.
//!
//! Relevant:
//! http://www.cs.columbia.edu/~nahum/w6998/papers/sosp87-timing-wheels.pdf

#![unstable]
#![feature(core)]

use std::mem;
use std::ops::IndexMut;

/// A simple wheel timer implementation with a fixed ring size.
pub struct WheelTimer<T> {
  max_interval: usize,
  current_tick: usize,
  size: usize,

  ring: Vec<Vec<T>>
}

/// Iterator implementation allows for using the wheel timer in a for loop.
///
/// # Example
///
/// ```
/// use wheel_timer::WheelTimer;
///
/// let mut timer: WheelTimer<usize> = WheelTimer::new(20us);
/// for result in timer {
///   // result is a vector of the values at that step
/// }
/// ```
impl<T> Iterator for WheelTimer<T> {
  type Item = Vec<T>;

  fn next(&mut self) -> Option<Vec<T>> {
    let size = self.size();
    return if size > 0 {
      Some(self.tick())
    } else {
      None
    };
  }
}

impl<T> WheelTimer<T> {

  /// Creates a new timer with the specified max interval.
  ///
  /// # Example
  ///
  /// ```
  /// use wheel_timer::WheelTimer;
  ///
  /// let mut timer: WheelTimer<usize> = WheelTimer::new(20us);
  /// ```
  pub fn new(max_interval: usize) -> WheelTimer<T> {
    // Initialize the ring with Nil values
    let mut ring = Vec::with_capacity(max_interval);
    for _ in range(0us, max_interval) {
      ring.push(Vec::new())
    }

    return WheelTimer{
      max_interval: max_interval,
      current_tick: 0,
      ring: ring,
      size: 0,
    }
  }

  /// Returns the number of items currently scheduled.
  ///
  /// # Example
  ///
  /// ```
  /// use wheel_timer::WheelTimer;
  ///
  /// let mut timer: WheelTimer<usize> = WheelTimer::new(20us);
  /// timer.schedule(4, 1);
  /// timer.schedule(7, 1);
  /// timer.schedule(1, 1);
  /// assert_eq!(timer.size(), 3);
  /// ```
  pub fn size(&self) -> usize {
    self.size
  }

  /// Schedules a new value, available after `ticks` have passed.
  ///
  /// # Example
  ///
  /// ```
  /// use wheel_timer::WheelTimer;
  ///
  /// let mut timer: WheelTimer<usize> = WheelTimer::new(20us);
  /// timer.schedule(4, 7); // schedule value 7 for 4 ticks
  /// ```
  pub fn schedule(&mut self, ticks: usize, value: T) {
    // Compute the scheduled position in the wheel
    let index = (self.current_tick + ticks) % self.max_interval;

    // Get the current node at `index` in the wheel and append the new node
    self.ring.index_mut(&index).push(value);

    // Increment the size counter
    self.size = self.size + 1;
  }

  /// Tick the timer, returning the node at the current tick.
  ///
  /// # Example
  ///
  /// ```
  /// use wheel_timer::WheelTimer;
  ///
  /// let mut timer: WheelTimer<usize> = WheelTimer::new(20us);
  /// timer.schedule(3, 4); // schedule value 4 for 3 ticks
  /// timer.tick();
  /// timer.tick();
  /// timer.tick();
  /// let result = timer.tick(); // vec![4]
  /// assert_eq!(result.len(), 1);
  /// ```
  pub fn tick(&mut self) -> Vec<T> {
    // Get the node at the current tick in the wheel
    let node = mem::replace(self.ring.index_mut(&self.current_tick), Vec::new());

    // Increment the timer
    self.current_tick = (self.current_tick + 1) % self.max_interval;

    // Reduce the size by the length of the removed node
    self.size = self.size - node.len();

    // Return the node that was in that spot
    return node
  }
}
<commit_msg>Removing us post-fixes for Rust compat<commit_after>//! Simple hashed wheel timer with bounded interval.
//!
//! Relevant:
//! http://www.cs.columbia.edu/~nahum/w6998/papers/sosp87-timing-wheels.pdf

#![unstable]
#![feature(core)]

use std::mem;
use std::ops::IndexMut;

/// A simple wheel timer implementation with a fixed ring size.
pub struct WheelTimer<T> {
  max_interval: usize,
  current_tick: usize,
  size: usize,

  ring: Vec<Vec<T>>
}

/// Iterator implementation allows for using the wheel timer in a for loop.
///
/// # Example
///
/// ```
/// use wheel_timer::WheelTimer;
///
/// let mut timer: WheelTimer<usize> = WheelTimer::new(20);
/// for result in timer {
///   // result is a vector of the values at that step
/// }
/// ```
impl<T> Iterator for WheelTimer<T> {
  type Item = Vec<T>;

  fn next(&mut self) -> Option<Vec<T>> {
    let size = self.size();
    return if size > 0 {
      Some(self.tick())
    } else {
      None
    };
  }
}

impl<T> WheelTimer<T> {

  /// Creates a new timer with the specified max interval.
  ///
  /// # Example
  ///
  /// ```
  /// use wheel_timer::WheelTimer;
  ///
  /// let mut timer: WheelTimer<usize> = WheelTimer::new(20);
  /// ```
  pub fn new(max_interval: usize) -> WheelTimer<T> {
    // Initialize the ring with Nil values
    let mut ring = Vec::with_capacity(max_interval);
    for _ in range(0, max_interval) {
      ring.push(Vec::new())
    }

    return WheelTimer{
      max_interval: max_interval,
      current_tick: 0,
      ring: ring,
      size: 0,
    }
  }

  /// Returns the number of items currently scheduled.
  ///
  /// # Example
  ///
  /// ```
  /// use wheel_timer::WheelTimer;
  ///
  /// let mut timer: WheelTimer<usize> = WheelTimer::new(20);
  /// timer.schedule(4, 1);
  /// timer.schedule(7, 1);
  /// timer.schedule(1, 1);
  /// assert_eq!(timer.size(), 3);
  /// ```
  pub fn size(&self) -> usize {
    self.size
  }

  /// Schedules a new value, available after `ticks` have passed.
  ///
  /// # Example
  ///
  /// ```
  /// use wheel_timer::WheelTimer;
  ///
  /// let mut timer: WheelTimer<usize> = WheelTimer::new(20);
  /// timer.schedule(4, 7); // schedule value 7 for 4 ticks
  /// ```
  pub fn schedule(&mut self, ticks: usize, value: T) {
    // Compute the scheduled position in the wheel
    let index = (self.current_tick + ticks) % self.max_interval;

    // Get the current node at `index` in the wheel and append the new node
    self.ring.index_mut(&index).push(value);

    // Increment the size counter
    self.size = self.size + 1;
  }

  /// Tick the timer, returning the node at the current tick.
  ///
  /// # Example
  ///
  /// ```
  /// use wheel_timer::WheelTimer;
  ///
  /// let mut timer: WheelTimer<usize> = WheelTimer::new(20);
  /// timer.schedule(3, 4); // schedule value 4 for 3 ticks
  /// timer.tick();
  /// timer.tick();
  /// timer.tick();
  /// let result = timer.tick(); // vec![4]
  /// assert_eq!(result.len(), 1);
  /// ```
  pub fn tick(&mut self) -> Vec<T> {
    // Get the node at the current tick in the wheel
    let node = mem::replace(self.ring.index_mut(&self.current_tick), Vec::new());

    // Increment the timer
    self.current_tick = (self.current_tick + 1) % self.max_interval;

    // Reduce the size by the length of the removed node
    self.size = self.size - node.len();

    // Return the node that was in that spot
    return node
  }
}
<|endoftext|>


<commit_before>extern crate test;

use test::Bencher;

use std::mem;
use std::fmt::{Show, Formatter, Result};
use std::iter::AdditiveIterator;

enum Node<T> {
  Cons(T, Box<Node<T>>),
  Nil
}

impl<T> Node<T> {
  fn prepend(self, elem: T) -> Node<T> {
    Cons(elem, box self)
  }

  fn len(&self) -> uint {
    match *self {
      Cons(_, ref tail) => tail.len() + 1,
      Nil => 0
    }
  }
}

impl<T: Show> Show for Node<T> {
  fn fmt(&self, f: &mut Formatter) -> Result {
    match *self {
      Cons(ref head, ref tail) => {
        write!(f, "{}, [ ] -> {}", head, tail)
      },
      Nil => {
        write!(f, "Nil")
      },
    }
  }
}

impl<T: PartialEq> PartialEq for Node<T> {
  fn eq(&self, ys: &Node<T>) -> bool {
    match (self, ys) {
      (&Nil, &Nil) => true,
      (&Cons(ref x, box ref next_xs), &Cons(ref y, box ref next_ys))
        if x == y => next_xs == next_ys,
      _ => false
    }
  }
}

// Simple hashed wheel timer with bounded interval
// See http://www.cs.columbia.edu/~nahum/w6998/papers/sosp87-timing-wheels.pdf
struct WheelTimer<T> {
  maxInterval: uint,
  currentTick: uint,

  ring: Vec<Node<T>>
}

impl<T> Iterator<Node<T>> for WheelTimer<T> {
  fn next(&mut self) -> Option<Node<T>> {
    let ticked = self.tick();
    return match ticked {
      Cons(_, _) => Some(ticked),
      Nil => None
    };
  }
}

impl<T> WheelTimer<T> {

  // Creates a new timer with the specified max interval
  fn new(maxInterval: uint) -> WheelTimer<T> {
    // Initialize the ring with Nil values
    let mut ring = Vec::with_capacity(maxInterval);
    for _ in range(0u, maxInterval) {
      ring.push(Nil)
    }

    return WheelTimer{
      maxInterval: maxInterval,
      currentTick: 0,
      ring: ring
    }
  }

  // Returns the number of items currently scheduled
  fn size(&self) -> uint {
    return self.ring.iter().map(|node| node.len()).sum()
  }

  // Schedules a new value, available after `ticks`
  fn schedule(&mut self, ticks: uint, value: T) {
    // Compute the scheduled position in the wheel
    let index = (self.currentTick + ticks) % self.maxInterval;

    // Get the current node at `index` in the wheel
    let node = mem::replace(self.ring.get_mut(index), Nil);

    // Set the position in the wheel with the appended node
    *self.ring.get_mut(index) = node.prepend(value);
  }

  // Tick the timer, returning the list of nodes at the spot
  fn tick(&mut self) -> Node<T> {
    // Get the node at the current tick in the wheel
    let node = mem::replace(self.ring.get_mut(self.currentTick), Nil);

    // Increment the timer
    self.currentTick = (self.currentTick + 1) % self.maxInterval;

    // Return the node that was in that spot
    return node
  }
}

#[test]
fn wheel_timer_new_test() {
  let timer = WheelTimer::<uint>::new(3);
  assert!(timer.maxInterval == 3);
  assert!(timer.ring.capacity() == 3);
  assert!(timer.ring.len() == 3);
}

#[test]
fn wheel_timer_schedule_test() {
  let mut timer = WheelTimer::<&'static str>::new(10);
  timer.schedule(3, "tick");

  timer.tick();
  timer.tick();
  timer.tick();

  let node = timer.tick();
  assert!(node != Nil);

  let val = match node {
    Cons(val, _) => val,
    Nil => ""
  };
  assert!(val == "tick");
}

#[test]
fn wheel_timer_tick_test() {
  let mut timer = WheelTimer::<uint>::new(10);

  for i in range(0, 10) {
    timer.schedule(i, i)
  }

  for i in range(0, 10) {
    let node = timer.tick();
    assert!(node != Nil);

    let val = match node {
      Cons(val, _) => val,
      Nil => -1
    };
    assert!(val == i);
  }
}

#[test]
fn wheel_timer_size_test() {
  let mut timer = WheelTimer::<uint>::new(10);

  for i in range(0, 10) {
    timer.schedule(i, i)
  }

  assert!(timer.size() == 10);

  for _ in timer {
  }

  assert!(timer.size() == 0);
}

#[bench]
fn bench_wheel_timer_drain(b: &mut Bencher) {
  let maxInterval = 20;
  let mut timer = WheelTimer::<uint>::new(maxInterval);

  b.iter(|| {
    // Fill
    for j in range(0u, 100u) {
      timer.schedule(j%maxInterval, j%maxInterval);
    }

    // Drain
    for k in timer {
      continue;
    }
  });
}

#[bench]
fn bench_wheel_timer_fill(b: &mut Bencher) {
  let maxInterval = 20;
  let mut timer = WheelTimer::<uint>::new(maxInterval);
  let mut i = 0;

  b.iter(|| {
    timer.schedule(i%maxInterval, i%maxInterval);
    i = i + 1;
  });
}

#[bench]
fn bench_wheel_timer_fast(b: &mut Bencher) {
  let maxInterval = 2;
  let mut timer = WheelTimer::<uint>::new(maxInterval);
  let mut i = 0;

  b.iter(|| {
    timer.schedule(i%maxInterval, i%maxInterval);
    timer.tick();
    i = i + 1;
  });
}
<commit_msg>Exposing WheelTimer<commit_after>extern crate test;

use test::Bencher;

use std::mem;
use std::fmt::{Show, Formatter, Result};
use std::iter::AdditiveIterator;

enum Node<T> {
  Cons(T, Box<Node<T>>),
  Nil
}

impl<T> Node<T> {
  fn prepend(self, elem: T) -> Node<T> {
    Cons(elem, box self)
  }

  fn len(&self) -> uint {
    match *self {
      Cons(_, ref tail) => tail.len() + 1,
      Nil => 0
    }
  }
}

impl<T: Show> Show for Node<T> {
  fn fmt(&self, f: &mut Formatter) -> Result {
    match *self {
      Cons(ref head, ref tail) => {
        write!(f, "{}, [ ] -> {}", head, tail)
      },
      Nil => {
        write!(f, "Nil")
      },
    }
  }
}

impl<T: PartialEq> PartialEq for Node<T> {
  fn eq(&self, ys: &Node<T>) -> bool {
    match (self, ys) {
      (&Nil, &Nil) => true,
      (&Cons(ref x, box ref next_xs), &Cons(ref y, box ref next_ys))
        if x == y => next_xs == next_ys,
      _ => false
    }
  }
}

// Simple hashed wheel timer with bounded interval
// See http://www.cs.columbia.edu/~nahum/w6998/papers/sosp87-timing-wheels.pdf
pub struct WheelTimer<T> {
  maxInterval: uint,
  currentTick: uint,

  ring: Vec<Node<T>>
}

impl<T> Iterator<Node<T>> for WheelTimer<T> {
  fn next(&mut self) -> Option<Node<T>> {
    let ticked = self.tick();
    return match ticked {
      Cons(_, _) => Some(ticked),
      Nil => None
    };
  }
}

impl<T> WheelTimer<T> {

  // Creates a new timer with the specified max interval
  fn new(maxInterval: uint) -> WheelTimer<T> {
    // Initialize the ring with Nil values
    let mut ring = Vec::with_capacity(maxInterval);
    for _ in range(0u, maxInterval) {
      ring.push(Nil)
    }

    return WheelTimer{
      maxInterval: maxInterval,
      currentTick: 0,
      ring: ring
    }
  }

  // Returns the number of items currently scheduled
  fn size(&self) -> uint {
    return self.ring.iter().map(|node| node.len()).sum()
  }

  // Schedules a new value, available after `ticks`
  fn schedule(&mut self, ticks: uint, value: T) {
    // Compute the scheduled position in the wheel
    let index = (self.currentTick + ticks) % self.maxInterval;

    // Get the current node at `index` in the wheel
    let node = mem::replace(self.ring.get_mut(index), Nil);

    // Set the position in the wheel with the appended node
    *self.ring.get_mut(index) = node.prepend(value);
  }

  // Tick the timer, returning the list of nodes at the spot
  fn tick(&mut self) -> Node<T> {
    // Get the node at the current tick in the wheel
    let node = mem::replace(self.ring.get_mut(self.currentTick), Nil);

    // Increment the timer
    self.currentTick = (self.currentTick + 1) % self.maxInterval;

    // Return the node that was in that spot
    return node
  }
}

#[test]
fn wheel_timer_new_test() {
  let timer = WheelTimer::<uint>::new(3);
  assert!(timer.maxInterval == 3);
  assert!(timer.ring.capacity() == 3);
  assert!(timer.ring.len() == 3);
}

#[test]
fn wheel_timer_schedule_test() {
  let mut timer = WheelTimer::<&'static str>::new(10);
  timer.schedule(3, "tick");

  timer.tick();
  timer.tick();
  timer.tick();

  let node = timer.tick();
  assert!(node != Nil);

  let val = match node {
    Cons(val, _) => val,
    Nil => ""
  };
  assert!(val == "tick");
}

#[test]
fn wheel_timer_tick_test() {
  let mut timer = WheelTimer::<uint>::new(10);

  for i in range(0, 10) {
    timer.schedule(i, i)
  }

  for i in range(0, 10) {
    let node = timer.tick();
    assert!(node != Nil);

    let val = match node {
      Cons(val, _) => val,
      Nil => -1
    };
    assert!(val == i);
  }
}

#[test]
fn wheel_timer_size_test() {
  let mut timer = WheelTimer::<uint>::new(10);

  for i in range(0, 10) {
    timer.schedule(i, i)
  }

  assert!(timer.size() == 10);

  for _ in timer {
  }

  assert!(timer.size() == 0);
}

#[bench]
fn bench_wheel_timer_drain(b: &mut Bencher) {
  let maxInterval = 20;
  let mut timer = WheelTimer::<uint>::new(maxInterval);

  b.iter(|| {
    // Fill
    for j in range(0u, 100u) {
      timer.schedule(j%maxInterval, j%maxInterval);
    }

    // Drain
    for k in timer {
      continue;
    }
  });
}

#[bench]
fn bench_wheel_timer_fill(b: &mut Bencher) {
  let maxInterval = 20;
  let mut timer = WheelTimer::<uint>::new(maxInterval);
  let mut i = 0;

  b.iter(|| {
    timer.schedule(i%maxInterval, i%maxInterval);
    i = i + 1;
  });
}

#[bench]
fn bench_wheel_timer_fast(b: &mut Bencher) {
  let maxInterval = 2;
  let mut timer = WheelTimer::<uint>::new(maxInterval);
  let mut i = 0;

  b.iter(|| {
    timer.schedule(i%maxInterval, i%maxInterval);
    timer.tick();
    i = i + 1;
  });
}
<|endoftext|>


<commit_before><commit_msg>Add #pragma hdrstop to preprocessed files.<commit_after><|endoftext|>