auto merge of #13117 : alexcrichton/rust/no-crate-map, r=brson
This can be done now that logging has been moved out and libnative is the default (not libgreen)
This commit is contained in:
commit
de85948ac0
src
compiletest
doc
libgreen
librustc
librustuv
libstd
test
run-make
bootstrap-from-c-with-green
bootstrap-from-c-with-native
c-link-to-rust-staticlib
c-set-crate-map-manually
lto-smoke-c
run-pass
@ -43,7 +43,9 @@ pub mod common;
|
||||
pub mod errors;
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) }
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
green::start(argc, argv, rustuv::event_loop, main)
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let args = os::args();
|
||||
|
@ -223,27 +223,49 @@ Having a default decision made in the compiler is done out of necessity and
|
||||
convenience. The compiler's decision of runtime to link to is *not* an
|
||||
endorsement of one over the other. As always, this decision can be overridden.
|
||||
|
||||
For example, this program will be linked to "the default runtime"
|
||||
For example, this program will be linked to "the default runtime". The current
|
||||
default runtime is to use libnative.
|
||||
|
||||
~~~{.rust}
|
||||
fn main() {}
|
||||
~~~
|
||||
|
||||
Whereas this program explicitly opts into using a particular runtime
|
||||
### Force booting with libgreen
|
||||
|
||||
In this example, the `main` function will be booted with I/O support powered by
|
||||
libuv. This is done by linking to the `rustuv` crate and specifying the
|
||||
`rustuv::event_loop` function as the event loop factory.
|
||||
|
||||
To create a pool of green tasks which have no I/O support, you may shed the
|
||||
`rustuv` dependency and use the `green::basic::event_loop` function instead of
|
||||
`rustuv::event_loop`. All tasks will have no I/O support, but they will still be
|
||||
able to deschedule/reschedule (use channels, locks, etc).
|
||||
|
||||
~~~{.rust}
|
||||
extern crate green;
|
||||
extern crate rustuv;
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
green::start(argc, argv, main)
|
||||
green::start(argc, argv, rustuv::event_loop, main)
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
~~~
|
||||
|
||||
Both libgreen/libnative provide a top-level `start` function which is used to
|
||||
boot an initial Rust task in that specified runtime.
|
||||
### Force booting with libnative
|
||||
|
||||
This program's `main` function will always be booted with libnative, running
|
||||
inside of an OS thread.
|
||||
|
||||
~~~{.rust}
|
||||
extern crate native;
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: **u8) -> int { native::start(argc, argv, main) }
|
||||
|
||||
fn main() {}
|
||||
~~~
|
||||
|
||||
# Finding the runtime
|
||||
|
||||
|
@ -237,7 +237,7 @@ mod test {
|
||||
fn pool() -> SchedPool {
|
||||
SchedPool::new(PoolConfig {
|
||||
threads: 1,
|
||||
event_loop_factory: Some(basic::event_loop),
|
||||
event_loop_factory: basic::event_loop,
|
||||
})
|
||||
}
|
||||
|
||||
@ -267,7 +267,7 @@ mod test {
|
||||
fn multi_thread() {
|
||||
let mut pool = SchedPool::new(PoolConfig {
|
||||
threads: 2,
|
||||
event_loop_factory: Some(basic::event_loop),
|
||||
event_loop_factory: basic::event_loop,
|
||||
});
|
||||
|
||||
for _ in range(0, 20) {
|
||||
|
@ -116,13 +116,34 @@
|
||||
//! extern crate green;
|
||||
//!
|
||||
//! #[start]
|
||||
//! fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) }
|
||||
//! fn start(argc: int, argv: **u8) -> int {
|
||||
//! green::start(argc, argv, green::basic::event_loop, main)
|
||||
//! }
|
||||
//!
|
||||
//! fn main() {
|
||||
//! // this code is running in a pool of schedulers
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! > **Note**: This `main` funciton in this example does *not* have I/O
|
||||
//! > support. The basic event loop does not provide any support
|
||||
//!
|
||||
//! # Starting with I/O support in libgreen
|
||||
//!
|
||||
//! ```rust
|
||||
//! extern crate green;
|
||||
//! extern crate rustuv;
|
||||
//!
|
||||
//! #[start]
|
||||
//! fn start(argc: int, argv: **u8) -> int {
|
||||
//! green::start(argc, argv, rustuv::event_loop, main)
|
||||
//! }
|
||||
//!
|
||||
//! fn main() {
|
||||
//! // this code is running in a pool of schedulers all powered by libuv
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! # Using a scheduler pool
|
||||
//!
|
||||
//! ```rust
|
||||
@ -176,11 +197,11 @@
|
||||
#[allow(visible_private_types)];
|
||||
|
||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
||||
#[cfg(test)] extern crate rustuv;
|
||||
extern crate rand;
|
||||
|
||||
use std::mem::replace;
|
||||
use std::os;
|
||||
use std::rt::crate_map;
|
||||
use std::rt::rtio;
|
||||
use std::rt::thread::Thread;
|
||||
use std::rt;
|
||||
@ -225,12 +246,14 @@ pub mod task;
|
||||
///
|
||||
/// The return value is used as the process return code. 0 on success, 101 on
|
||||
/// error.
|
||||
pub fn start(argc: int, argv: **u8, main: proc()) -> int {
|
||||
pub fn start(argc: int, argv: **u8,
|
||||
event_loop_factory: fn() -> ~rtio::EventLoop,
|
||||
main: proc()) -> int {
|
||||
rt::init(argc, argv);
|
||||
let mut main = Some(main);
|
||||
let mut ret = None;
|
||||
simple::task().run(|| {
|
||||
ret = Some(run(main.take_unwrap()));
|
||||
ret = Some(run(event_loop_factory, main.take_unwrap()));
|
||||
});
|
||||
// unsafe is ok b/c we're sure that the runtime is gone
|
||||
unsafe { rt::cleanup() }
|
||||
@ -245,10 +268,12 @@ pub fn start(argc: int, argv: **u8, main: proc()) -> int {
|
||||
///
|
||||
/// This function will not return until all schedulers in the associated pool
|
||||
/// have returned.
|
||||
pub fn run(main: proc()) -> int {
|
||||
pub fn run(event_loop_factory: fn() -> ~rtio::EventLoop, main: proc()) -> int {
|
||||
// Create a scheduler pool and spawn the main task into this pool. We will
|
||||
// get notified over a channel when the main task exits.
|
||||
let mut pool = SchedPool::new(PoolConfig::new());
|
||||
let mut cfg = PoolConfig::new();
|
||||
cfg.event_loop_factory = event_loop_factory;
|
||||
let mut pool = SchedPool::new(cfg);
|
||||
let (tx, rx) = channel();
|
||||
let mut opts = TaskOpts::new();
|
||||
opts.notify_chan = Some(tx);
|
||||
@ -273,7 +298,7 @@ pub struct PoolConfig {
|
||||
threads: uint,
|
||||
/// A factory function used to create new event loops. If this is not
|
||||
/// specified then the default event loop factory is used.
|
||||
event_loop_factory: Option<fn() -> ~rtio::EventLoop>,
|
||||
event_loop_factory: fn() -> ~rtio::EventLoop,
|
||||
}
|
||||
|
||||
impl PoolConfig {
|
||||
@ -282,7 +307,7 @@ impl PoolConfig {
|
||||
pub fn new() -> PoolConfig {
|
||||
PoolConfig {
|
||||
threads: rt::default_sched_threads(),
|
||||
event_loop_factory: None,
|
||||
event_loop_factory: basic::event_loop,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -324,7 +349,6 @@ impl SchedPool {
|
||||
threads: nscheds,
|
||||
event_loop_factory: factory
|
||||
} = config;
|
||||
let factory = factory.unwrap_or(default_event_loop_factory());
|
||||
assert!(nscheds > 0);
|
||||
|
||||
// The pool of schedulers that will be returned from this function
|
||||
@ -493,20 +517,3 @@ impl Drop for SchedPool {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn default_event_loop_factory() -> fn() -> ~rtio::EventLoop {
|
||||
match crate_map::get_crate_map() {
|
||||
None => {}
|
||||
Some(map) => {
|
||||
match map.event_loop_factory {
|
||||
None => {}
|
||||
Some(factory) => return factory
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the crate map didn't specify a factory to create an event loop, then
|
||||
// instead just use a basic event loop missing all I/O services to at least
|
||||
// get the scheduler running.
|
||||
return basic::event_loop;
|
||||
}
|
||||
|
@ -1003,6 +1003,8 @@ fn new_sched_rng() -> XorShiftRng {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use rustuv;
|
||||
|
||||
use std::comm;
|
||||
use std::task::TaskOpts;
|
||||
use std::rt::Runtime;
|
||||
@ -1017,7 +1019,7 @@ mod test {
|
||||
fn pool() -> SchedPool {
|
||||
SchedPool::new(PoolConfig {
|
||||
threads: 1,
|
||||
event_loop_factory: Some(basic::event_loop),
|
||||
event_loop_factory: basic::event_loop,
|
||||
})
|
||||
}
|
||||
|
||||
@ -1262,7 +1264,7 @@ mod test {
|
||||
|
||||
let mut pool = SchedPool::new(PoolConfig {
|
||||
threads: 2,
|
||||
event_loop_factory: None,
|
||||
event_loop_factory: rustuv::event_loop,
|
||||
});
|
||||
|
||||
// This is a regression test that when there are no schedulable tasks in
|
||||
@ -1413,7 +1415,7 @@ mod test {
|
||||
fn dont_starve_1() {
|
||||
let mut pool = SchedPool::new(PoolConfig {
|
||||
threads: 2, // this must be > 1
|
||||
event_loop_factory: Some(basic::event_loop),
|
||||
event_loop_factory: basic::event_loop,
|
||||
});
|
||||
pool.spawn(TaskOpts::new(), proc() {
|
||||
let (tx, rx) = channel();
|
||||
|
@ -494,7 +494,7 @@ mod tests {
|
||||
fn spawn_opts(opts: TaskOpts, f: proc()) {
|
||||
let mut pool = SchedPool::new(PoolConfig {
|
||||
threads: 1,
|
||||
event_loop_factory: None,
|
||||
event_loop_factory: ::rustuv::event_loop,
|
||||
});
|
||||
pool.spawn(opts, f);
|
||||
pool.shutdown();
|
||||
|
@ -451,8 +451,6 @@ cgoptions!(
|
||||
"don't run LLVM's SLP vectorization pass"),
|
||||
soft_float: bool = (false, parse_bool,
|
||||
"generate software floating point library calls"),
|
||||
gen_crate_map: bool = (false, parse_bool,
|
||||
"force generation of a toplevel crate map"),
|
||||
prefer_dynamic: bool = (false, parse_bool,
|
||||
"prefer dynamic linking to static linking"),
|
||||
no_integrated_as: bool = (false, parse_bool,
|
||||
|
@ -254,8 +254,6 @@ lets_do_this! {
|
||||
TyVisitorTraitLangItem, "ty_visitor", ty_visitor;
|
||||
OpaqueStructLangItem, "opaque", opaque;
|
||||
|
||||
EventLoopFactoryLangItem, "event_loop_factory", event_loop_factory;
|
||||
|
||||
TypeIdLangItem, "type_id", type_id;
|
||||
|
||||
EhPersonalityLangItem, "eh_personality", eh_personality_fn;
|
||||
|
@ -980,7 +980,7 @@ static other_attrs: &'static [&'static str] = &[
|
||||
"thread_local", // for statics
|
||||
"allow", "deny", "forbid", "warn", // lint options
|
||||
"deprecated", "experimental", "unstable", "stable", "locked", "frozen", //item stability
|
||||
"crate_map", "cfg", "doc", "export_name", "link_section",
|
||||
"cfg", "doc", "export_name", "link_section",
|
||||
"no_mangle", "static_assert", "unsafe_no_drop_flag", "packed",
|
||||
"simd", "repr", "deriving", "unsafe_destructor", "link", "phase",
|
||||
"macro_export", "must_use", "automatically_derived",
|
||||
|
@ -76,7 +76,7 @@ use std::c_str::ToCStr;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::libc::c_uint;
|
||||
use std::local_data;
|
||||
use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic, OsWin32};
|
||||
use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic};
|
||||
use syntax::ast_map::PathName;
|
||||
use syntax::ast_util::{local_def, is_local};
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
@ -2316,65 +2316,6 @@ pub fn symname(name: &str, hash: &str, vers: &str) -> ~str {
|
||||
link::exported_name(ast_map::Values(path.iter()).chain(None), hash, vers)
|
||||
}
|
||||
|
||||
pub fn decl_crate_map(ccx: &mut CrateContext) {
|
||||
let mut n_subcrates = 1;
|
||||
while ccx.sess().cstore.have_crate_data(n_subcrates) {
|
||||
n_subcrates += 1;
|
||||
}
|
||||
let is_top = !ccx.sess().building_library.get() || ccx.sess().opts.cg.gen_crate_map;
|
||||
let sym_name = if is_top {
|
||||
~"_rust_crate_map_toplevel"
|
||||
} else {
|
||||
symname("_rust_crate_map_" + ccx.link_meta.crateid.name,
|
||||
ccx.link_meta.crate_hash.as_str(),
|
||||
ccx.link_meta.crateid.version_or_default())
|
||||
};
|
||||
|
||||
let maptype = Type::struct_(ccx, [
|
||||
Type::i32(ccx), // version
|
||||
ccx.int_type.ptr_to(), // event loop factory
|
||||
], false);
|
||||
let map = sym_name.with_c_str(|buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, maptype.to_ref(), buf)
|
||||
}
|
||||
});
|
||||
lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
|
||||
|
||||
// On windows we'd like to export the toplevel cratemap
|
||||
// such that we can find it from libstd.
|
||||
if ccx.sess().targ_cfg.os == OsWin32 && is_top {
|
||||
unsafe { llvm::LLVMRustSetDLLExportStorageClass(map) }
|
||||
}
|
||||
|
||||
ccx.crate_map_name = sym_name;
|
||||
ccx.crate_map = map;
|
||||
}
|
||||
|
||||
pub fn fill_crate_map(ccx: &CrateContext, map: ValueRef) {
|
||||
let event_loop_factory = match ccx.tcx.lang_items.event_loop_factory() {
|
||||
Some(did) => unsafe {
|
||||
if is_local(did) {
|
||||
llvm::LLVMConstPointerCast(get_item_val(ccx, did.node),
|
||||
ccx.int_type.ptr_to().to_ref())
|
||||
} else {
|
||||
let name = csearch::get_symbol(&ccx.sess().cstore, did);
|
||||
let global = name.with_c_str(|buf| {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf)
|
||||
});
|
||||
global
|
||||
}
|
||||
},
|
||||
None => C_null(ccx.int_type.ptr_to())
|
||||
};
|
||||
unsafe {
|
||||
llvm::LLVMSetInitializer(map, C_struct(ccx,
|
||||
[C_i32(ccx, 2),
|
||||
event_loop_factory,
|
||||
], false));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::EncodeInlinedItem<'r>)
|
||||
-> encoder::EncodeParams<'r> {
|
||||
|
||||
@ -2467,26 +2408,6 @@ pub fn trans_crate(krate: ast::Crate,
|
||||
trans_mod(&ccx, &krate.module);
|
||||
}
|
||||
|
||||
fill_crate_map(&ccx, ccx.crate_map);
|
||||
|
||||
// win32: wart with exporting crate_map symbol
|
||||
// We set the crate map (_rust_crate_map_toplevel) to use dll_export
|
||||
// linkage but that ends up causing the linker to look for a
|
||||
// __rust_crate_map_toplevel symbol (extra underscore) which it will
|
||||
// subsequently fail to find. So to mitigate that we just introduce
|
||||
// an alias from the symbol it expects to the one that actually exists.
|
||||
if ccx.sess().targ_cfg.os == OsWin32 && !ccx.sess().building_library.get() {
|
||||
|
||||
let maptype = val_ty(ccx.crate_map).to_ref();
|
||||
|
||||
"__rust_crate_map_toplevel".with_c_str(|buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAddAlias(ccx.llmod, maptype,
|
||||
ccx.crate_map, buf);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
glue::emit_tydescs(&ccx);
|
||||
if ccx.sess().opts.debuginfo != NoDebugInfo {
|
||||
debuginfo::finalize(&ccx);
|
||||
@ -2537,7 +2458,6 @@ pub fn trans_crate(krate: ast::Crate,
|
||||
// symbol. This symbol is required for use by the libmorestack library that
|
||||
// we link in, so we must ensure that this symbol is not internalized (if
|
||||
// defined in the crate).
|
||||
reachable.push(ccx.crate_map_name.to_owned());
|
||||
reachable.push(~"main");
|
||||
reachable.push(~"rust_stack_exhausted");
|
||||
reachable.push(~"rust_eh_personality"); // referenced from .eh_frame section on some platforms
|
||||
|
@ -22,7 +22,6 @@ use middle::trans::base;
|
||||
use middle::trans::builder::Builder;
|
||||
use middle::trans::common::{C_i32, C_null};
|
||||
use middle::trans::common::{mono_id,ExternMap,tydesc_info,BuilderRef_res,Stats};
|
||||
use middle::trans::base::{decl_crate_map};
|
||||
use middle::trans::debuginfo;
|
||||
use middle::trans::type_::Type;
|
||||
use middle::ty;
|
||||
@ -105,8 +104,6 @@ pub struct CrateContext {
|
||||
int_type: Type,
|
||||
opaque_vec_type: Type,
|
||||
builder: BuilderRef_res,
|
||||
crate_map: ValueRef,
|
||||
crate_map_name: ~str,
|
||||
// Set when at least one function uses GC. Needed so that
|
||||
// decl_gc_metadata knows whether to link to the module metadata, which
|
||||
// is not emitted by LLVM's GC pass when no functions use GC.
|
||||
@ -200,8 +197,6 @@ impl CrateContext {
|
||||
int_type: Type::from_ref(ptr::null()),
|
||||
opaque_vec_type: Type::from_ref(ptr::null()),
|
||||
builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)),
|
||||
crate_map: ptr::null(),
|
||||
crate_map_name: ~"",
|
||||
uses_gc: false,
|
||||
dbg_cx: dbg_cx,
|
||||
};
|
||||
@ -215,8 +210,6 @@ impl CrateContext {
|
||||
str_slice_ty.set_struct_body([Type::i8p(&ccx), ccx.int_type], false);
|
||||
ccx.tn.associate_type("str_slice", &str_slice_ty);
|
||||
|
||||
decl_crate_map(&mut ccx);
|
||||
|
||||
base::declare_intrinsics(&mut ccx);
|
||||
|
||||
if ccx.sess().count_llvm_insns() {
|
||||
|
@ -134,28 +134,6 @@ pub fn register_static(ccx: &CrateContext,
|
||||
let ty = ty::node_id_to_type(ccx.tcx(), foreign_item.id);
|
||||
let llty = type_of::type_of(ccx, ty);
|
||||
|
||||
// Treat the crate map static specially in order to
|
||||
// a weak-linkage-like functionality where it's
|
||||
// dynamically resolved at runtime. If we're
|
||||
// building a library, then we declare the static
|
||||
// with weak linkage, but if we're building a
|
||||
// library then we've already declared the crate map
|
||||
// so use that instead.
|
||||
if attr::contains_name(foreign_item.attrs.as_slice(), "crate_map") {
|
||||
return if ccx.sess().building_library.get() {
|
||||
let s = "_rust_crate_map_toplevel";
|
||||
let g = unsafe {
|
||||
s.with_c_str(|buf| {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, llty.to_ref(), buf)
|
||||
})
|
||||
};
|
||||
lib::llvm::SetLinkage(g, lib::llvm::ExternalWeakLinkage);
|
||||
g
|
||||
} else {
|
||||
ccx.crate_map
|
||||
}
|
||||
}
|
||||
|
||||
let ident = link_name(foreign_item);
|
||||
match attr::first_attr_value_str_by_name(foreign_item.attrs.as_slice(),
|
||||
"linkage") {
|
||||
|
@ -167,7 +167,7 @@ mod test {
|
||||
let (tx, rx) = channel();
|
||||
let mut pool = SchedPool::new(PoolConfig {
|
||||
threads: 1,
|
||||
event_loop_factory: None,
|
||||
event_loop_factory: ::event_loop,
|
||||
});
|
||||
|
||||
pool.spawn(TaskOpts::new(), proc() {
|
||||
@ -188,7 +188,7 @@ mod test {
|
||||
let (tx, rx) = channel();
|
||||
let mut pool = SchedPool::new(PoolConfig {
|
||||
threads: 1,
|
||||
event_loop_factory: None,
|
||||
event_loop_factory: ::event_loop,
|
||||
});
|
||||
|
||||
pool.spawn(TaskOpts::new(), proc() {
|
||||
|
@ -54,6 +54,7 @@ use std::libc::{c_int, c_void};
|
||||
use std::ptr::null;
|
||||
use std::ptr;
|
||||
use std::rt::local::Local;
|
||||
use std::rt::rtio;
|
||||
use std::rt::task::{BlockedTask, Task};
|
||||
use std::str::raw::from_c_str;
|
||||
use std::str;
|
||||
@ -76,7 +77,7 @@ pub use self::tty::TtyWatcher;
|
||||
// '__test' module.
|
||||
#[cfg(test)] #[start]
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
green::start(argc, argv, __test::main)
|
||||
green::start(argc, argv, event_loop, __test::main)
|
||||
}
|
||||
|
||||
mod macros;
|
||||
@ -104,6 +105,31 @@ pub mod tty;
|
||||
pub mod signal;
|
||||
pub mod stream;
|
||||
|
||||
/// Creates a new event loop which is powered by libuv
|
||||
///
|
||||
/// This function is used in tandem with libgreen's `PoolConfig` type as a value
|
||||
/// for the `event_loop_factory` field. Using this function as the event loop
|
||||
/// factory will power programs with libuv and enable green threading.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// extern crate rustuv;
|
||||
/// extern crate green;
|
||||
///
|
||||
/// #[start]
|
||||
/// fn start(argc: int, argv: **u8) -> int {
|
||||
/// green::start(argc, argv, rustuv::event_loop, main)
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// // this code is running inside of a green task powered by libuv
|
||||
/// }
|
||||
/// ```
|
||||
pub fn event_loop() -> ~rtio::EventLoop {
|
||||
~uvio::UvEventLoop::new() as ~rtio::EventLoop
|
||||
}
|
||||
|
||||
/// A type that wraps a uv handle
|
||||
pub trait UvHandle<T> {
|
||||
fn uv_handle(&self) -> *T;
|
||||
|
@ -105,12 +105,6 @@ impl rtio::EventLoop for UvEventLoop {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[lang = "event_loop_factory"]
|
||||
pub fn new_loop() -> ~rtio::EventLoop {
|
||||
~UvEventLoop::new() as ~rtio::EventLoop
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_callback_run_once() {
|
||||
use std::rt::rtio::EventLoop;
|
||||
|
@ -84,7 +84,7 @@
|
||||
// '__test' module.
|
||||
#[cfg(test)] #[start]
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
green::start(argc, argv, __test::main)
|
||||
green::start(argc, argv, rustuv::event_loop, __test::main)
|
||||
}
|
||||
|
||||
pub mod macros;
|
||||
|
@ -1,104 +0,0 @@
|
||||
// Copyright 2013 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 cast;
|
||||
use option::{Some, None, Option};
|
||||
use ptr::RawPtr;
|
||||
use rt::rtio::EventLoop;
|
||||
|
||||
// Need to tell the linker on OS X to not barf on undefined symbols
|
||||
// and instead look them up at runtime, which we need to resolve
|
||||
// the crate_map properly.
|
||||
#[cfg(target_os = "macos")]
|
||||
#[link_args = "-Wl,-U,__rust_crate_map_toplevel"]
|
||||
extern {}
|
||||
|
||||
pub struct CrateMap<'a> {
|
||||
version: i32,
|
||||
event_loop_factory: Option<fn() -> ~EventLoop>,
|
||||
}
|
||||
|
||||
// When working on android, apparently weak symbols don't work so well for
|
||||
// finding the crate map, and neither does dlopen + dlsym. This is mainly a
|
||||
// problem when integrating a shared library with an existing application.
|
||||
// Standalone binaries do not appear to have this problem. The reasons are a
|
||||
// little mysterious, and more information can be found in #11731.
|
||||
//
|
||||
// For now we provide a way to tell libstd about the crate map manually that's
|
||||
// checked before the normal weak symbol/dlopen paths. In theory this is useful
|
||||
// on other platforms where our dlopen/weak linkage strategy mysteriously fails
|
||||
// but the crate map can be specified manually.
|
||||
static mut MANUALLY_PROVIDED_CRATE_MAP: *CrateMap<'static> =
|
||||
0 as *CrateMap<'static>;
|
||||
#[no_mangle]
|
||||
#[cfg(not(test))]
|
||||
pub extern fn rust_set_crate_map(map: *CrateMap<'static>) {
|
||||
unsafe { MANUALLY_PROVIDED_CRATE_MAP = map; }
|
||||
}
|
||||
|
||||
fn manual_crate_map() -> Option<&'static CrateMap<'static>> {
|
||||
unsafe {
|
||||
if MANUALLY_PROVIDED_CRATE_MAP.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(cast::transmute(MANUALLY_PROVIDED_CRATE_MAP))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
|
||||
extern {
|
||||
#[crate_map]
|
||||
static CRATE_MAP: CrateMap<'static>;
|
||||
}
|
||||
|
||||
manual_crate_map().or_else(|| {
|
||||
let ptr: (*CrateMap) = &'static CRATE_MAP;
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(&'static CRATE_MAP)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
|
||||
use c_str::ToCStr;
|
||||
use unstable::dynamic_lib::dl;
|
||||
|
||||
match manual_crate_map() {
|
||||
Some(cm) => return Some(cm),
|
||||
None => {}
|
||||
}
|
||||
|
||||
let sym = unsafe {
|
||||
let module = dl::open_internal();
|
||||
let rust_crate_map_toplevel = if cfg!(target_arch = "x86") {
|
||||
"__rust_crate_map_toplevel"
|
||||
} else {
|
||||
"_rust_crate_map_toplevel"
|
||||
};
|
||||
let sym = rust_crate_map_toplevel.with_c_str(|buf| {
|
||||
dl::symbol(module, buf)
|
||||
});
|
||||
dl::close(module);
|
||||
sym
|
||||
};
|
||||
let ptr: (*CrateMap) = sym as *CrateMap;
|
||||
if ptr.is_null() {
|
||||
return None;
|
||||
} else {
|
||||
unsafe {
|
||||
return Some(cast::transmute(sym));
|
||||
}
|
||||
}
|
||||
}
|
@ -104,9 +104,6 @@ pub mod env;
|
||||
/// The local, managed heap
|
||||
pub mod local_heap;
|
||||
|
||||
/// Crate map
|
||||
pub mod crate_map;
|
||||
|
||||
/// The runtime needs to be able to put a pointer into thread-local storage.
|
||||
mod local_ptr;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) lib.rs -C gen-crate-map
|
||||
$(RUSTC) lib.rs
|
||||
ln -nsf $(call DYLIB,boot-*) $(call DYLIB,boot)
|
||||
$(CC) main.c -o $(call RUN,main) -lboot
|
||||
$(call RUN,main)
|
||||
|
@ -16,7 +16,7 @@ extern crate green;
|
||||
|
||||
#[no_mangle] // this needs to get called from C
|
||||
pub extern "C" fn foo(argc: int, argv: **u8) -> int {
|
||||
green::start(argc, argv, proc() {
|
||||
green::start(argc, argv, rustuv::event_loop, proc() {
|
||||
spawn(proc() {
|
||||
println!("hello");
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) lib.rs -C gen-crate-map
|
||||
$(RUSTC) lib.rs
|
||||
ln -nsf $(call DYLIB,boot-*) $(call DYLIB,boot)
|
||||
$(CC) main.c -o $(call RUN,main) -lboot
|
||||
$(call RUN,main)
|
||||
|
@ -5,7 +5,7 @@ ifneq ($(shell uname),Darwin)
|
||||
endif
|
||||
|
||||
all:
|
||||
$(RUSTC) foo.rs -C gen-crate-map
|
||||
$(RUSTC) foo.rs
|
||||
ln -s $(call STATICLIB,foo-*) $(call STATICLIB,foo)
|
||||
$(CC) bar.c -lfoo -o $(call RUN,bar) $(EXTRAFLAGS) -lstdc++
|
||||
$(call RUN,bar)
|
||||
|
@ -1,7 +0,0 @@
|
||||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) lib.rs -C gen-crate-map
|
||||
ln -nsf $(call DYLIB,boot-*) $(call DYLIB,boot)
|
||||
$(CC) main.c -o $(call RUN,main) -lboot -Wl,-rpath,$(TMPDIR)
|
||||
RUST_LOG=boot $(call RUN,main)
|
@ -1,32 +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.
|
||||
|
||||
#[crate_id="boot#0.1"];
|
||||
#[crate_type="dylib"];
|
||||
#[no_uv];
|
||||
#[feature(phase)];
|
||||
|
||||
extern crate rustuv;
|
||||
extern crate green;
|
||||
#[phase(syntax, link)] extern crate log;
|
||||
|
||||
use std::rt::crate_map::{CrateMap, rust_set_crate_map};
|
||||
|
||||
// pull in this symbol from libstd into this crate (for convenience)
|
||||
#[no_mangle]
|
||||
pub static set_crate_map: extern "C" fn(*CrateMap<'static>) = rust_set_crate_map;
|
||||
|
||||
#[no_mangle] // this needs to get called from C
|
||||
pub extern "C" fn foo(argc: int, argv: **u8) -> int {
|
||||
green::start(argc, argv, proc() {
|
||||
if log_enabled!(log::DEBUG) { return }
|
||||
fail!()
|
||||
})
|
||||
}
|
@ -1,20 +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.
|
||||
|
||||
// this is the rust entry point that we're going to call.
|
||||
int foo(int argc, char *argv[]);
|
||||
|
||||
extern void (*set_crate_map)(void *map);
|
||||
extern int _rust_crate_map_toplevel;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
set_crate_map(&_rust_crate_map_toplevel);
|
||||
return foo(argc, argv);
|
||||
}
|
@ -5,7 +5,7 @@ ifneq ($(shell uname),Darwin)
|
||||
endif
|
||||
|
||||
all:
|
||||
$(RUSTC) foo.rs -C gen-crate-map -Z lto
|
||||
$(RUSTC) foo.rs -Z lto
|
||||
ln -s $(call STATICLIB,foo-*) $(call STATICLIB,foo)
|
||||
$(CC) bar.c -lfoo -o $(call RUN,bar) $(EXTRAFLAGS) -lstdc++
|
||||
$(call RUN,bar)
|
||||
|
@ -49,7 +49,7 @@ macro_rules! iotest (
|
||||
|
||||
#[cfg(test)] #[start]
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
green::start(argc, argv, __test::main)
|
||||
green::start(argc, argv, rustuv::event_loop, __test::main)
|
||||
}
|
||||
|
||||
iotest!(fn test_destroy_once() {
|
||||
|
@ -15,7 +15,9 @@ extern crate green;
|
||||
extern crate rustuv;
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) }
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
green::start(argc, argv, rustuv::event_loop, main)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
native::task::spawn(proc() customtask());
|
||||
|
@ -18,7 +18,7 @@ static mut DROP_T: int = 0i;
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
let ret = green::start(argc, argv, main);
|
||||
let ret = green::start(argc, argv, green::basic::event_loop, main);
|
||||
unsafe {
|
||||
assert_eq!(2, DROP);
|
||||
assert_eq!(1, DROP_S);
|
||||
|
@ -28,7 +28,9 @@ use std::io::process;
|
||||
use std::io::signal::{Listener, Interrupt};
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) }
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
green::start(argc, argv, rustuv::event_loop, main)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe { libc::setsid(); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user