<commit_before>//! Metrics
//!
//! Varz are updated by pretty much all components, using only two
//! operations: set() and inc().

use coarsetime::Instant;
use prometheus::{Counter, Gauge, Histogram};

pub struct StartInstant(pub Instant);

pub struct Varz {
    pub start_instant: StartInstant,
    pub uptime: Gauge,
    pub cache_frequent_len: Gauge,
    pub cache_recent_len: Gauge,
    pub cache_test_len: Gauge,
    pub cache_inserted: Gauge,
    pub cache_evicted: Gauge,
    pub client_queries: Gauge,
    pub client_queries_udp: Counter,
    pub client_queries_tcp: Counter,
    pub client_queries_cached: Counter,
    pub client_queries_expired: Counter,
    pub client_queries_offline: Counter,
    pub client_queries_errors: Counter,
    pub inflight_queries: Gauge,
    pub upstream_errors: Counter,
    pub upstream_sent: Counter,
    pub upstream_received: Counter,
    pub upstream_timeout: Counter,
    pub upstream_avg_rtt: Gauge,
    pub upstream_response_sizes: Histogram,
}

impl Varz {
    pub fn new() -> Varz {
        Varz {
            start_instant: StartInstant::default(),
            uptime: register_gauge!(opts!("edgedns_uptime",
                                          "Uptime",
                                          labels!{"handler" => "all",}))
                    .unwrap(),
            cache_frequent_len: register_gauge!(opts!("edgedns_cache_frequent_len",
                                                      "Number of entries in the cached set of \
                                                       frequent items",
                                                      labels!{"handler" => "all",}))
                    .unwrap(),
            cache_recent_len: register_gauge!(opts!("edgedns_cache_recent_len",
                                                    "Number of entries in the cached set of \
                                                     recent items",
                                                    labels!{"handler" => "all",}))
                    .unwrap(),
            cache_test_len: register_gauge!(opts!("edgedns_cache_test_len",
                                                  "Number of entries in the cached set of \
                                                   staged items",
                                                  labels!{"handler" => "all",}))
                    .unwrap(),
            cache_inserted: register_gauge!(opts!("edgedns_cache_inserted",
                                                  "Number of entries added to the cache",
                                                  labels!{"handler" => "all",}))
                    .unwrap(),
            cache_evicted: register_gauge!(opts!("edgedns_cache_evicted",
                                                 "Number of entries evicted from the cache",
                                                 labels!{"handler" => "all",}))
                    .unwrap(),
            client_queries: register_gauge!(opts!("edgedns_client_queries",
                                                  "Number of client queries received",
                                                  labels!{"handler" => "all",}))
                    .unwrap(),
            client_queries_udp: register_counter!(opts!("edgedns_client_queries_udp",
                                                        "Number of client queries received \
                                                         using UDP",
                                                        labels!{"handler" => "all",}))
                    .unwrap(),
            client_queries_tcp: register_counter!(opts!("edgedns_client_queries_tcp",
                                                        "Number of client queries received \
                                                         using TCP",
                                                        labels!{"handler" => "all",}))
                    .unwrap(),
            client_queries_cached: register_counter!(opts!("edgedns_client_queries_cached",
                                                           "Number of client queries sent from \
                                                            the cache",
                                                           labels!{"handler" => "all",}))
                    .unwrap(),
            client_queries_expired: register_counter!(opts!("edgedns_client_queries_expired",
                                                            "Number of expired client queries",
                                                            labels!{"handler" => "all",}))
                    .unwrap(),
            client_queries_offline: register_counter!(opts!("edgedns_client_queries_offline",
                                                            "Number of client queries answered \
                                                             while upstream resolvers are \
                                                             unresponsive",
                                                            labels!{"handler" => "all",}))
                    .unwrap(),
            client_queries_errors: register_counter!(opts!("edgedns_client_queries_errors",
                                                           "Number of bogus client queries",
                                                           labels!{"handler" => "all",}))
                    .unwrap(),
            inflight_queries:
                register_gauge!(opts!("edgedns_inflight_queries",
                                      "Number of queries currently waiting for a response",
                                      labels!{"handler" => "all",}))
                        .unwrap(),
            upstream_errors: register_counter!(opts!("edgedns_upstream_errors",
                                                     "Number of bogus upstream servers responses",
                                                     labels!{"handler" => "all",}))
                    .unwrap(),
            upstream_sent: register_counter!(opts!("edgedns_upstream_sent",
                                                   "Number of upstream servers queries sent",
                                                   labels!{"handler" => "all",}))
                    .unwrap(),
            upstream_received:
                register_counter!(opts!("edgedns_upstream_received",
                                        "Number of upstream servers responses received",
                                        labels!{"handler" => "all",}))
                        .unwrap(),
            upstream_timeout: register_counter!(opts!("edgedns_upstream_timeout",
                                                      "Number of upstream servers responses \
                                                       having timed out",
                                                      labels!{"handler" => "all",}))
                    .unwrap(),
            upstream_avg_rtt: register_gauge!(opts!("edgedns_upstream_avg_rtt",
                                                    "Average RTT to upstream servers",
                                                    labels!{"handler" => "all",}))
                    .unwrap(),
            upstream_response_sizes: register_histogram!("edgedns_upstream_response_sizes",
                                                         "Response size in bytes.")
                    .unwrap(),
        }
    }
}

impl Default for Varz {
    fn default() -> Self {
        Self::new()
    }
}

impl Default for StartInstant {
    fn default() -> StartInstant {
        StartInstant(Instant::now())
    }
}
<commit_msg>Define edgedns_upstream_response_sizes buckets<commit_after>//! Metrics
//!
//! Varz are updated by pretty much all components, using only two
//! operations: set() and inc().

use coarsetime::Instant;
use prometheus::{Counter, Gauge, Histogram};

pub struct StartInstant(pub Instant);

pub struct Varz {
    pub start_instant: StartInstant,
    pub uptime: Gauge,
    pub cache_frequent_len: Gauge,
    pub cache_recent_len: Gauge,
    pub cache_test_len: Gauge,
    pub cache_inserted: Gauge,
    pub cache_evicted: Gauge,
    pub client_queries: Gauge,
    pub client_queries_udp: Counter,
    pub client_queries_tcp: Counter,
    pub client_queries_cached: Counter,
    pub client_queries_expired: Counter,
    pub client_queries_offline: Counter,
    pub client_queries_errors: Counter,
    pub inflight_queries: Gauge,
    pub upstream_errors: Counter,
    pub upstream_sent: Counter,
    pub upstream_received: Counter,
    pub upstream_timeout: Counter,
    pub upstream_avg_rtt: Gauge,
    pub upstream_response_sizes: Histogram,
}

impl Varz {
    pub fn new() -> Varz {
        Varz {
            start_instant: StartInstant::default(),
            uptime: register_gauge!(opts!("edgedns_uptime",
                                          "Uptime",
                                          labels!{"handler" => "all",}))
                    .unwrap(),
            cache_frequent_len: register_gauge!(opts!("edgedns_cache_frequent_len",
                                                      "Number of entries in the cached set of \
                                                       frequent items",
                                                      labels!{"handler" => "all",}))
                    .unwrap(),
            cache_recent_len: register_gauge!(opts!("edgedns_cache_recent_len",
                                                    "Number of entries in the cached set of \
                                                     recent items",
                                                    labels!{"handler" => "all",}))
                    .unwrap(),
            cache_test_len: register_gauge!(opts!("edgedns_cache_test_len",
                                                  "Number of entries in the cached set of \
                                                   staged items",
                                                  labels!{"handler" => "all",}))
                    .unwrap(),
            cache_inserted: register_gauge!(opts!("edgedns_cache_inserted",
                                                  "Number of entries added to the cache",
                                                  labels!{"handler" => "all",}))
                    .unwrap(),
            cache_evicted: register_gauge!(opts!("edgedns_cache_evicted",
                                                 "Number of entries evicted from the cache",
                                                 labels!{"handler" => "all",}))
                    .unwrap(),
            client_queries: register_gauge!(opts!("edgedns_client_queries",
                                                  "Number of client queries received",
                                                  labels!{"handler" => "all",}))
                    .unwrap(),
            client_queries_udp: register_counter!(opts!("edgedns_client_queries_udp",
                                                        "Number of client queries received \
                                                         using UDP",
                                                        labels!{"handler" => "all",}))
                    .unwrap(),
            client_queries_tcp: register_counter!(opts!("edgedns_client_queries_tcp",
                                                        "Number of client queries received \
                                                         using TCP",
                                                        labels!{"handler" => "all",}))
                    .unwrap(),
            client_queries_cached: register_counter!(opts!("edgedns_client_queries_cached",
                                                           "Number of client queries sent from \
                                                            the cache",
                                                           labels!{"handler" => "all",}))
                    .unwrap(),
            client_queries_expired: register_counter!(opts!("edgedns_client_queries_expired",
                                                            "Number of expired client queries",
                                                            labels!{"handler" => "all",}))
                    .unwrap(),
            client_queries_offline: register_counter!(opts!("edgedns_client_queries_offline",
                                                            "Number of client queries answered \
                                                             while upstream resolvers are \
                                                             unresponsive",
                                                            labels!{"handler" => "all",}))
                    .unwrap(),
            client_queries_errors: register_counter!(opts!("edgedns_client_queries_errors",
                                                           "Number of bogus client queries",
                                                           labels!{"handler" => "all",}))
                    .unwrap(),
            inflight_queries:
                register_gauge!(opts!("edgedns_inflight_queries",
                                      "Number of queries currently waiting for a response",
                                      labels!{"handler" => "all",}))
                        .unwrap(),
            upstream_errors: register_counter!(opts!("edgedns_upstream_errors",
                                                     "Number of bogus upstream servers responses",
                                                     labels!{"handler" => "all",}))
                    .unwrap(),
            upstream_sent: register_counter!(opts!("edgedns_upstream_sent",
                                                   "Number of upstream servers queries sent",
                                                   labels!{"handler" => "all",}))
                    .unwrap(),
            upstream_received:
                register_counter!(opts!("edgedns_upstream_received",
                                        "Number of upstream servers responses received",
                                        labels!{"handler" => "all",}))
                        .unwrap(),
            upstream_timeout: register_counter!(opts!("edgedns_upstream_timeout",
                                                      "Number of upstream servers responses \
                                                       having timed out",
                                                      labels!{"handler" => "all",}))
                    .unwrap(),
            upstream_avg_rtt: register_gauge!(opts!("edgedns_upstream_avg_rtt",
                                                    "Average RTT to upstream servers",
                                                    labels!{"handler" => "all",}))
                    .unwrap(),
            upstream_response_sizes: register_histogram!(histogram_opts!("edgedns_upstream_response_sizes",
                                                                         "Response size in bytes",
                                                                         vec![64.0, 128.0,
                                                                              192.0, 256.0,
                                                                              512.0, 1024.0,
                                                                              2048.0]))
                    .unwrap(),
        }
    }
}

impl Default for Varz {
    fn default() -> Self {
        Self::new()
    }
}

impl Default for StartInstant {
    fn default() -> StartInstant {
        StartInstant(Instant::now())
    }
}
<|endoftext|>


<commit_before>extern crate sdl2;

use super::start;

#[derive(Clone, Copy, Debug)]
pub struct FlatPoint {
    pub x: i32,
    pub y: i32,
}

impl FlatPoint {
    pub fn make_sdl(&self) -> sdl2::rect::Point {
        sdl2::rect::Point::new(self.x, self.y)
    }
}

#[derive(Clone, Copy, Debug)]
pub struct DepthPoint {
    pub x: f32,
    pub y: f32,
    pub z: f32,

    pub x_y: f32,
    pub x_z: f32,
    pub y_z: f32,

    last_x_y: f32,
    last_x_z: f32,
    last_y_z: f32,
}

impl DepthPoint {
    pub fn new(x: f32, y: f32, z: f32) -> DepthPoint {
        DepthPoint {
            x: x,
            y: y,
            z: z,

            x_y: 0.0,
            x_z: 0.0,
            y_z: 0.0,

            last_x_y: 0.0,
            last_x_z: 0.0,
            last_y_z: 0.0,
        }
    }

    pub fn flat_point(&mut self, engine_scr_x: u32, engine_scr_y: u32, offset_x: f32, offset_y: f32, offset_z: f32) -> FlatPoint {
        if self.z > -0.01 && self.z < 0.0 {
            self.z = 0.001
        }

        else if self.z < 0.1 { // Prevents division by nearly 0, that cause integer overflow/underflow
            self.z = 0.11;
        }

        FlatPoint {
            x: ((engine_scr_x as f32 * (self.x + offset_x) as f32/(self.z + offset_z)) + engine_scr_x as f32 / 2.0) as i32,
            y: ((engine_scr_x as f32 * (self.y + offset_y) as f32/(self.z + offset_z)) + engine_scr_y as f32 / 2.0) as i32,
        }
    }

    pub fn apply_camera_rotations(&mut self, engine: &start::Engine) {
        let x_y = self.x_y;
        let x_z = self.x_z;
        let y_z = self.y_z;

        let last_x_y = self.last_x_y;
        let last_x_z = self.last_x_z;
        let last_y_z = self.last_y_z;

        self.rotate_x_y(&engine, x_y - last_x_y);
        self.rotate_x_z(&engine, x_z - last_x_z);
        self.rotate_y_z(&engine, y_z - last_y_z);

        self.last_x_y = x_y;
        self.last_x_z = x_z;
        self.last_y_z = y_z;
    }

    pub fn rotate_x_y(&mut self, engine: &start::Engine, angle: f32) {
        use std::f32;
        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.x -= engine.camera_x;
        self.y -= engine.camera_y;

        let new_x = self.x * c - self.y * s;
        let new_y = self.x * s + self.y * c;

        self.x = new_x + engine.camera_x;
        self.y = new_y + engine.camera_y;
    }

    pub fn rotate_x_z(&mut self, engine: &start::Engine, angle: f32) {
        use std::f32;
        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.x -= engine.camera_x;
        self.z -= engine.camera_z;

        let new_x = self.x * c - self.z * s;
        let new_z = self.x * s + self.z * c;

        self.x = new_x + engine.camera_x;
        self.z = new_z + engine.camera_z;
    }

    pub fn rotate_y_z(&mut self, engine: &start::Engine, angle: f32) {
        use std::f32;
        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.y -= engine.camera_y;
        self.z -= engine.camera_z;

        let new_y = self.y * c - self.z * s;
        let new_z = self.y * s + self.z * c;

        self.y = new_y + engine.camera_y;
        self.z = new_z + engine.camera_z;
    }
}

#[derive(Clone, Copy, Debug)]
pub struct Triangle {
    pub p1: DepthPoint,
    pub p2: DepthPoint,
    pub p3: DepthPoint,

    pub x: f32,
    pub y: f32,
    pub z: f32,

    pub x_y: f32,
    pub x_z: f32,
    pub y_z: f32,

    last_x_y: f32,
    last_x_z: f32,
    last_y_z: f32,
}

impl Triangle {
    pub fn new(p1: DepthPoint, p2: DepthPoint, p3: DepthPoint, x: f32, y: f32, z: f32) -> Triangle {
        Triangle {
            p1: p1,
            p2: p2,
            p3: p3,

            x: x,
            y: y,
            z: z,

            x_y: 0.0,
            x_z: 0.0,
            y_z: 0.0,

            last_x_y: 0.0,
            last_x_z: 0.0,
            last_y_z: 0.0,
        }
    }
}<commit_msg>Renamed rotation functions to indicade they rotate points around the camera.<commit_after>extern crate sdl2;

use super::start;

#[derive(Clone, Copy, Debug)]
pub struct FlatPoint {
    pub x: i32,
    pub y: i32,
}

impl FlatPoint {
    pub fn make_sdl(&self) -> sdl2::rect::Point {
        sdl2::rect::Point::new(self.x, self.y)
    }
}

#[derive(Clone, Copy, Debug)]
pub struct DepthPoint {
    pub x: f32,
    pub y: f32,
    pub z: f32,

    pub x_y: f32,
    pub x_z: f32,
    pub y_z: f32,

    last_x_y: f32,
    last_x_z: f32,
    last_y_z: f32,
}

impl DepthPoint {
    pub fn new(x: f32, y: f32, z: f32) -> DepthPoint {
        DepthPoint {
            x: x,
            y: y,
            z: z,

            x_y: 0.0,
            x_z: 0.0,
            y_z: 0.0,

            last_x_y: 0.0,
            last_x_z: 0.0,
            last_y_z: 0.0,
        }
    }

    pub fn flat_point(&mut self, engine_scr_x: u32, engine_scr_y: u32, offset_x: f32, offset_y: f32, offset_z: f32) -> FlatPoint {
        if self.z > -0.01 && self.z < 0.0 {
            self.z = 0.001
        }

        else if self.z < 0.1 { // Prevents division by nearly 0, that cause integer overflow/underflow
            self.z = 0.11;
        }

        FlatPoint {
            x: ((engine_scr_x as f32 * (self.x + offset_x) as f32/(self.z + offset_z)) + engine_scr_x as f32 / 2.0) as i32,
            y: ((engine_scr_x as f32 * (self.y + offset_y) as f32/(self.z + offset_z)) + engine_scr_y as f32 / 2.0) as i32,
        }
    }

    pub fn apply_camera_rotations(&mut self, engine: &start::Engine) {
        let x_y = self.x_y;
        let x_z = self.x_z;
        let y_z = self.y_z;

        let last_x_y = self.last_x_y;
        let last_x_z = self.last_x_z;
        let last_y_z = self.last_y_z;

        self.camera_rotate_x_y(&engine, x_y - last_x_y);
        self.camera_rotate_x_z(&engine, x_z - last_x_z);
        self.camera_rotate_y_z(&engine, y_z - last_y_z);

        self.last_x_y = x_y;
        self.last_x_z = x_z;
        self.last_y_z = y_z;
    }

    pub fn camera_rotate_x_y(&mut self, engine: &start::Engine, angle: f32) {
        use std::f32;
        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.x -= engine.camera_x;
        self.y -= engine.camera_y;

        let new_x = self.x * c - self.y * s;
        let new_y = self.x * s + self.y * c;

        self.x = new_x + engine.camera_x;
        self.y = new_y + engine.camera_y;
    }

    pub fn camera_rotate_x_z(&mut self, engine: &start::Engine, angle: f32) {
        use std::f32;
        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.x -= engine.camera_x;
        self.z -= engine.camera_z;

        let new_x = self.x * c - self.z * s;
        let new_z = self.x * s + self.z * c;

        self.x = new_x + engine.camera_x;
        self.z = new_z + engine.camera_z;
    }

    pub fn camera_rotate_y_z(&mut self, engine: &start::Engine, angle: f32) {
        use std::f32;
        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.y -= engine.camera_y;
        self.z -= engine.camera_z;

        let new_y = self.y * c - self.z * s;
        let new_z = self.y * s + self.z * c;

        self.y = new_y + engine.camera_y;
        self.z = new_z + engine.camera_z;
    }
}

#[derive(Clone, Copy, Debug)]
pub struct Triangle {
    pub p1: DepthPoint,
    pub p2: DepthPoint,
    pub p3: DepthPoint,

    pub x: f32,
    pub y: f32,
    pub z: f32,

    pub x_y: f32,
    pub x_z: f32,
    pub y_z: f32,

    last_x_y: f32,
    last_x_z: f32,
    last_y_z: f32,
}

impl Triangle {
    pub fn new(p1: DepthPoint, p2: DepthPoint, p3: DepthPoint, x: f32, y: f32, z: f32) -> Triangle {
        Triangle {
            p1: p1,
            p2: p2,
            p3: p3,

            x: x,
            y: y,
            z: z,

            x_y: 0.0,
            x_z: 0.0,
            y_z: 0.0,

            last_x_y: 0.0,
            last_x_z: 0.0,
            last_y_z: 0.0,
        }
    }
}<|endoftext|>


<commit_before><commit_msg>Introduce PIO Generics<commit_after><|endoftext|>


<commit_before><commit_msg>fix: ArgRequiredElseHelp setting now takes precedence over missing required args<commit_after><|endoftext|>


<commit_before><commit_msg>Do not call into_iter() when iter() is sufficient<commit_after><|endoftext|>


<commit_before><commit_msg>impl Deserialize for m.ignored_user_list<commit_after><|endoftext|>


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

#![unstable(feature = "futures_api",
            reason = "futures in libcore are unstable",
            issue = "50547")]

use fmt;
use future::Future;
use marker::PhantomData;
use mem::PinMut;
use task::{Context, Poll};

/// A custom trait object for polling futures, roughly akin to
/// `Box<dyn Future<Output = T>>`.
/// Contrary to `FutureObj`, `LocalFutureObj` does not have a `Send` bound.
pub struct LocalFutureObj<'a, T> {
    ptr: *mut (),
    poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<T>,
    drop_fn: unsafe fn(*mut ()),
    _marker1: PhantomData<T>,
    _marker2: PhantomData<&'a ()>,
}

impl<'a, T> LocalFutureObj<'a, T> {
    /// Create a `LocalFutureObj` from a custom trait object representation.
    #[inline]
    pub fn new<F: UnsafeFutureObj<'a, T> + 'a>(f: F) -> LocalFutureObj<'a, T> {
        LocalFutureObj {
            ptr: f.into_raw(),
            poll_fn: F::poll,
            drop_fn: F::drop,
            _marker1: PhantomData,
            _marker2: PhantomData,
        }
    }

    /// Converts the `LocalFutureObj` into a `FutureObj`
    /// To make this operation safe one has to ensure that the `UnsafeFutureObj`
    /// instance from which this `LocalFutureObj` was created actually
    /// implements `Send`.
    #[inline]
    pub unsafe fn as_future_obj(self) -> FutureObj<'a, T> {
        FutureObj(self)
    }
}

impl<'a, T> fmt::Debug for LocalFutureObj<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("LocalFutureObj")
            .finish()
    }
}

impl<'a, T> From<FutureObj<'a, T>> for LocalFutureObj<'a, T> {
    #[inline]
    fn from(f: FutureObj<'a, T>) -> LocalFutureObj<'a, T> {
        f.0
    }
}

impl<'a, T> Future for LocalFutureObj<'a, T> {
    type Output = T;

    #[inline]
    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<T> {
        unsafe {
            (self.poll_fn)(self.ptr, cx)
        }
    }
}

impl<'a, T> Drop for LocalFutureObj<'a, T> {
    fn drop(&mut self) {
        unsafe {
            (self.drop_fn)(self.ptr)
        }
    }
}

/// A custom trait object for polling futures, roughly akin to
/// `Box<dyn Future<Output = T>> + Send`.
pub struct FutureObj<'a, T>(LocalFutureObj<'a, T>);

unsafe impl<'a, T> Send for FutureObj<'a, T> {}

impl<'a, T> FutureObj<'a, T> {
    /// Create a `FutureObj` from a custom trait object representation.
    #[inline]
    pub fn new<F: UnsafeFutureObj<'a, T> + Send>(f: F) -> FutureObj<'a, T> {
        FutureObj(LocalFutureObj::new(f))
    }
}

impl<'a, T> fmt::Debug for FutureObj<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("FutureObj")
            .finish()
    }
}

impl<'a, T> Future for FutureObj<'a, T> {
    type Output = T;

    #[inline]
    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<T> {
        let pinned_field = unsafe { PinMut::map_unchecked(self, |x| &mut x.0) };
        pinned_field.poll(cx)
    }
}

/// A custom implementation of a future trait object for `FutureObj`, providing
/// a hand-rolled vtable.
///
/// This custom representation is typically used only in `no_std` contexts,
/// where the default `Box`-based implementation is not available.
///
/// The implementor must guarantee that it is safe to call `poll` repeatedly (in
/// a non-concurrent fashion) with the result of `into_raw` until `drop` is
/// called.
pub unsafe trait UnsafeFutureObj<'a, T>: 'a {
    /// Convert an owned instance into a (conceptually owned) void pointer.
    fn into_raw(self) -> *mut ();

    /// Poll the future represented by the given void pointer.
    ///
    /// # Safety
    ///
    /// The trait implementor must guarantee that it is safe to repeatedly call
    /// `poll` with the result of `into_raw` until `drop` is called; such calls
    /// are not, however, allowed to race with each other or with calls to `drop`.
    unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T>;

    /// Drops the future represented by the given void pointer.
    ///
    /// # Safety
    ///
    /// The trait implementor must guarantee that it is safe to call this
    /// function once per `into_raw` invocation; that call cannot race with
    /// other calls to `drop` or `poll`.
    unsafe fn drop(ptr: *mut ());
}
<commit_msg>Improve doc comments for `FutureObj`<commit_after>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![unstable(feature = "futures_api",
            reason = "futures in libcore are unstable",
            issue = "50547")]

use fmt;
use future::Future;
use marker::PhantomData;
use mem::PinMut;
use task::{Context, Poll};

/// A custom trait object for polling futures, roughly akin to
/// `Box<dyn Future<Output = T> + 'a>`.
/// Contrary to `FutureObj`, `LocalFutureObj` does not have a `Send` bound.
pub struct LocalFutureObj<'a, T> {
    ptr: *mut (),
    poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<T>,
    drop_fn: unsafe fn(*mut ()),
    _marker1: PhantomData<T>,
    _marker2: PhantomData<&'a ()>,
}

impl<'a, T> LocalFutureObj<'a, T> {
    /// Create a `LocalFutureObj` from a custom trait object representation.
    #[inline]
    pub fn new<F: UnsafeFutureObj<'a, T> + 'a>(f: F) -> LocalFutureObj<'a, T> {
        LocalFutureObj {
            ptr: f.into_raw(),
            poll_fn: F::poll,
            drop_fn: F::drop,
            _marker1: PhantomData,
            _marker2: PhantomData,
        }
    }

    /// Converts the `LocalFutureObj` into a `FutureObj`
    /// To make this operation safe one has to ensure that the `UnsafeFutureObj`
    /// instance from which this `LocalFutureObj` was created actually
    /// implements `Send`.
    #[inline]
    pub unsafe fn as_future_obj(self) -> FutureObj<'a, T> {
        FutureObj(self)
    }
}

impl<'a, T> fmt::Debug for LocalFutureObj<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("LocalFutureObj")
            .finish()
    }
}

impl<'a, T> From<FutureObj<'a, T>> for LocalFutureObj<'a, T> {
    #[inline]
    fn from(f: FutureObj<'a, T>) -> LocalFutureObj<'a, T> {
        f.0
    }
}

impl<'a, T> Future for LocalFutureObj<'a, T> {
    type Output = T;

    #[inline]
    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<T> {
        unsafe {
            (self.poll_fn)(self.ptr, cx)
        }
    }
}

impl<'a, T> Drop for LocalFutureObj<'a, T> {
    fn drop(&mut self) {
        unsafe {
            (self.drop_fn)(self.ptr)
        }
    }
}

/// A custom trait object for polling futures, roughly akin to
/// `Box<dyn Future<Output = T> + Send + 'a>`.
pub struct FutureObj<'a, T>(LocalFutureObj<'a, T>);

unsafe impl<'a, T> Send for FutureObj<'a, T> {}

impl<'a, T> FutureObj<'a, T> {
    /// Create a `FutureObj` from a custom trait object representation.
    #[inline]
    pub fn new<F: UnsafeFutureObj<'a, T> + Send>(f: F) -> FutureObj<'a, T> {
        FutureObj(LocalFutureObj::new(f))
    }
}

impl<'a, T> fmt::Debug for FutureObj<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("FutureObj")
            .finish()
    }
}

impl<'a, T> Future for FutureObj<'a, T> {
    type Output = T;

    #[inline]
    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<T> {
        let pinned_field = unsafe { PinMut::map_unchecked(self, |x| &mut x.0) };
        pinned_field.poll(cx)
    }
}

/// A custom implementation of a future trait object for `FutureObj`, providing
/// a hand-rolled vtable.
///
/// This custom representation is typically used only in `no_std` contexts,
/// where the default `Box`-based implementation is not available.
///
/// The implementor must guarantee that it is safe to call `poll` repeatedly (in
/// a non-concurrent fashion) with the result of `into_raw` until `drop` is
/// called.
pub unsafe trait UnsafeFutureObj<'a, T>: 'a {
    /// Convert an owned instance into a (conceptually owned) void pointer.
    fn into_raw(self) -> *mut ();

    /// Poll the future represented by the given void pointer.
    ///
    /// # Safety
    ///
    /// The trait implementor must guarantee that it is safe to repeatedly call
    /// `poll` with the result of `into_raw` until `drop` is called; such calls
    /// are not, however, allowed to race with each other or with calls to
    /// `drop`.
    unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T>;

    /// Drops the future represented by the given void pointer.
    ///
    /// # Safety
    ///
    /// The trait implementor must guarantee that it is safe to call this
    /// function once per `into_raw` invocation; that call cannot race with
    /// other calls to `drop` or `poll`.
    unsafe fn drop(ptr: *mut ());
}
<|endoftext|>


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

//! C definitions used by libnative that don't belong in liblibc

#![allow(dead_code)]
#![allow(non_camel_case_types)]

pub use self::select::fd_set;
pub use self::signal::{sigaction, siginfo, sigset_t};
pub use self::signal::{SA_ONSTACK, SA_RESTART, SA_RESETHAND, SA_NOCLDSTOP};
pub use self::signal::{SA_NODEFER, SA_NOCLDWAIT, SA_SIGINFO, SIGCHLD};

use libc;

#[cfg(any(target_os = "macos",
          target_os = "ios",
          target_os = "freebsd",
          target_os = "dragonfly",
          target_os = "openbsd"))]
pub const FIONBIO: libc::c_ulong = 0x8004667e;
#[cfg(any(all(target_os = "linux",
              any(target_arch = "x86",
                  target_arch = "x86_64",
                  target_arch = "arm",
                  target_arch = "aarch64")),
          target_os = "android"))]
pub const FIONBIO: libc::c_ulong = 0x5421;
#[cfg(all(target_os = "linux",
          any(target_arch = "mips",
              target_arch = "mipsel",
              target_arch = "powerpc")))]
pub const FIONBIO: libc::c_ulong = 0x667e;

#[cfg(any(target_os = "macos",
          target_os = "ios",
          target_os = "freebsd",
          target_os = "dragonfly",
          target_os = "openbsd"))]
pub const FIOCLEX: libc::c_ulong = 0x20006601;
#[cfg(any(all(target_os = "linux",
              any(target_arch = "x86",
                  target_arch = "x86_64",
                  target_arch = "arm",
                  target_arch = "aarch64")),
          target_os = "android"))]
pub const FIOCLEX: libc::c_ulong = 0x5451;
#[cfg(all(target_os = "linux",
          any(target_arch = "mips",
              target_arch = "mipsel",
              target_arch = "powerpc")))]
pub const FIOCLEX: libc::c_ulong = 0x6601;

#[cfg(any(target_os = "macos",
          target_os = "ios",
          target_os = "freebsd",
          target_os = "dragonfly",
          target_os = "openbsd"))]
pub const MSG_DONTWAIT: libc::c_int = 0x80;
#[cfg(any(target_os = "linux", target_os = "android"))]
pub const MSG_DONTWAIT: libc::c_int = 0x40;

pub const WNOHANG: libc::c_int = 1;

#[cfg(target_os = "linux")]
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 70;
#[cfg(any(target_os = "macos",
          target_os = "freebsd"))]
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 71;
#[cfg(target_os = "openbsd")]
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 101;
#[cfg(target_os = "android")]
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 0x0048;

#[repr(C)]
#[cfg(target_os = "linux")]
pub struct passwd {
    pub pw_name: *mut libc::c_char,
    pub pw_passwd: *mut libc::c_char,
    pub pw_uid: libc::uid_t,
    pub pw_gid: libc::gid_t,
    pub pw_gecos: *mut libc::c_char,
    pub pw_dir: *mut libc::c_char,
    pub pw_shell: *mut libc::c_char,
}

#[repr(C)]
#[cfg(any(target_os = "macos",
          target_os = "freebsd",
          target_os = "openbsd"))]
pub struct passwd {
    pub pw_name: *mut libc::c_char,
    pub pw_passwd: *mut libc::c_char,
    pub pw_uid: libc::uid_t,
    pub pw_gid: libc::gid_t,
    pub pw_change: libc::time_t,
    pub pw_class: *mut libc::c_char,
    pub pw_gecos: *mut libc::c_char,
    pub pw_dir: *mut libc::c_char,
    pub pw_shell: *mut libc::c_char,
    pub pw_expire: libc::time_t,
}

#[repr(C)]
#[cfg(target_os = "android")]
pub struct passwd {
    pub pw_name: *mut libc::c_char,
    pub pw_passwd: *mut libc::c_char,
    pub pw_uid: libc::uid_t,
    pub pw_gid: libc::gid_t,
    pub pw_dir: *mut libc::c_char,
    pub pw_shell: *mut libc::c_char,
}

extern {
    pub fn gettimeofday(timeval: *mut libc::timeval,
                        tzp: *mut libc::c_void) -> libc::c_int;
    pub fn select(nfds: libc::c_int,
                  readfds: *mut fd_set,
                  writefds: *mut fd_set,
                  errorfds: *mut fd_set,
                  timeout: *mut libc::timeval) -> libc::c_int;
    pub fn getsockopt(sockfd: libc::c_int,
                      level: libc::c_int,
                      optname: libc::c_int,
                      optval: *mut libc::c_void,
                      optlen: *mut libc::socklen_t) -> libc::c_int;
    pub fn ioctl(fd: libc::c_int, req: libc::c_ulong, ...) -> libc::c_int;

    pub fn waitpid(pid: libc::pid_t, status: *mut libc::c_int,
                   options: libc::c_int) -> libc::pid_t;

    pub fn sigaction(signum: libc::c_int,
                     act: *const sigaction,
                     oldact: *mut sigaction) -> libc::c_int;

    pub fn sigaddset(set: *mut sigset_t, signum: libc::c_int) -> libc::c_int;
    pub fn sigdelset(set: *mut sigset_t, signum: libc::c_int) -> libc::c_int;
    pub fn sigemptyset(set: *mut sigset_t) -> libc::c_int;

    #[cfg(not(target_os = "ios"))]
    pub fn getpwuid_r(uid: libc::uid_t,
                      pwd: *mut passwd,
                      buf: *mut libc::c_char,
                      buflen: libc::size_t,
                      result: *mut *mut passwd) -> libc::c_int;
}

#[cfg(any(target_os = "macos", target_os = "ios"))]
mod select {
    pub const FD_SETSIZE: uint = 1024;

    #[repr(C)]
    pub struct fd_set {
        fds_bits: [i32; (FD_SETSIZE / 32)]
    }

    pub fn fd_set(set: &mut fd_set, fd: i32) {
        set.fds_bits[(fd / 32) as uint] |= 1 << ((fd % 32) as uint);
    }
}

#[cfg(any(target_os = "android",
          target_os = "freebsd",
          target_os = "dragonfly",
          target_os = "openbsd",
          target_os = "linux"))]
mod select {
    use uint;
    use libc;

    pub const FD_SETSIZE: uint = 1024;

    #[repr(C)]
    pub struct fd_set {
        // FIXME: shouldn't this be a c_ulong?
        fds_bits: [libc::uintptr_t; (FD_SETSIZE / uint::BITS)]
    }

    pub fn fd_set(set: &mut fd_set, fd: i32) {
        let fd = fd as uint;
        set.fds_bits[fd / uint::BITS] |= 1 << (fd % uint::BITS);
    }
}

#[cfg(any(all(target_os = "linux",
              any(target_arch = "x86",
                  target_arch = "x86_64",
                  target_arch = "arm",
                  target_arch = "aarch64")),
          target_os = "android"))]
mod signal {
    use libc;

    pub const SA_NOCLDSTOP: libc::c_ulong = 0x00000001;
    pub const SA_NOCLDWAIT: libc::c_ulong = 0x00000002;
    pub const SA_NODEFER: libc::c_ulong = 0x40000000;
    pub const SA_ONSTACK: libc::c_ulong = 0x08000000;
    pub const SA_RESETHAND: libc::c_ulong = 0x80000000;
    pub const SA_RESTART: libc::c_ulong = 0x10000000;
    pub const SA_SIGINFO: libc::c_ulong = 0x00000004;
    pub const SIGCHLD: libc::c_int = 17;

    // This definition is not as accurate as it could be, {pid, uid, status} is
    // actually a giant union. Currently we're only interested in these fields,
    // however.
    #[repr(C)]
    pub struct siginfo {
        si_signo: libc::c_int,
        si_errno: libc::c_int,
        si_code: libc::c_int,
        pub pid: libc::pid_t,
        pub uid: libc::uid_t,
        pub status: libc::c_int,
    }

    #[repr(C)]
    pub struct sigaction {
        pub sa_handler: extern fn(libc::c_int),
        pub sa_mask: sigset_t,
        pub sa_flags: libc::c_ulong,
        sa_restorer: *mut libc::c_void,
    }

    unsafe impl ::marker::Send for sigaction { }
    unsafe impl ::marker::Sync for sigaction { }

    #[repr(C)]
    #[cfg(target_pointer_width = "32")]
    pub struct sigset_t {
        __val: [libc::c_ulong; 32],
    }

    #[repr(C)]
    #[cfg(target_pointer_width = "64")]
    pub struct sigset_t {
        __val: [libc::c_ulong; 16],
    }
}

#[cfg(all(target_os = "linux",
          any(target_arch = "mips",
              target_arch = "mipsel",
              target_arch = "powerpc")))]
mod signal {
    use libc;

    pub const SA_NOCLDSTOP: libc::c_ulong = 0x00000001;
    pub const SA_NOCLDWAIT: libc::c_ulong = 0x00010000;
    pub const SA_NODEFER: libc::c_ulong = 0x40000000;
    pub const SA_ONSTACK: libc::c_ulong = 0x08000000;
    pub const SA_RESETHAND: libc::c_ulong = 0x80000000;
    pub const SA_RESTART: libc::c_ulong = 0x10000000;
    pub const SA_SIGINFO: libc::c_ulong = 0x00000008;
    pub const SIGCHLD: libc::c_int = 18;

    // This definition is not as accurate as it could be, {pid, uid, status} is
    // actually a giant union. Currently we're only interested in these fields,
    // however.
    #[repr(C)]
    pub struct siginfo {
        si_signo: libc::c_int,
        si_code: libc::c_int,
        si_errno: libc::c_int,
        pub pid: libc::pid_t,
        pub uid: libc::uid_t,
        pub status: libc::c_int,
    }

    #[repr(C)]
    pub struct sigaction {
        pub sa_flags: libc::c_uint,
        pub sa_handler: extern fn(libc::c_int),
        pub sa_mask: sigset_t,
        sa_restorer: *mut libc::c_void,
        sa_resv: [libc::c_int; 1],
    }

    unsafe impl ::marker::Send for sigaction { }
    unsafe impl ::marker::Sync for sigaction { }

    #[repr(C)]
    pub struct sigset_t {
        __val: [libc::c_ulong; 32],
    }
}

#[cfg(any(target_os = "macos",
          target_os = "ios",
          target_os = "freebsd",
          target_os = "dragonfly",
          target_os = "openbsd"))]
mod signal {
    use libc;

    pub const SA_ONSTACK: libc::c_int = 0x0001;
    pub const SA_RESTART: libc::c_int = 0x0002;
    pub const SA_RESETHAND: libc::c_int = 0x0004;
    pub const SA_NOCLDSTOP: libc::c_int = 0x0008;
    pub const SA_NODEFER: libc::c_int = 0x0010;
    pub const SA_NOCLDWAIT: libc::c_int = 0x0020;
    pub const SA_SIGINFO: libc::c_int = 0x0040;
    pub const SIGCHLD: libc::c_int = 20;

    #[cfg(any(target_os = "macos",
              target_os = "ios",
              target_os = "openbsd"))]
    pub type sigset_t = u32;
    #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
    #[repr(C)]
    pub struct sigset_t {
        bits: [u32; 4],
    }

    // This structure has more fields, but we're not all that interested in
    // them.
    #[repr(C)]
    pub struct siginfo {
        pub si_signo: libc::c_int,
        pub si_errno: libc::c_int,
        pub si_code: libc::c_int,
        pub pid: libc::pid_t,
        pub uid: libc::uid_t,
        pub status: libc::c_int,
    }

    #[repr(C)]
    pub struct sigaction {
        pub sa_handler: extern fn(libc::c_int),
        pub sa_flags: libc::c_int,
        pub sa_mask: sigset_t,
    }
}
<commit_msg>Fix struct passwd and _SC_GETPW_R_SIZE_MAX for DragonFly<commit_after>// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! C definitions used by libnative that don't belong in liblibc

#![allow(dead_code)]
#![allow(non_camel_case_types)]

pub use self::select::fd_set;
pub use self::signal::{sigaction, siginfo, sigset_t};
pub use self::signal::{SA_ONSTACK, SA_RESTART, SA_RESETHAND, SA_NOCLDSTOP};
pub use self::signal::{SA_NODEFER, SA_NOCLDWAIT, SA_SIGINFO, SIGCHLD};

use libc;

#[cfg(any(target_os = "macos",
          target_os = "ios",
          target_os = "freebsd",
          target_os = "dragonfly",
          target_os = "openbsd"))]
pub const FIONBIO: libc::c_ulong = 0x8004667e;
#[cfg(any(all(target_os = "linux",
              any(target_arch = "x86",
                  target_arch = "x86_64",
                  target_arch = "arm",
                  target_arch = "aarch64")),
          target_os = "android"))]
pub const FIONBIO: libc::c_ulong = 0x5421;
#[cfg(all(target_os = "linux",
          any(target_arch = "mips",
              target_arch = "mipsel",
              target_arch = "powerpc")))]
pub const FIONBIO: libc::c_ulong = 0x667e;

#[cfg(any(target_os = "macos",
          target_os = "ios",
          target_os = "freebsd",
          target_os = "dragonfly",
          target_os = "openbsd"))]
pub const FIOCLEX: libc::c_ulong = 0x20006601;
#[cfg(any(all(target_os = "linux",
              any(target_arch = "x86",
                  target_arch = "x86_64",
                  target_arch = "arm",
                  target_arch = "aarch64")),
          target_os = "android"))]
pub const FIOCLEX: libc::c_ulong = 0x5451;
#[cfg(all(target_os = "linux",
          any(target_arch = "mips",
              target_arch = "mipsel",
              target_arch = "powerpc")))]
pub const FIOCLEX: libc::c_ulong = 0x6601;

#[cfg(any(target_os = "macos",
          target_os = "ios",
          target_os = "freebsd",
          target_os = "dragonfly",
          target_os = "openbsd"))]
pub const MSG_DONTWAIT: libc::c_int = 0x80;
#[cfg(any(target_os = "linux", target_os = "android"))]
pub const MSG_DONTWAIT: libc::c_int = 0x40;

pub const WNOHANG: libc::c_int = 1;

#[cfg(target_os = "linux")]
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 70;
#[cfg(any(target_os = "macos",
          target_os = "freebsd",
          target_os = "dragonfly"))]
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 71;
#[cfg(target_os = "openbsd")]
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 101;
#[cfg(target_os = "android")]
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 0x0048;

#[repr(C)]
#[cfg(target_os = "linux")]
pub struct passwd {
    pub pw_name: *mut libc::c_char,
    pub pw_passwd: *mut libc::c_char,
    pub pw_uid: libc::uid_t,
    pub pw_gid: libc::gid_t,
    pub pw_gecos: *mut libc::c_char,
    pub pw_dir: *mut libc::c_char,
    pub pw_shell: *mut libc::c_char,
}

#[repr(C)]
#[cfg(any(target_os = "macos",
          target_os = "freebsd",
          target_os = "dragonfly",
          target_os = "openbsd"))]
pub struct passwd {
    pub pw_name: *mut libc::c_char,
    pub pw_passwd: *mut libc::c_char,
    pub pw_uid: libc::uid_t,
    pub pw_gid: libc::gid_t,
    pub pw_change: libc::time_t,
    pub pw_class: *mut libc::c_char,
    pub pw_gecos: *mut libc::c_char,
    pub pw_dir: *mut libc::c_char,
    pub pw_shell: *mut libc::c_char,
    pub pw_expire: libc::time_t,
}

#[repr(C)]
#[cfg(target_os = "android")]
pub struct passwd {
    pub pw_name: *mut libc::c_char,
    pub pw_passwd: *mut libc::c_char,
    pub pw_uid: libc::uid_t,
    pub pw_gid: libc::gid_t,
    pub pw_dir: *mut libc::c_char,
    pub pw_shell: *mut libc::c_char,
}

extern {
    pub fn gettimeofday(timeval: *mut libc::timeval,
                        tzp: *mut libc::c_void) -> libc::c_int;
    pub fn select(nfds: libc::c_int,
                  readfds: *mut fd_set,
                  writefds: *mut fd_set,
                  errorfds: *mut fd_set,
                  timeout: *mut libc::timeval) -> libc::c_int;
    pub fn getsockopt(sockfd: libc::c_int,
                      level: libc::c_int,
                      optname: libc::c_int,
                      optval: *mut libc::c_void,
                      optlen: *mut libc::socklen_t) -> libc::c_int;
    pub fn ioctl(fd: libc::c_int, req: libc::c_ulong, ...) -> libc::c_int;

    pub fn waitpid(pid: libc::pid_t, status: *mut libc::c_int,
                   options: libc::c_int) -> libc::pid_t;

    pub fn sigaction(signum: libc::c_int,
                     act: *const sigaction,
                     oldact: *mut sigaction) -> libc::c_int;

    pub fn sigaddset(set: *mut sigset_t, signum: libc::c_int) -> libc::c_int;
    pub fn sigdelset(set: *mut sigset_t, signum: libc::c_int) -> libc::c_int;
    pub fn sigemptyset(set: *mut sigset_t) -> libc::c_int;

    #[cfg(not(target_os = "ios"))]
    pub fn getpwuid_r(uid: libc::uid_t,
                      pwd: *mut passwd,
                      buf: *mut libc::c_char,
                      buflen: libc::size_t,
                      result: *mut *mut passwd) -> libc::c_int;
}

#[cfg(any(target_os = "macos", target_os = "ios"))]
mod select {
    pub const FD_SETSIZE: uint = 1024;

    #[repr(C)]
    pub struct fd_set {
        fds_bits: [i32; (FD_SETSIZE / 32)]
    }

    pub fn fd_set(set: &mut fd_set, fd: i32) {
        set.fds_bits[(fd / 32) as uint] |= 1 << ((fd % 32) as uint);
    }
}

#[cfg(any(target_os = "android",
          target_os = "freebsd",
          target_os = "dragonfly",
          target_os = "openbsd",
          target_os = "linux"))]
mod select {
    use uint;
    use libc;

    pub const FD_SETSIZE: uint = 1024;

    #[repr(C)]
    pub struct fd_set {
        // FIXME: shouldn't this be a c_ulong?
        fds_bits: [libc::uintptr_t; (FD_SETSIZE / uint::BITS)]
    }

    pub fn fd_set(set: &mut fd_set, fd: i32) {
        let fd = fd as uint;
        set.fds_bits[fd / uint::BITS] |= 1 << (fd % uint::BITS);
    }
}

#[cfg(any(all(target_os = "linux",
              any(target_arch = "x86",
                  target_arch = "x86_64",
                  target_arch = "arm",
                  target_arch = "aarch64")),
          target_os = "android"))]
mod signal {
    use libc;

    pub const SA_NOCLDSTOP: libc::c_ulong = 0x00000001;
    pub const SA_NOCLDWAIT: libc::c_ulong = 0x00000002;
    pub const SA_NODEFER: libc::c_ulong = 0x40000000;
    pub const SA_ONSTACK: libc::c_ulong = 0x08000000;
    pub const SA_RESETHAND: libc::c_ulong = 0x80000000;
    pub const SA_RESTART: libc::c_ulong = 0x10000000;
    pub const SA_SIGINFO: libc::c_ulong = 0x00000004;
    pub const SIGCHLD: libc::c_int = 17;

    // This definition is not as accurate as it could be, {pid, uid, status} is
    // actually a giant union. Currently we're only interested in these fields,
    // however.
    #[repr(C)]
    pub struct siginfo {
        si_signo: libc::c_int,
        si_errno: libc::c_int,
        si_code: libc::c_int,
        pub pid: libc::pid_t,
        pub uid: libc::uid_t,
        pub status: libc::c_int,
    }

    #[repr(C)]
    pub struct sigaction {
        pub sa_handler: extern fn(libc::c_int),
        pub sa_mask: sigset_t,
        pub sa_flags: libc::c_ulong,
        sa_restorer: *mut libc::c_void,
    }

    unsafe impl ::marker::Send for sigaction { }
    unsafe impl ::marker::Sync for sigaction { }

    #[repr(C)]
    #[cfg(target_pointer_width = "32")]
    pub struct sigset_t {
        __val: [libc::c_ulong; 32],
    }

    #[repr(C)]
    #[cfg(target_pointer_width = "64")]
    pub struct sigset_t {
        __val: [libc::c_ulong; 16],
    }
}

#[cfg(all(target_os = "linux",
          any(target_arch = "mips",
              target_arch = "mipsel",
              target_arch = "powerpc")))]
mod signal {
    use libc;

    pub const SA_NOCLDSTOP: libc::c_ulong = 0x00000001;
    pub const SA_NOCLDWAIT: libc::c_ulong = 0x00010000;
    pub const SA_NODEFER: libc::c_ulong = 0x40000000;
    pub const SA_ONSTACK: libc::c_ulong = 0x08000000;
    pub const SA_RESETHAND: libc::c_ulong = 0x80000000;
    pub const SA_RESTART: libc::c_ulong = 0x10000000;
    pub const SA_SIGINFO: libc::c_ulong = 0x00000008;
    pub const SIGCHLD: libc::c_int = 18;

    // This definition is not as accurate as it could be, {pid, uid, status} is
    // actually a giant union. Currently we're only interested in these fields,
    // however.
    #[repr(C)]
    pub struct siginfo {
        si_signo: libc::c_int,
        si_code: libc::c_int,
        si_errno: libc::c_int,
        pub pid: libc::pid_t,
        pub uid: libc::uid_t,
        pub status: libc::c_int,
    }

    #[repr(C)]
    pub struct sigaction {
        pub sa_flags: libc::c_uint,
        pub sa_handler: extern fn(libc::c_int),
        pub sa_mask: sigset_t,
        sa_restorer: *mut libc::c_void,
        sa_resv: [libc::c_int; 1],
    }

    unsafe impl ::marker::Send for sigaction { }
    unsafe impl ::marker::Sync for sigaction { }

    #[repr(C)]
    pub struct sigset_t {
        __val: [libc::c_ulong; 32],
    }
}

#[cfg(any(target_os = "macos",
          target_os = "ios",
          target_os = "freebsd",
          target_os = "dragonfly",
          target_os = "openbsd"))]
mod signal {
    use libc;

    pub const SA_ONSTACK: libc::c_int = 0x0001;
    pub const SA_RESTART: libc::c_int = 0x0002;
    pub const SA_RESETHAND: libc::c_int = 0x0004;
    pub const SA_NOCLDSTOP: libc::c_int = 0x0008;
    pub const SA_NODEFER: libc::c_int = 0x0010;
    pub const SA_NOCLDWAIT: libc::c_int = 0x0020;
    pub const SA_SIGINFO: libc::c_int = 0x0040;
    pub const SIGCHLD: libc::c_int = 20;

    #[cfg(any(target_os = "macos",
              target_os = "ios",
              target_os = "openbsd"))]
    pub type sigset_t = u32;
    #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
    #[repr(C)]
    pub struct sigset_t {
        bits: [u32; 4],
    }

    // This structure has more fields, but we're not all that interested in
    // them.
    #[repr(C)]
    pub struct siginfo {
        pub si_signo: libc::c_int,
        pub si_errno: libc::c_int,
        pub si_code: libc::c_int,
        pub pid: libc::pid_t,
        pub uid: libc::uid_t,
        pub status: libc::c_int,
    }

    #[repr(C)]
    pub struct sigaction {
        pub sa_handler: extern fn(libc::c_int),
        pub sa_flags: libc::c_int,
        pub sa_mask: sigset_t,
    }
}
<|endoftext|>


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

/*!
 * This module contains a simple utility routine
 * used by both `typeck` and `const_eval`.
 * Almost certainly this could (and should) be refactored out of existence.
 */

use middle::def;
use middle::ty::{self, Ty};

use syntax::codemap::Span;
use rustc_front::hir as ast;

pub fn prohibit_type_params(tcx: &ty::ctxt, segments: &[ast::PathSegment]) {
    for segment in segments {
        for typ in segment.parameters.types() {
            span_err!(tcx.sess, typ.span, E0109,
                      "type parameters are not allowed on this type");
            break;
        }
        for lifetime in segment.parameters.lifetimes() {
            span_err!(tcx.sess, lifetime.span, E0110,
                      "lifetime parameters are not allowed on this type");
            break;
        }
        for binding in segment.parameters.bindings() {
            prohibit_projection(tcx, binding.span);
            break;
        }
    }
}

pub fn prohibit_projection(tcx: &ty::ctxt, span: Span)
{
    span_err!(tcx.sess, span, E0229,
              "associated type bindings are not allowed here");
}

pub fn prim_ty_to_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
                           segments: &[ast::PathSegment],
                           nty: ast::PrimTy)
                           -> Ty<'tcx> {
    prohibit_type_params(tcx, segments);
    match nty {
        ast::TyBool => tcx.types.bool,
        ast::TyChar => tcx.types.char,
        ast::TyInt(it) => tcx.mk_mach_int(it),
        ast::TyUint(uit) => tcx.mk_mach_uint(uit),
        ast::TyFloat(ft) => tcx.mk_mach_float(ft),
        ast::TyStr => tcx.mk_str()
    }
}

pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
                               -> Option<Ty<'tcx>> {
    if let ast::TyPath(None, ref path) = ast_ty.node {
        let def = match tcx.def_map.borrow().get(&ast_ty.id) {
            None => {
                tcx.sess.span_bug(ast_ty.span,
                                  &format!("unbound path {:?}", path))
            }
            Some(d) => d.full_def()
        };
        if let def::DefPrimTy(nty) = def {
            Some(prim_ty_to_ty(tcx, &path.segments, nty))
        } else {
            None
        }
    } else {
        None
    }
}
<commit_msg>Auto merge of #29074 - Manishearth:astconv-doc, r=eddyb<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!
 * This module contains a simple utility routine
 * used by both `typeck` and `const_eval`.
 * Almost certainly this could (and should) be refactored out of existence.
 */

use middle::def;
use middle::ty::{self, Ty};

use syntax::codemap::Span;
use rustc_front::hir as ast;

pub fn prohibit_type_params(tcx: &ty::ctxt, segments: &[ast::PathSegment]) {
    for segment in segments {
        for typ in segment.parameters.types() {
            span_err!(tcx.sess, typ.span, E0109,
                      "type parameters are not allowed on this type");
            break;
        }
        for lifetime in segment.parameters.lifetimes() {
            span_err!(tcx.sess, lifetime.span, E0110,
                      "lifetime parameters are not allowed on this type");
            break;
        }
        for binding in segment.parameters.bindings() {
            prohibit_projection(tcx, binding.span);
            break;
        }
    }
}

pub fn prohibit_projection(tcx: &ty::ctxt, span: Span)
{
    span_err!(tcx.sess, span, E0229,
              "associated type bindings are not allowed here");
}

pub fn prim_ty_to_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
                           segments: &[ast::PathSegment],
                           nty: ast::PrimTy)
                           -> Ty<'tcx> {
    prohibit_type_params(tcx, segments);
    match nty {
        ast::TyBool => tcx.types.bool,
        ast::TyChar => tcx.types.char,
        ast::TyInt(it) => tcx.mk_mach_int(it),
        ast::TyUint(uit) => tcx.mk_mach_uint(uit),
        ast::TyFloat(ft) => tcx.mk_mach_float(ft),
        ast::TyStr => tcx.mk_str()
    }
}

/// If a type in the AST is a primitive type, return the ty::Ty corresponding
/// to it.
pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
                               -> Option<Ty<'tcx>> {
    if let ast::TyPath(None, ref path) = ast_ty.node {
        let def = match tcx.def_map.borrow().get(&ast_ty.id) {
            None => {
                tcx.sess.span_bug(ast_ty.span,
                                  &format!("unbound path {:?}", path))
            }
            Some(d) => d.full_def()
        };
        if let def::DefPrimTy(nty) = def {
            Some(prim_ty_to_ty(tcx, &path.segments, nty))
        } else {
            None
        }
    } else {
        None
    }
}
<|endoftext|>


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

#![allow(private_no_mangle_fns)]

use prelude::v1::*;

use any::Any;
use sys_common::libunwind as uw;

struct Exception {
    uwe: uw::_Unwind_Exception,
    cause: Option<Box<Any + Send + 'static>>,
}

pub unsafe fn panic(data: Box<Any + Send + 'static>) -> ! {
    let exception: Box<_> = box Exception {
        uwe: uw::_Unwind_Exception {
            exception_class: rust_exception_class(),
            exception_cleanup: exception_cleanup,
            private: [0; uw::unwinder_private_data_size],
        },
        cause: Some(data),
    };
    let exception_param = Box::into_raw(exception) as *mut uw::_Unwind_Exception;
    let error = uw::_Unwind_RaiseException(exception_param);
    rtabort!("Could not unwind stack, error = {}", error as isize);

    extern fn exception_cleanup(_unwind_code: uw::_Unwind_Reason_Code,
                                exception: *mut uw::_Unwind_Exception) {
        unsafe {
            let _: Box<Exception> = Box::from_raw(exception as *mut Exception);
        }
    }
}

pub fn payload() -> *mut u8 {
    0 as *mut u8
}

pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send + 'static> {
    let my_ep = ptr as *mut Exception;
    let cause = (*my_ep).cause.take();
    uw::_Unwind_DeleteException(ptr as *mut _);
    cause.unwrap()
}

// Rust's exception class identifier.  This is used by personality routines to
// determine whether the exception was thrown by their own runtime.
fn rust_exception_class() -> uw::_Unwind_Exception_Class {
    // M O Z \0  R U S T -- vendor, language
    0x4d4f5a_00_52555354
}

// We could implement our personality routine in pure Rust, however exception
// info decoding is tedious.  More importantly, personality routines have to
// handle various platform quirks, which are not fun to maintain.  For this
// reason, we attempt to reuse personality routine of the C language:
// __gcc_personality_v0.
//
// Since C does not support exception catching, __gcc_personality_v0 simply
// always returns _URC_CONTINUE_UNWIND in search phase, and always returns
// _URC_INSTALL_CONTEXT (i.e. "invoke cleanup code") in cleanup phase.
//
// This is pretty close to Rust's exception handling approach, except that Rust
// does have a single "catch-all" handler at the bottom of each thread's stack.
// So we have two versions of the personality routine:
// - rust_eh_personality, used by all cleanup landing pads, which never catches,
//   so the behavior of __gcc_personality_v0 is perfectly adequate there, and
// - rust_eh_personality_catch, used only by rust_try(), which always catches.
//
// See also: rustc_trans::trans::intrinsic::trans_gnu_try

#[cfg(all(not(target_arch = "arm"),
          not(all(windows, target_arch = "x86_64")),
          not(test)))]
pub mod eabi {
    use sys_common::libunwind as uw;
    use libc::c_int;

    extern {
        fn __gcc_personality_v0(version: c_int,
                                actions: uw::_Unwind_Action,
                                exception_class: uw::_Unwind_Exception_Class,
                                ue_header: *mut uw::_Unwind_Exception,
                                context: *mut uw::_Unwind_Context)
            -> uw::_Unwind_Reason_Code;
    }

    #[lang = "eh_personality"]
    #[no_mangle]
    extern fn rust_eh_personality(
        version: c_int,
        actions: uw::_Unwind_Action,
        exception_class: uw::_Unwind_Exception_Class,
        ue_header: *mut uw::_Unwind_Exception,
        context: *mut uw::_Unwind_Context
    ) -> uw::_Unwind_Reason_Code
    {
        unsafe {
            __gcc_personality_v0(version, actions, exception_class, ue_header,
                                 context)
        }
    }

    #[lang = "eh_personality_catch"]
    #[no_mangle]
    pub extern fn rust_eh_personality_catch(
        version: c_int,
        actions: uw::_Unwind_Action,
        exception_class: uw::_Unwind_Exception_Class,
        ue_header: *mut uw::_Unwind_Exception,
        context: *mut uw::_Unwind_Context
    ) -> uw::_Unwind_Reason_Code
    {

        if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
            uw::_URC_HANDLER_FOUND // catch!
        }
        else { // cleanup phase
            unsafe {
                __gcc_personality_v0(version, actions, exception_class, ue_header,
                                     context)
            }
        }
    }
}

// iOS on armv7 is using SjLj exceptions and therefore requires to use
// a specialized personality routine: __gcc_personality_sj0

#[cfg(all(target_os = "ios", target_arch = "arm", not(test)))]
pub mod eabi {
    use sys_common::libunwind as uw;
    use libc::c_int;

    extern {
        fn __gcc_personality_sj0(version: c_int,
                                actions: uw::_Unwind_Action,
                                exception_class: uw::_Unwind_Exception_Class,
                                ue_header: *mut uw::_Unwind_Exception,
                                context: *mut uw::_Unwind_Context)
            -> uw::_Unwind_Reason_Code;
    }

    #[lang = "eh_personality"]
    #[no_mangle]
    pub extern fn rust_eh_personality(
        version: c_int,
        actions: uw::_Unwind_Action,
        exception_class: uw::_Unwind_Exception_Class,
        ue_header: *mut uw::_Unwind_Exception,
        context: *mut uw::_Unwind_Context
    ) -> uw::_Unwind_Reason_Code
    {
        unsafe {
            __gcc_personality_sj0(version, actions, exception_class, ue_header,
                                  context)
        }
    }

    #[lang = "eh_personality_catch"]
    #[no_mangle]
    pub extern fn rust_eh_personality_catch(
        version: c_int,
        actions: uw::_Unwind_Action,
        exception_class: uw::_Unwind_Exception_Class,
        ue_header: *mut uw::_Unwind_Exception,
        context: *mut uw::_Unwind_Context
    ) -> uw::_Unwind_Reason_Code
    {
        if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
            uw::_URC_HANDLER_FOUND // catch!
        }
        else { // cleanup phase
            unsafe {
                __gcc_personality_sj0(version, actions, exception_class, ue_header,
                                      context)
            }
        }
    }
}

// ARM EHABI uses a slightly different personality routine signature,
// but otherwise works the same.
#[cfg(all(target_arch = "arm", not(target_os = "ios"), not(test)))]
pub mod eabi {
    use sys_common::libunwind as uw;
    use libc::c_int;

    extern {
        fn __gcc_personality_v0(state: uw::_Unwind_State,
                                ue_header: *mut uw::_Unwind_Exception,
                                context: *mut uw::_Unwind_Context)
            -> uw::_Unwind_Reason_Code;
    }

    #[lang = "eh_personality"]
    #[no_mangle]
    extern fn rust_eh_personality(
        state: uw::_Unwind_State,
        ue_header: *mut uw::_Unwind_Exception,
        context: *mut uw::_Unwind_Context
    ) -> uw::_Unwind_Reason_Code
    {
        unsafe {
            __gcc_personality_v0(state, ue_header, context)
        }
    }

    #[lang = "eh_personality_catch"]
    #[no_mangle]
    pub extern fn rust_eh_personality_catch(
        state: uw::_Unwind_State,
        ue_header: *mut uw::_Unwind_Exception,
        context: *mut uw::_Unwind_Context
    ) -> uw::_Unwind_Reason_Code
    {
        if (state as c_int & uw::_US_ACTION_MASK as c_int)
                           == uw::_US_VIRTUAL_UNWIND_FRAME as c_int { // search phase
            uw::_URC_HANDLER_FOUND // catch!
        }
        else { // cleanup phase
            unsafe {
                __gcc_personality_v0(state, ue_header, context)
            }
        }
    }
}

// See docs in the `unwind` module.
#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu", not(test)))]
#[lang = "eh_unwind_resume"]
#[unwind]
unsafe extern fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! {
    uw::_Unwind_Resume(panic_ctx as *mut uw::_Unwind_Exception);
}

#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))]
pub mod eh_frame_registry {
    // The implementation of stack unwinding is (for now) deferred to libgcc_eh, however Rust
    // crates use these Rust-specific entry points to avoid potential clashes with GCC runtime.
    // See also: rtbegin.rs, `unwind` module.

    #[link(name = "gcc_eh")]
    #[cfg(not(cargobuild))]
    extern {}

    extern {
        fn __register_frame_info(eh_frame_begin: *const u8, object: *mut u8);
        fn __deregister_frame_info(eh_frame_begin: *const u8, object: *mut u8);
    }
    #[cfg(not(test))]
    #[no_mangle]
    #[unstable(feature = "libstd_sys_internals", issue = "0")]
    pub unsafe extern fn rust_eh_register_frames(eh_frame_begin: *const u8,
                                                 object: *mut u8) {
        __register_frame_info(eh_frame_begin, object);
    }
    #[cfg(not(test))]
    #[no_mangle]
    #[unstable(feature = "libstd_sys_internals", issue = "0")]
    pub  unsafe extern fn rust_eh_unregister_frames(eh_frame_begin: *const u8,
                                                   object: *mut u8) {
        __deregister_frame_info(eh_frame_begin, object);
    }
}
<commit_msg>Rollup merge of #32737 - timonvo:arm-ehabi-backtraces, r=alexcrichton<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(private_no_mangle_fns)]

use prelude::v1::*;

use any::Any;
use sys_common::libunwind as uw;

struct Exception {
    uwe: uw::_Unwind_Exception,
    cause: Option<Box<Any + Send + 'static>>,
}

pub unsafe fn panic(data: Box<Any + Send + 'static>) -> ! {
    let exception: Box<_> = box Exception {
        uwe: uw::_Unwind_Exception {
            exception_class: rust_exception_class(),
            exception_cleanup: exception_cleanup,
            private: [0; uw::unwinder_private_data_size],
        },
        cause: Some(data),
    };
    let exception_param = Box::into_raw(exception) as *mut uw::_Unwind_Exception;
    let error = uw::_Unwind_RaiseException(exception_param);
    rtabort!("Could not unwind stack, error = {}", error as isize);

    extern fn exception_cleanup(_unwind_code: uw::_Unwind_Reason_Code,
                                exception: *mut uw::_Unwind_Exception) {
        unsafe {
            let _: Box<Exception> = Box::from_raw(exception as *mut Exception);
        }
    }
}

pub fn payload() -> *mut u8 {
    0 as *mut u8
}

pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send + 'static> {
    let my_ep = ptr as *mut Exception;
    let cause = (*my_ep).cause.take();
    uw::_Unwind_DeleteException(ptr as *mut _);
    cause.unwrap()
}

// Rust's exception class identifier.  This is used by personality routines to
// determine whether the exception was thrown by their own runtime.
fn rust_exception_class() -> uw::_Unwind_Exception_Class {
    // M O Z \0  R U S T -- vendor, language
    0x4d4f5a_00_52555354
}

// We could implement our personality routine in pure Rust, however exception
// info decoding is tedious.  More importantly, personality routines have to
// handle various platform quirks, which are not fun to maintain.  For this
// reason, we attempt to reuse personality routine of the C language:
// __gcc_personality_v0.
//
// Since C does not support exception catching, __gcc_personality_v0 simply
// always returns _URC_CONTINUE_UNWIND in search phase, and always returns
// _URC_INSTALL_CONTEXT (i.e. "invoke cleanup code") in cleanup phase.
//
// This is pretty close to Rust's exception handling approach, except that Rust
// does have a single "catch-all" handler at the bottom of each thread's stack.
// So we have two versions of the personality routine:
// - rust_eh_personality, used by all cleanup landing pads, which never catches,
//   so the behavior of __gcc_personality_v0 is perfectly adequate there, and
// - rust_eh_personality_catch, used only by rust_try(), which always catches.
//
// See also: rustc_trans::trans::intrinsic::trans_gnu_try

#[cfg(all(not(target_arch = "arm"),
          not(all(windows, target_arch = "x86_64")),
          not(test)))]
pub mod eabi {
    use sys_common::libunwind as uw;
    use libc::c_int;

    extern {
        fn __gcc_personality_v0(version: c_int,
                                actions: uw::_Unwind_Action,
                                exception_class: uw::_Unwind_Exception_Class,
                                ue_header: *mut uw::_Unwind_Exception,
                                context: *mut uw::_Unwind_Context)
            -> uw::_Unwind_Reason_Code;
    }

    #[lang = "eh_personality"]
    #[no_mangle]
    extern fn rust_eh_personality(
        version: c_int,
        actions: uw::_Unwind_Action,
        exception_class: uw::_Unwind_Exception_Class,
        ue_header: *mut uw::_Unwind_Exception,
        context: *mut uw::_Unwind_Context
    ) -> uw::_Unwind_Reason_Code
    {
        unsafe {
            __gcc_personality_v0(version, actions, exception_class, ue_header,
                                 context)
        }
    }

    #[lang = "eh_personality_catch"]
    #[no_mangle]
    pub extern fn rust_eh_personality_catch(
        version: c_int,
        actions: uw::_Unwind_Action,
        exception_class: uw::_Unwind_Exception_Class,
        ue_header: *mut uw::_Unwind_Exception,
        context: *mut uw::_Unwind_Context
    ) -> uw::_Unwind_Reason_Code
    {

        if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
            uw::_URC_HANDLER_FOUND // catch!
        }
        else { // cleanup phase
            unsafe {
                __gcc_personality_v0(version, actions, exception_class, ue_header,
                                     context)
            }
        }
    }
}

// iOS on armv7 is using SjLj exceptions and therefore requires to use
// a specialized personality routine: __gcc_personality_sj0

#[cfg(all(target_os = "ios", target_arch = "arm", not(test)))]
pub mod eabi {
    use sys_common::libunwind as uw;
    use libc::c_int;

    extern {
        fn __gcc_personality_sj0(version: c_int,
                                actions: uw::_Unwind_Action,
                                exception_class: uw::_Unwind_Exception_Class,
                                ue_header: *mut uw::_Unwind_Exception,
                                context: *mut uw::_Unwind_Context)
            -> uw::_Unwind_Reason_Code;
    }

    #[lang = "eh_personality"]
    #[no_mangle]
    pub extern fn rust_eh_personality(
        version: c_int,
        actions: uw::_Unwind_Action,
        exception_class: uw::_Unwind_Exception_Class,
        ue_header: *mut uw::_Unwind_Exception,
        context: *mut uw::_Unwind_Context
    ) -> uw::_Unwind_Reason_Code
    {
        unsafe {
            __gcc_personality_sj0(version, actions, exception_class, ue_header,
                                  context)
        }
    }

    #[lang = "eh_personality_catch"]
    #[no_mangle]
    pub extern fn rust_eh_personality_catch(
        version: c_int,
        actions: uw::_Unwind_Action,
        exception_class: uw::_Unwind_Exception_Class,
        ue_header: *mut uw::_Unwind_Exception,
        context: *mut uw::_Unwind_Context
    ) -> uw::_Unwind_Reason_Code
    {
        if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
            uw::_URC_HANDLER_FOUND // catch!
        }
        else { // cleanup phase
            unsafe {
                __gcc_personality_sj0(version, actions, exception_class, ue_header,
                                      context)
            }
        }
    }
}

// ARM EHABI uses a slightly different personality routine signature,
// but otherwise works the same.
#[cfg(all(target_arch = "arm", not(target_os = "ios"), not(test)))]
pub mod eabi {
    use sys_common::libunwind as uw;
    use libc::c_int;

    extern {
        fn __gcc_personality_v0(state: uw::_Unwind_State,
                                ue_header: *mut uw::_Unwind_Exception,
                                context: *mut uw::_Unwind_Context)
            -> uw::_Unwind_Reason_Code;
    }

    #[lang = "eh_personality"]
    #[no_mangle]
    extern fn rust_eh_personality(
        state: uw::_Unwind_State,
        ue_header: *mut uw::_Unwind_Exception,
        context: *mut uw::_Unwind_Context
    ) -> uw::_Unwind_Reason_Code
    {
        unsafe {
            __gcc_personality_v0(state, ue_header, context)
        }
    }

    #[lang = "eh_personality_catch"]
    #[no_mangle]
    pub extern fn rust_eh_personality_catch(
        state: uw::_Unwind_State,
        ue_header: *mut uw::_Unwind_Exception,
        context: *mut uw::_Unwind_Context
    ) -> uw::_Unwind_Reason_Code
    {
        // Backtraces on ARM will call the personality routine with
        // state == _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND. In those cases
        // we want to continue unwinding the stack, otherwise all our backtraces
        // would end at __rust_try.
        if (state as c_int & uw::_US_ACTION_MASK as c_int)
                           == uw::_US_VIRTUAL_UNWIND_FRAME as c_int
               && (state as c_int & uw::_US_FORCE_UNWIND as c_int) == 0 { // search phase
            uw::_URC_HANDLER_FOUND // catch!
        }
        else { // cleanup phase
            unsafe {
                __gcc_personality_v0(state, ue_header, context)
            }
        }
    }
}

// See docs in the `unwind` module.
#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu", not(test)))]
#[lang = "eh_unwind_resume"]
#[unwind]
unsafe extern fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! {
    uw::_Unwind_Resume(panic_ctx as *mut uw::_Unwind_Exception);
}

#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))]
pub mod eh_frame_registry {
    // The implementation of stack unwinding is (for now) deferred to libgcc_eh, however Rust
    // crates use these Rust-specific entry points to avoid potential clashes with GCC runtime.
    // See also: rtbegin.rs, `unwind` module.

    #[link(name = "gcc_eh")]
    #[cfg(not(cargobuild))]
    extern {}

    extern {
        fn __register_frame_info(eh_frame_begin: *const u8, object: *mut u8);
        fn __deregister_frame_info(eh_frame_begin: *const u8, object: *mut u8);
    }
    #[cfg(not(test))]
    #[no_mangle]
    #[unstable(feature = "libstd_sys_internals", issue = "0")]
    pub unsafe extern fn rust_eh_register_frames(eh_frame_begin: *const u8,
                                                 object: *mut u8) {
        __register_frame_info(eh_frame_begin, object);
    }
    #[cfg(not(test))]
    #[no_mangle]
    #[unstable(feature = "libstd_sys_internals", issue = "0")]
    pub  unsafe extern fn rust_eh_unregister_frames(eh_frame_begin: *const u8,
                                                   object: *mut u8) {
        __deregister_frame_info(eh_frame_begin, object);
    }
}
<|endoftext|>


<commit_before><commit_msg>adding expiration enum<commit_after>pub enum Expiration {
    Never,
    TenMinutes,
    OneHour,
    OneDay,
    OneWeek,
    TwoWeeks,
    OneMonth,
}<|endoftext|>


<commit_before><commit_msg>Implement display processing<commit_after><|endoftext|>


<commit_before><commit_msg>Refactor Glob Checking<commit_after><|endoftext|>