Remove libnative

With runtime removal complete, there's nothing left of libnative. This
commit removes it.

Fixes #18687

[breaking-change]
This commit is contained in:
Aaron Turon 2014-11-14 13:55:57 -08:00
parent ad022b1a1b
commit 3ee916e50b
10 changed files with 87 additions and 1683 deletions

View file

@ -49,7 +49,7 @@
# automatically generated for all stage/host/target combinations.
################################################################################
TARGET_CRATES := libc std green native flate arena term \
TARGET_CRATES := libc std green flate arena term \
serialize sync getopts collections test time rand \
log regex graphviz core rbml alloc rustrt \
unicode
@ -67,7 +67,6 @@ DEPS_std := core libc rand alloc collections rustrt sync unicode \
native:rust_builtin native:backtrace
DEPS_graphviz := std
DEPS_green := std native:context_switch
DEPS_native := std
DEPS_syntax := std term serialize log fmt_macros arena libc
DEPS_rustc_trans := rustc rustc_back rustc_llvm libc
DEPS_rustc := syntax flate arena serialize getopts rbml \
@ -95,9 +94,9 @@ DEPS_regex := std
DEPS_regex_macros = rustc syntax std regex
DEPS_fmt_macros = std
TOOL_DEPS_compiletest := test getopts native
TOOL_DEPS_rustdoc := rustdoc native
TOOL_DEPS_rustc := rustc_trans native
TOOL_DEPS_compiletest := test getopts
TOOL_DEPS_rustdoc := rustdoc
TOOL_DEPS_rustc := rustc_trans
TOOL_SOURCE_compiletest := $(S)src/compiletest/compiletest.rs
TOOL_SOURCE_rustdoc := $(S)src/driver/driver.rs
TOOL_SOURCE_rustc := $(S)src/driver/driver.rs

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![no_start]
#[cfg(rustdoc)]
extern crate "rustdoc" as this;

View file

@ -1,116 +0,0 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use libc::{c_char, c_int};
use libc;
use std::mem;
use std::ptr::{null, null_mut};
use std::rt::rtio;
use std::rt::rtio::IoError;
use super::net;
pub struct GetAddrInfoRequest;
impl GetAddrInfoRequest {
pub fn run(host: Option<&str>, servname: Option<&str>,
hint: Option<rtio::AddrinfoHint>)
-> Result<Vec<rtio::AddrinfoInfo>, IoError>
{
assert!(host.is_some() || servname.is_some());
let c_host = host.map(|x| x.to_c_str());
let c_host = c_host.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
let c_serv = servname.map(|x| x.to_c_str());
let c_serv = c_serv.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
let hint = hint.map(|hint| {
libc::addrinfo {
ai_flags: hint.flags as c_int,
ai_family: hint.family as c_int,
ai_socktype: 0,
ai_protocol: 0,
ai_addrlen: 0,
ai_canonname: null_mut(),
ai_addr: null_mut(),
ai_next: null_mut()
}
});
let hint_ptr = hint.as_ref().map_or(null(), |x| {
x as *const libc::addrinfo
});
let mut res = null_mut();
// Make the call
let s = unsafe {
getaddrinfo(c_host, c_serv, hint_ptr, &mut res)
};
// Error?
if s != 0 {
return Err(get_error(s));
}
// Collect all the results we found
let mut addrs = Vec::new();
let mut rp = res;
while rp.is_not_null() {
unsafe {
let addr = match net::sockaddr_to_addr(mem::transmute((*rp).ai_addr),
(*rp).ai_addrlen as uint) {
Ok(a) => a,
Err(e) => return Err(e)
};
addrs.push(rtio::AddrinfoInfo {
address: addr,
family: (*rp).ai_family as uint,
socktype: 0,
protocol: 0,
flags: (*rp).ai_flags as uint
});
rp = (*rp).ai_next as *mut libc::addrinfo;
}
}
unsafe { freeaddrinfo(res); }
Ok(addrs)
}
}
extern "system" {
fn getaddrinfo(node: *const c_char, service: *const c_char,
hints: *const libc::addrinfo,
res: *mut *mut libc::addrinfo) -> c_int;
fn freeaddrinfo(res: *mut libc::addrinfo);
#[cfg(not(windows))]
fn gai_strerror(errcode: c_int) -> *const c_char;
}
#[cfg(windows)]
fn get_error(_: c_int) -> IoError {
net::last_error()
}
#[cfg(not(windows))]
fn get_error(s: c_int) -> IoError {
use std::c_str::CString;
let err_str = unsafe {
CString::new(gai_strerror(s), false).as_str().unwrap().to_string()
};
IoError {
code: s as uint,
extra: 0,
detail: Some(err_str),
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,155 +0,0 @@
// Copyright 2013-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.
//! The native I/O and threading crate
//!
//! This crate contains an implementation of 1:1 scheduling for a "native"
//! runtime. In addition, all I/O provided by this crate is the thread blocking
//! version of I/O.
//!
//! # Starting with libnative
//!
//! ```rust
//! extern crate native;
//!
//! #[start]
//! fn start(argc: int, argv: *const *const u8) -> int {
//! native::start(argc, argv, main)
//! }
//!
//! fn main() {
//! // this code is running on the main OS thread
//! }
//! ```
//!
//! # Force spawning a native task
//!
//! ```rust
//! extern crate native;
//!
//! use std::task::TaskBuilder;
//! use native::NativeTaskBuilder;
//!
//! fn main() {
//! // We're not sure whether this main function is run in 1:1 or M:N mode.
//!
//! TaskBuilder::new().native().spawn(proc() {
//! // this code is guaranteed to be run on a native thread
//! });
//! }
//! ```
#![crate_name = "native"]
#![experimental]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/nightly/")]
#![deny(unused_results, unused_must_use)]
#![allow(non_camel_case_types)]
#![allow(unknown_features)]
#![feature(default_type_params, lang_items, slicing_syntax, globs)]
// NB this crate explicitly does *not* allow glob imports, please seriously
// consider whether they're needed before adding that feature here (the
// answer is that you don't need them)
#![feature(macro_rules, unsafe_destructor, default_type_params)]
extern crate alloc;
extern crate libc;
use std::os;
use std::rt;
use std::str;
pub use task::NativeTaskBuilder;
pub mod task;
#[cfg(any(windows, android))]
static OS_DEFAULT_STACK_ESTIMATE: uint = 1 << 20;
#[cfg(all(unix, not(android)))]
static OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);
#[lang = "start"]
#[cfg(not(test))]
pub fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
use std::mem;
start(argc, argv, proc() {
let main: extern "Rust" fn() = unsafe { mem::transmute(main) };
main();
})
}
/// Executes the given procedure after initializing the runtime with the given
/// argc/argv.
///
/// This procedure is guaranteed to run on the thread calling this function, but
/// the stack bounds for this rust task will *not* be set. Care must be taken
/// for this function to not overflow its stack.
///
/// This function will only return once *all* native threads in the system have
/// exited.
pub fn start(argc: int, argv: *const *const u8, main: proc()) -> int {
let something_around_the_top_of_the_stack = 1;
let addr = &something_around_the_top_of_the_stack as *const int;
let my_stack_top = addr as uint;
// FIXME #11359 we just assume that this thread has a stack of a
// certain size, and estimate that there's at most 20KB of stack
// frames above our current position.
let my_stack_bottom = my_stack_top + 20000 - OS_DEFAULT_STACK_ESTIMATE;
// When using libgreen, one of the first things that we do is to turn off
// the SIGPIPE signal (set it to ignore). By default, some platforms will
// send a *signal* when a EPIPE error would otherwise be delivered. This
// runtime doesn't install a SIGPIPE handler, causing it to kill the
// program, which isn't exactly what we want!
//
// Hence, we set SIGPIPE to ignore when the program starts up in order to
// prevent this problem.
#[cfg(windows)] fn ignore_sigpipe() {}
#[cfg(unix)] fn ignore_sigpipe() {
use libc;
use libc::funcs::posix01::signal::signal;
unsafe {
assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != -1);
}
}
ignore_sigpipe();
rt::init(argc, argv);
let mut exit_code = None;
let mut main = Some(main);
let mut task = task::new((my_stack_bottom, my_stack_top),
rt::thread::main_guard_page());
task.name = Some(str::Slice("<main>"));
drop(task.run(|| {
unsafe {
rt::stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
}
exit_code = Some(run(main.take().unwrap()));
}).destroy());
unsafe { rt::cleanup(); }
// If the exit code wasn't set, then the task block must have panicked.
return exit_code.unwrap_or(rt::DEFAULT_ERROR_CODE);
}
/// Executes a procedure on the current thread in a Rust task context.
///
/// This function has all of the same details as `start` except for a different
/// number of arguments.
pub fn run(main: proc()) -> int {
main();
os::get_exit_status()
}

View file

@ -1,130 +0,0 @@
// Copyright 2013-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.
//! Tasks implemented on top of OS threads
//!
//! This module contains the implementation of the 1:1 threading module required
//! by rust tasks. This implements the necessary API traits laid out by std::rt
//! in order to spawn new tasks and deschedule the current task.
use std::any::Any;
use std::mem;
use std::rt::bookkeeping;
use std::rt::local::Local;
use std::rt::mutex::NativeMutex;
use std::rt::stack;
use std::rt::task::{Task, BlockedTask, TaskOpts};
use std::rt::thread::Thread;
use std::rt;
#[cfg(test)]
mod tests {
use std::rt::local::Local;
use std::rt::task::{Task, TaskOpts};
use std::task;
use std::task::{TaskBuilder, Spawner};
use super::{Ops, NativeTaskBuilder, NativeSpawner};
#[test]
fn smoke() {
let (tx, rx) = channel();
spawn(proc() {
tx.send(());
});
rx.recv();
}
#[test]
fn smoke_panic() {
let (tx, rx) = channel::<()>();
spawn(proc() {
let _tx = tx;
panic!()
});
assert_eq!(rx.recv_opt(), Err(()));
}
#[test]
fn smoke_opts() {
let mut opts = TaskOpts::new();
opts.name = Some("test".into_maybe_owned());
opts.stack_size = Some(20 * 4096);
let (tx, rx) = channel();
opts.on_exit = Some(proc(r) tx.send(r));
NativeSpawner.spawn(opts, proc() {});
assert!(rx.recv().is_ok());
}
#[test]
fn smoke_opts_panic() {
let mut opts = TaskOpts::new();
let (tx, rx) = channel();
opts.on_exit = Some(proc(r) tx.send(r));
NativeSpawner.spawn(opts, proc() { panic!() });
assert!(rx.recv().is_err());
}
#[test]
fn yield_test() {
let (tx, rx) = channel();
spawn(proc() {
for _ in range(0u, 10) { task::deschedule(); }
tx.send(());
});
rx.recv();
}
#[test]
fn spawn_children() {
let (tx1, rx) = channel();
spawn(proc() {
let (tx2, rx) = channel();
spawn(proc() {
let (tx3, rx) = channel();
spawn(proc() {
tx3.send(());
});
rx.recv();
tx2.send(());
});
rx.recv();
tx1.send(());
});
rx.recv();
}
#[test]
fn spawn_inherits() {
let (tx, rx) = channel();
TaskBuilder::new().spawner(NativeSpawner).spawn(proc() {
spawn(proc() {
let mut task: Box<Task> = Local::take();
match task.maybe_take_runtime::<Ops>() {
Some(ops) => {
task.put_runtime(ops);
}
None => panic!(),
}
Local::put(task);
tx.send(());
});
});
rx.recv();
}
#[test]
fn test_native_builder() {
let res = TaskBuilder::new().native().try(proc() {
"Success!".to_string()
});
assert_eq!(res.ok().unwrap(), "Success!".to_string());
}
}

View file

@ -198,10 +198,6 @@ pub fn phase_2_configure_and_expand(sess: &Session,
*sess.features.borrow_mut() = features;
});
let any_exe = sess.crate_types.borrow().iter().any(|ty| {
*ty == config::CrateTypeExecutable
});
// strip before expansion to allow macros to depend on
// configuration variables e.g/ in
//
@ -215,8 +211,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
krate = time(time_passes, "crate injection", krate, |krate|
syntax::std_inject::maybe_inject_crates_ref(krate,
sess.opts.alt_std_name.clone(),
any_exe));
sess.opts.alt_std_name.clone()));
let mut addl_plugins = Some(addl_plugins);
let Plugins { macros, registrars }

View file

@ -248,9 +248,7 @@
#[path = "sys/common/mod.rs"] mod sys_common;
// FIXME #7809: This shouldn't be pub, and it should be reexported under 'unstable'
// but name resolution doesn't work without it being pub.
pub mod rt;
mod rt;
mod failure;
// A curious inner-module that's not exported that contains the binding

View file

@ -58,6 +58,7 @@
use failure;
use rustrt;
use startup;
// Reexport some of our utilities which are expected by other crates.
pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};
@ -86,6 +87,81 @@ pub fn init(argc: int, argv: *const *const u8) {
unsafe { unwind::register(failure::on_fail); }
}
#[cfg(any(windows, android))]
static OS_DEFAULT_STACK_ESTIMATE: uint = 1 << 20;
#[cfg(all(unix, not(android)))]
static OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);
#[cfg(not(test))]
#[lang = "start"]
fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
use std::mem;
start(argc, argv, proc() {
let main: extern "Rust" fn() = unsafe { mem::transmute(main) };
main();
})
}
/// Executes the given procedure after initializing the runtime with the given
/// argc/argv.
///
/// This procedure is guaranteed to run on the thread calling this function, but
/// the stack bounds for this rust task will *not* be set. Care must be taken
/// for this function to not overflow its stack.
///
/// This function will only return once *all* native threads in the system have
/// exited.
pub fn start(argc: int, argv: *const *const u8, main: proc()) -> int {
use prelude::*;
use rt;
use rustrt::task::Task;
use str;
let something_around_the_top_of_the_stack = 1;
let addr = &something_around_the_top_of_the_stack as *const int;
let my_stack_top = addr as uint;
// FIXME #11359 we just assume that this thread has a stack of a
// certain size, and estimate that there's at most 20KB of stack
// frames above our current position.
let my_stack_bottom = my_stack_top + 20000 - OS_DEFAULT_STACK_ESTIMATE;
// When using libgreen, one of the first things that we do is to turn off
// the SIGPIPE signal (set it to ignore). By default, some platforms will
// send a *signal* when a EPIPE error would otherwise be delivered. This
// runtime doesn't install a SIGPIPE handler, causing it to kill the
// program, which isn't exactly what we want!
//
// Hence, we set SIGPIPE to ignore when the program starts up in order to
// prevent this problem.
#[cfg(windows)] fn ignore_sigpipe() {}
#[cfg(unix)] fn ignore_sigpipe() {
use libc;
use libc::funcs::posix01::signal::signal;
unsafe {
assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != -1);
}
}
ignore_sigpipe();
init(argc, argv);
let mut exit_code = None;
let mut main = Some(main);
let mut task = task::new((my_stack_bottom, my_stack_top),
rt::thread::main_guard_page());
task.name = Some(str::Slice("<main>"));
drop(task.run(|| {
unsafe {
rt::stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
}
(main.take().unwrap())();
exit_code = Some(os::get_exit_status());
}).destroy());
unsafe { rt::cleanup(); }
// If the exit code wasn't set, then the task block must have panicked.
return exit_code.unwrap_or(rt::DEFAULT_ERROR_CODE);
}
/// One-time runtime cleanup.
///
/// This function is unsafe because it performs no checks to ensure that the

View file

@ -22,10 +22,10 @@
use std::mem;
pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>, any_exe: bool)
pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>)
-> ast::Crate {
if use_std(&krate) {
inject_crates_ref(krate, alt_std_name, any_exe)
inject_crates_ref(krate, alt_std_name)
} else {
krate
}
@ -43,17 +43,12 @@ fn use_std(krate: &ast::Crate) -> bool {
!attr::contains_name(krate.attrs.as_slice(), "no_std")
}
fn use_start(krate: &ast::Crate) -> bool {
!attr::contains_name(krate.attrs.as_slice(), "no_start")
}
fn no_prelude(attrs: &[ast::Attribute]) -> bool {
attr::contains_name(attrs, "no_implicit_prelude")
}
struct StandardLibraryInjector<'a> {
alt_std_name: Option<String>,
any_exe: bool,
}
impl<'a> fold::Folder for StandardLibraryInjector<'a> {
@ -80,23 +75,6 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
span: DUMMY_SP
});
if use_start(&krate) && self.any_exe {
let visible_rt_name = "rt";
let actual_rt_name = "native";
// Gensym the ident so it can't be named
let visible_rt_name = token::gensym_ident(visible_rt_name);
let actual_rt_name = token::intern_and_get_ident(actual_rt_name);
vis.push(ast::ViewItem {
node: ast::ViewItemExternCrate(visible_rt_name,
Some((actual_rt_name, ast::CookedStr)),
ast::DUMMY_NODE_ID),
attrs: Vec::new(),
vis: ast::Inherited,
span: DUMMY_SP
});
}
// `extern crate` must be precede `use` items
mem::swap(&mut vis, &mut krate.module.view_items);
krate.module.view_items.extend(vis.into_iter());
@ -118,12 +96,9 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
}
}
fn inject_crates_ref(krate: ast::Crate,
alt_std_name: Option<String>,
any_exe: bool) -> ast::Crate {
fn inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>) -> ast::Crate {
let mut fold = StandardLibraryInjector {
alt_std_name: alt_std_name,
any_exe: any_exe,
};
fold.fold_crate(krate)
}