Skip to content

Commit 6aadc9d

Browse files
committed
native: Introduce libnative
This commit introduces a new crate called "native" which will be the crate that implements the 1:1 runtime of rust. This currently entails having an implementation of std::rt::Runtime inside of libnative as well as moving all of the native I/O implementations to libnative. The current snag is that the start lang item must currently be defined in libnative in order to start running, but this will change in the future. Cool fact about this crate, there are no extra features that are enabled. Note that this commit does not include any makefile support necessary for building libnative, that's all coming in a later commit.
1 parent 49e5493 commit 6aadc9d

File tree

6 files changed

+386
-85
lines changed

6 files changed

+386
-85
lines changed

src/libstd/io/native/file.rs renamed to src/libnative/io/file.rs

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,21 @@
1010

1111
//! Blocking posix-based file I/O
1212
13-
#[allow(non_camel_case_types)];
14-
15-
use c_str::CString;
16-
use io::IoError;
17-
use io;
18-
use libc::c_int;
19-
use libc;
20-
use ops::Drop;
21-
use option::{Some, None, Option};
22-
use os;
23-
use path::{Path, GenericPath};
24-
use ptr::RawPtr;
25-
use result::{Result, Ok, Err};
26-
use rt::rtio;
13+
use std::c_str::CString;
14+
use std::io::IoError;
15+
use std::io;
16+
use std::libc::c_int;
17+
use std::libc;
18+
use std::os;
19+
use std::rt::rtio;
20+
use std::unstable::intrinsics;
21+
use std::vec;
22+
2723
use super::IoResult;
28-
use unstable::intrinsics;
29-
use vec::ImmutableVector;
30-
use vec;
3124

32-
#[cfg(windows)] use os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
33-
#[cfg(windows)] use ptr;
34-
#[cfg(windows)] use str;
25+
#[cfg(windows)] use std::os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
26+
#[cfg(windows)] use std::ptr;
27+
#[cfg(windows)] use std::str;
3528

3629
fn keep_going(data: &[u8], f: |*u8, uint| -> i64) -> i64 {
3730
#[cfg(windows)] static eintr: int = 0; // doesn't matter
@@ -490,8 +483,8 @@ pub fn readdir(p: &CString) -> IoResult<~[Path]> {
490483
unsafe {
491484
#[cfg(not(windows))]
492485
unsafe fn get_list(p: &CString) -> IoResult<~[Path]> {
493-
use libc::{dirent_t};
494-
use libc::{opendir, readdir, closedir};
486+
use std::libc::{dirent_t};
487+
use std::libc::{opendir, readdir, closedir};
495488
extern {
496489
fn rust_list_dir_val(ptr: *dirent_t) -> *libc::c_char;
497490
}
@@ -517,14 +510,14 @@ pub fn readdir(p: &CString) -> IoResult<~[Path]> {
517510

518511
#[cfg(windows)]
519512
unsafe fn get_list(p: &CString) -> IoResult<~[Path]> {
520-
use libc::consts::os::extra::INVALID_HANDLE_VALUE;
521-
use libc::{wcslen, free};
522-
use libc::funcs::extra::kernel32::{
513+
use std::libc::consts::os::extra::INVALID_HANDLE_VALUE;
514+
use std::libc::{wcslen, free};
515+
use std::libc::funcs::extra::kernel32::{
523516
FindFirstFileW,
524517
FindNextFileW,
525518
FindClose,
526519
};
527-
use libc::types::os::arch::extra::HANDLE;
520+
use std::libc::types::os::arch::extra::HANDLE;
528521
use os::win32::{
529522
as_utf16_p
530523
};
@@ -906,12 +899,12 @@ pub fn utime(p: &CString, atime: u64, mtime: u64) -> IoResult<()> {
906899

907900
#[cfg(test)]
908901
mod tests {
909-
use io::native::file::{CFile, FileDesc};
910-
use io;
911-
use libc;
912-
use os;
913-
use result::Ok;
914-
use rt::rtio::RtioFileStream;
902+
use std::io::native::file::{CFile, FileDesc};
903+
use std::io::fs;
904+
use std::io;
905+
use std::libc;
906+
use std::os;
907+
use std::rt::rtio::RtioFileStream;
915908

916909
#[ignore(cfg(target_os = "freebsd"))] // hmm, maybe pipes have a tiny buffer
917910
#[test]

src/libstd/io/native/mod.rs renamed to src/libnative/io/mod.rs

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,21 @@
2121
//! play. The only dependencies of these modules are the normal system libraries
2222
//! that you would find on the respective platform.
2323
24-
use c_str::CString;
25-
use comm::SharedChan;
26-
use libc::c_int;
27-
use libc;
28-
use option::{Option, None, Some};
29-
use os;
30-
use path::Path;
31-
use result::{Result, Ok, Err};
32-
use rt::rtio;
33-
use rt::rtio::{RtioTcpStream, RtioTcpListener, RtioUdpSocket, RtioUnixListener,
34-
RtioPipe, RtioFileStream, RtioProcess, RtioSignal, RtioTTY,
35-
CloseBehavior, RtioTimer};
36-
use io;
37-
use io::IoError;
38-
use io::net::ip::SocketAddr;
39-
use io::process::ProcessConfig;
40-
use io::signal::Signum;
41-
use ai = io::net::addrinfo;
24+
use std::c_str::CString;
25+
use std::comm::SharedChan;
26+
use std::libc::c_int;
27+
use std::libc;
28+
use std::os;
29+
use std::rt::rtio;
30+
use std::rt::rtio::{RtioTcpStream, RtioTcpListener, RtioUdpSocket,
31+
RtioUnixListener, RtioPipe, RtioFileStream, RtioProcess,
32+
RtioSignal, RtioTTY, CloseBehavior, RtioTimer};
33+
use std::io;
34+
use std::io::IoError;
35+
use std::io::net::ip::SocketAddr;
36+
use std::io::process::ProcessConfig;
37+
use std::io::signal::Signum;
38+
use ai = std::io::net::addrinfo;
4239

4340
// Local re-exports
4441
pub use self::file::FileDesc;
@@ -114,6 +111,9 @@ fn mkerr_winbool(ret: libc::c_int) -> IoResult<()> {
114111
pub struct IoFactory;
115112

116113
impl rtio::IoFactory for IoFactory {
114+
// all native io factories are the same
115+
fn id(&self) -> uint { 0 }
116+
117117
// networking
118118
fn tcp_connect(&mut self, _addr: SocketAddr) -> IoResult<~RtioTcpStream> {
119119
Err(unimpl())
@@ -223,6 +223,3 @@ impl rtio::IoFactory for IoFactory {
223223
Err(unimpl())
224224
}
225225
}
226-
227-
pub static mut NATIVE_IO_FACTORY: IoFactory = IoFactory;
228-

src/libstd/io/native/process.rs renamed to src/libnative/io/process.rs

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,16 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use io;
12-
use libc::{pid_t, c_void, c_int};
13-
use libc;
14-
use os;
15-
use prelude::*;
16-
use ptr;
17-
use rt::rtio;
18-
use super::file;
19-
#[cfg(windows)]
20-
use cast;
11+
use std::cast;
12+
use std::io;
13+
use std::libc::{pid_t, c_void, c_int};
14+
use std::libc;
15+
use std::os;
16+
use std::ptr;
17+
use std::rt::rtio;
18+
use p = std::io::process;
2119

22-
use p = io::process;
20+
use super::file;
2321

2422
/**
2523
* A value representing a child process.
@@ -179,22 +177,22 @@ fn spawn_process_os(prog: &str, args: &[~str],
179177
env: Option<~[(~str, ~str)]>,
180178
dir: Option<&Path>,
181179
in_fd: c_int, out_fd: c_int, err_fd: c_int) -> SpawnProcessResult {
182-
use libc::types::os::arch::extra::{DWORD, HANDLE, STARTUPINFO};
183-
use libc::consts::os::extra::{
180+
use std::libc::types::os::arch::extra::{DWORD, HANDLE, STARTUPINFO};
181+
use std::libc::consts::os::extra::{
184182
TRUE, FALSE,
185183
STARTF_USESTDHANDLES,
186184
INVALID_HANDLE_VALUE,
187185
DUPLICATE_SAME_ACCESS
188186
};
189-
use libc::funcs::extra::kernel32::{
187+
use std::libc::funcs::extra::kernel32::{
190188
GetCurrentProcess,
191189
DuplicateHandle,
192190
CloseHandle,
193191
CreateProcessA
194192
};
195-
use libc::funcs::extra::msvcrt::get_osfhandle;
193+
use std::libc::funcs::extra::msvcrt::get_osfhandle;
196194

197-
use mem;
195+
use std::mem;
198196

199197
unsafe {
200198

@@ -256,10 +254,10 @@ fn spawn_process_os(prog: &str, args: &[~str],
256254
fail!("failure in CreateProcess: {}", *msg);
257255
}
258256

259-
// We close the thread handle because we don't care about keeping the
257+
// We close the thread handle because std::we don't care about keeping the
260258
// thread id valid, and we aren't keeping the thread handle around to be
261259
// able to close it later. We don't close the process handle however
262-
// because we want the process id to stay valid at least until the
260+
// because std::we want the process id to stay valid at least until the
263261
// calling code closes the process handle.
264262
CloseHandle(pi.hThread);
265263

@@ -362,8 +360,8 @@ fn spawn_process_os(prog: &str, args: &[~str],
362360
env: Option<~[(~str, ~str)]>,
363361
dir: Option<&Path>,
364362
in_fd: c_int, out_fd: c_int, err_fd: c_int) -> SpawnProcessResult {
365-
use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp};
366-
use libc::funcs::bsd44::getdtablesize;
363+
use std::libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp};
364+
use std::libc::funcs::bsd44::getdtablesize;
367365

368366
mod rustrt {
369367
extern {
@@ -433,7 +431,7 @@ fn spawn_process_os(prog: &str, args: &[~str],
433431

434432
#[cfg(unix)]
435433
fn with_argv<T>(prog: &str, args: &[~str], cb: |**libc::c_char| -> T) -> T {
436-
use vec;
434+
use std::vec;
437435

438436
// We can't directly convert `str`s into `*char`s, as someone needs to hold
439437
// a reference to the intermediary byte buffers. So first build an array to
@@ -459,7 +457,7 @@ fn with_argv<T>(prog: &str, args: &[~str], cb: |**libc::c_char| -> T) -> T {
459457

460458
#[cfg(unix)]
461459
fn with_envp<T>(env: Option<~[(~str, ~str)]>, cb: |*c_void| -> T) -> T {
462-
use vec;
460+
use std::vec;
463461

464462
// On posixy systems we can pass a char** for envp, which is a
465463
// null-terminated array of "k=v\n" strings. Like `with_argv`, we have to
@@ -540,16 +538,16 @@ fn waitpid(pid: pid_t) -> int {
540538

541539
#[cfg(windows)]
542540
fn waitpid_os(pid: pid_t) -> int {
543-
use libc::types::os::arch::extra::DWORD;
544-
use libc::consts::os::extra::{
541+
use std::libc::types::os::arch::extra::DWORD;
542+
use std::libc::consts::os::extra::{
545543
SYNCHRONIZE,
546544
PROCESS_QUERY_INFORMATION,
547545
FALSE,
548546
STILL_ACTIVE,
549547
INFINITE,
550548
WAIT_FAILED
551549
};
552-
use libc::funcs::extra::kernel32::{
550+
use std::libc::funcs::extra::kernel32::{
553551
OpenProcess,
554552
GetExitCodeProcess,
555553
CloseHandle,
@@ -585,7 +583,7 @@ fn waitpid(pid: pid_t) -> int {
585583

586584
#[cfg(unix)]
587585
fn waitpid_os(pid: pid_t) -> int {
588-
use libc::funcs::posix01::wait::*;
586+
use std::libc::funcs::posix01::wait;
589587

590588
#[cfg(target_os = "linux")]
591589
#[cfg(target_os = "android")]
@@ -612,7 +610,7 @@ fn waitpid(pid: pid_t) -> int {
612610
}
613611

614612
let mut status = 0 as c_int;
615-
if unsafe { waitpid(pid, &mut status, 0) } == -1 {
613+
if unsafe { wait::waitpid(pid, &mut status, 0) } == -1 {
616614
fail!("failure in waitpid: {}", os::last_os_error());
617615
}
618616

src/libnative/lib.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! The native runtime crate
12+
//!
13+
//! This crate contains an implementation of 1:1 scheduling for a "native"
14+
//! runtime. In addition, all I/O provided by this crate is the thread blocking
15+
//! version of I/O.
16+
17+
#[link(name = "native",
18+
package_id = "native",
19+
vers = "0.9-pre",
20+
uuid = "535344a7-890f-5a23-e1f3-e0d118805141",
21+
url = "https://github.com/mozilla/rust/tree/master/src/native")];
22+
23+
#[license = "MIT/ASL2"];
24+
#[crate_type = "rlib"];
25+
#[crate_type = "dylib"];
26+
27+
// NB this crate explicitly does *not* allow glob imports, please seriously
28+
// consider whether they're needed before adding that feature here.
29+
30+
use std::cast;
31+
use std::os;
32+
use std::rt;
33+
use std::task::try;
34+
35+
pub mod io;
36+
pub mod task;
37+
38+
// XXX: this should not exist here
39+
#[cfg(stage0)]
40+
#[lang = "start"]
41+
pub fn start(main: *u8, argc: int, argv: **u8) -> int {
42+
rt::init(argc, argv);
43+
44+
// Bootstrap ourselves by installing a local Task and then immediately
45+
// spawning a thread to run 'main'. Always spawn a new thread for main so
46+
// the stack size of 'main' is known (and the bounds can be set
47+
// appropriately).
48+
//
49+
// Once the main task has completed, then we wait for everyone else to exit.
50+
task::run(task::new(), proc() {
51+
let main: extern "Rust" fn() = unsafe { cast::transmute(main) };
52+
match do try { main() } {
53+
Ok(()) => { os::set_exit_status(0); }
54+
Err(..) => { os::set_exit_status(rt::DEFAULT_ERROR_CODE); }
55+
}
56+
});
57+
task::wait_for_completion();
58+
59+
unsafe { rt::cleanup(); }
60+
os::get_exit_status()
61+
}

0 commit comments

Comments
 (0)