Skip to content

Commit 043fb0b

Browse files
committed
---
yaml --- r: 63512 b: refs/heads/snap-stage3 c: bbf5469 h: refs/heads/master v: v3
1 parent 9b39475 commit 043fb0b

File tree

14 files changed

+570
-554
lines changed

14 files changed

+570
-554
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 2d28d645422c1617be58c8ca7ad9a457264ca850
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 55dda46cf676e5efd713a0c1c8c4c5a297a6db02
4+
refs/heads/snap-stage3: bbf5469b750233455e47a48d477a8c9a5a724a9a
55
refs/heads/try: 7b78b52e602bb3ea8174f9b2006bff3315f03ef9
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/libstd/rt/io/net/ip.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#[deriving(Eq, TotalEq)]
1211
pub enum IpAddr {
1312
Ipv4(u8, u8, u8, u8, u16),
1413
Ipv6

branches/snap-stage3/src/libstd/rt/io/net/udp.rs

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

11-
use option::{Option, Some, None};
12-
use result::{Ok, Err};
13-
use rt::io::net::ip::IpAddr;
14-
use rt::io::{Reader, Writer};
15-
use rt::io::{io_error, read_error, EndOfFile};
16-
use rt::rtio::{RtioUdpSocketObject, RtioUdpSocket, IoFactory, IoFactoryObject};
17-
use rt::local::Local;
11+
use prelude::*;
12+
use super::super::*;
13+
use super::ip::IpAddr;
1814

19-
pub struct UdpSocket {
20-
rtsocket: ~RtioUdpSocketObject
21-
}
22-
23-
impl UdpSocket {
24-
fn new(s: ~RtioUdpSocketObject) -> UdpSocket {
25-
UdpSocket { rtsocket: s }
26-
}
27-
28-
pub fn bind(addr: IpAddr) -> Option<UdpSocket> {
29-
let socket = unsafe {
30-
let io = Local::unsafe_borrow::<IoFactoryObject>();
31-
(*io).udp_bind(addr)
32-
};
33-
match socket {
34-
Ok(s) => { Some(UdpSocket { rtsocket: s }) }
35-
Err(ioerr) => {
36-
io_error::cond.raise(ioerr);
37-
return None;
38-
}
39-
}
40-
}
41-
42-
pub fn recvfrom(&self, buf: &mut [u8]) -> Option<(uint, IpAddr)> {
43-
match (*self.rtsocket).recvfrom(buf) {
44-
Ok((nread, src)) => Some((nread, src)),
45-
Err(ioerr) => {
46-
// EOF is indicated by returning None
47-
// XXX do we ever find EOF reading UDP packets?
48-
if ioerr.kind != EndOfFile {
49-
read_error::cond.raise(ioerr);
50-
}
51-
None
52-
}
53-
}
54-
}
55-
56-
pub fn sendto(&self, buf: &[u8], dst: IpAddr) {
57-
match (*self.rtsocket).sendto(buf, dst) {
58-
Ok(_) => (),
59-
Err(ioerr) => {
60-
io_error::cond.raise(ioerr);
61-
}
62-
}
63-
}
64-
65-
// XXX convert ~self to self eventually
66-
pub fn connect(~self, other: IpAddr) -> UdpStream {
67-
UdpStream { socket: self, connectedTo: other }
68-
}
69-
}
70-
71-
pub struct UdpStream {
72-
socket: ~UdpSocket,
73-
connectedTo: IpAddr
74-
}
15+
pub struct UdpStream;
7516

7617
impl UdpStream {
77-
pub fn as_socket<T>(&self, f: &fn(&UdpSocket) -> T) -> T {
78-
f(self.socket)
79-
}
80-
81-
pub fn disconnect(self) -> ~UdpSocket {
82-
let UdpStream { socket: s, _ } = self;
83-
s
18+
pub fn connect(_addr: IpAddr) -> Option<UdpStream> {
19+
fail!()
8420
}
8521
}
8622

8723
impl Reader for UdpStream {
88-
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
89-
let conn = self.connectedTo;
90-
do self.as_socket |sock| {
91-
sock.recvfrom(buf)
92-
.map_consume(|(nread,src)| if src == conn {nread} else {0})
93-
}
94-
}
24+
fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() }
9525

9626
fn eof(&mut self) -> bool { fail!() }
9727
}
9828

9929
impl Writer for UdpStream {
100-
fn write(&mut self, buf: &[u8]) {
101-
do self.as_socket |sock| {
102-
sock.sendto(buf, self.connectedTo);
103-
}
104-
}
30+
fn write(&mut self, _buf: &[u8]) { fail!() }
10531

10632
fn flush(&mut self) { fail!() }
10733
}
34+
35+
pub struct UdpListener;
36+
37+
impl UdpListener {
38+
pub fn bind(_addr: IpAddr) -> Option<UdpListener> {
39+
fail!()
40+
}
41+
}
42+
43+
impl Listener<UdpStream> for UdpListener {
44+
fn accept(&mut self) -> Option<UdpStream> { fail!() }
45+
}

branches/snap-stage3/src/libstd/rt/mod.rs

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,19 @@ use cell::Cell;
6363
use clone::Clone;
6464
use container::Container;
6565
use from_str::FromStr;
66+
use iter::Times;
6667
use iterator::IteratorUtil;
6768
use option::{Some, None};
6869
use os;
6970
use ptr::RawPtr;
70-
use uint;
7171
use rt::sched::{Scheduler, Coroutine, Shutdown};
7272
use rt::sleeper_list::SleeperList;
7373
use rt::task::Task;
7474
use rt::thread::Thread;
7575
use rt::work_queue::WorkQueue;
7676
use rt::uv::uvio::UvEventLoop;
77+
use unstable::atomics::{AtomicInt, SeqCst};
78+
use unstable::sync::UnsafeAtomicRcBox;
7779
use vec::{OwnedVector, MutableVector};
7880

7981
/// The global (exchange) heap.
@@ -148,7 +150,7 @@ pub mod local_ptr;
148150
/// Bindings to pthread/windows thread-local storage.
149151
pub mod thread_local_storage;
150152

151-
/// A concurrent data structure with which parent tasks wait on child tasks.
153+
/// For waiting on child tasks.
152154
pub mod join_latch;
153155

154156
pub mod metrics;
@@ -174,68 +176,95 @@ pub mod util;
174176
pub fn start(_argc: int, _argv: **u8, crate_map: *u8, main: ~fn()) -> int {
175177

176178
init(crate_map);
177-
run(main);
179+
let exit_code = run(main);
178180
cleanup();
179181

180-
return 0;
182+
return exit_code;
181183
}
182184

183185
/// One-time runtime initialization. Currently all this does is set up logging
184186
/// based on the RUST_LOG environment variable.
185187
pub fn init(crate_map: *u8) {
186188
logging::init(crate_map);
189+
unsafe { rust_update_gc_metadata(crate_map) }
190+
191+
extern {
192+
fn rust_update_gc_metadata(crate_map: *u8);
193+
}
187194
}
188195

196+
/// One-time runtime cleanup.
189197
pub fn cleanup() {
190198
global_heap::cleanup();
191199
}
192200

193-
pub fn run(main: ~fn()) {
201+
/// Execute the main function in a scheduler.
202+
///
203+
/// Configures the runtime according to the environment, by default
204+
/// using a task scheduler with the same number of threads as cores.
205+
/// Returns a process exit code.
206+
pub fn run(main: ~fn()) -> int {
207+
208+
static DEFAULT_ERROR_CODE: int = 101;
209+
194210
let nthreads = match os::getenv("RUST_THREADS") {
195211
Some(nstr) => FromStr::from_str(nstr).get(),
196-
None => unsafe {
197-
// Using more threads than cores in test code
198-
// to force the OS to preempt them frequently.
199-
// Assuming that this help stress test concurrent types.
200-
util::num_cpus() * 2
201-
}
212+
None => unsafe { util::num_cpus() }
202213
};
203214

215+
// The shared list of sleeping schedulers. Schedulers wake each other
216+
// occassionally to do new work.
204217
let sleepers = SleeperList::new();
218+
// The shared work queue. Temporary until work stealing is implemented.
205219
let work_queue = WorkQueue::new();
206220

207-
let mut handles = ~[];
221+
// The schedulers.
208222
let mut scheds = ~[];
223+
// Handles to the schedulers. When the main task ends these will be
224+
// sent the Shutdown message to terminate the schedulers.
225+
let mut handles = ~[];
209226

210-
for uint::range(0, nthreads) |_| {
227+
for nthreads.times {
228+
// Every scheduler is driven by an I/O event loop.
211229
let loop_ = ~UvEventLoop::new();
212230
let mut sched = ~Scheduler::new(loop_, work_queue.clone(), sleepers.clone());
213231
let handle = sched.make_handle();
214232

215-
handles.push(handle);
216233
scheds.push(sched);
234+
handles.push(handle);
217235
}
218236

219-
let main_cell = Cell::new(main);
237+
// Create a shared cell for transmitting the process exit
238+
// code from the main task to this function.
239+
let exit_code = UnsafeAtomicRcBox::new(AtomicInt::new(0));
240+
let exit_code_clone = exit_code.clone();
241+
242+
// When the main task exits, after all the tasks in the main
243+
// task tree, shut down the schedulers and set the exit code.
220244
let handles = Cell::new(handles);
221-
let mut new_task = ~Task::new_root();
222-
let on_exit: ~fn(bool) = |exit_status| {
245+
let on_exit: ~fn(bool) = |exit_success| {
223246

224247
let mut handles = handles.take();
225-
// Tell schedulers to exit
226248
for handles.mut_iter().advance |handle| {
227249
handle.send(Shutdown);
228250
}
229251

230-
rtassert!(exit_status);
252+
unsafe {
253+
let exit_code = if exit_success { 0 } else { DEFAULT_ERROR_CODE };
254+
(*exit_code_clone.get()).store(exit_code, SeqCst);
255+
}
231256
};
257+
258+
// Create and enqueue the main task.
259+
let main_cell = Cell::new(main);
260+
let mut new_task = ~Task::new_root();
232261
new_task.on_exit = Some(on_exit);
233262
let main_task = ~Coroutine::with_task(&mut scheds[0].stack_pool,
234263
new_task, main_cell.take());
235264
scheds[0].enqueue_task(main_task);
236265

266+
// Run each scheduler in a thread.
237267
let mut threads = ~[];
238-
239268
while !scheds.is_empty() {
240269
let sched = scheds.pop();
241270
let sched_cell = Cell::new(sched);
@@ -248,7 +277,12 @@ pub fn run(main: ~fn()) {
248277
}
249278

250279
// Wait for schedulers
251-
let _threads = threads;
280+
{ let _threads = threads; }
281+
282+
// Return the exit code
283+
unsafe {
284+
(*exit_code.get()).load(SeqCst)
285+
}
252286
}
253287

254288
/// Possible contexts in which Rust code may be executing.

branches/snap-stage3/src/libstd/rt/rtio.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ pub type RemoteCallbackObject = uvio::UvRemoteCallback;
2222
pub type IoFactoryObject = uvio::UvIoFactory;
2323
pub type RtioTcpStreamObject = uvio::UvTcpStream;
2424
pub type RtioTcpListenerObject = uvio::UvTcpListener;
25-
pub type RtioUdpSocketObject = uvio::UvUdpSocket;
2625

2726
pub trait EventLoop {
2827
fn run(&mut self);
@@ -45,19 +44,13 @@ pub trait RemoteCallback {
4544
pub trait IoFactory {
4645
fn tcp_connect(&mut self, addr: IpAddr) -> Result<~RtioTcpStreamObject, IoError>;
4746
fn tcp_bind(&mut self, addr: IpAddr) -> Result<~RtioTcpListenerObject, IoError>;
48-
fn udp_bind(&mut self, addr: IpAddr) -> Result<~RtioUdpSocketObject, IoError>;
4947
}
5048

5149
pub trait RtioTcpListener {
5250
fn accept(&mut self) -> Result<~RtioTcpStreamObject, IoError>;
5351
}
5452

5553
pub trait RtioTcpStream {
56-
fn read(&self, buf: &mut [u8]) -> Result<uint, IoError>;
57-
fn write(&self, buf: &[u8]) -> Result<(), IoError>;
58-
}
59-
60-
pub trait RtioUdpSocket {
61-
fn recvfrom(&self, buf: &mut [u8]) -> Result<(uint, IpAddr), IoError>;
62-
fn sendto(&self, buf: &[u8], dst: IpAddr) -> Result<(), IoError>;
54+
fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
55+
fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
6356
}

branches/snap-stage3/src/libstd/rt/uv/mod.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ use rt::io::IoError;
5252
#[cfg(test)] use unstable::run_in_bare_thread;
5353

5454
pub use self::file::FsRequest;
55-
pub use self::net::{StreamWatcher, TcpWatcher, UdpWatcher};
55+
pub use self::net::{StreamWatcher, TcpWatcher};
5656
pub use self::idle::IdleWatcher;
5757
pub use self::timer::TimerWatcher;
5858
pub use self::async::AsyncWatcher;
@@ -126,8 +126,6 @@ pub type ConnectionCallback = ~fn(StreamWatcher, Option<UvError>);
126126
pub type FsCallback = ~fn(FsRequest, Option<UvError>);
127127
pub type TimerCallback = ~fn(TimerWatcher, Option<UvError>);
128128
pub type AsyncCallback = ~fn(AsyncWatcher, Option<UvError>);
129-
pub type UdpReceiveCallback = ~fn(UdpWatcher, int, Buf, Ipv4, uint, Option<UvError>);
130-
pub type UdpSendCallback = ~fn(UdpWatcher, Option<UvError>);
131129

132130

133131
/// Callbacks used by StreamWatchers, set as custom data on the foreign handle
@@ -139,9 +137,7 @@ struct WatcherData {
139137
alloc_cb: Option<AllocCallback>,
140138
idle_cb: Option<IdleCallback>,
141139
timer_cb: Option<TimerCallback>,
142-
async_cb: Option<AsyncCallback>,
143-
udp_recv_cb: Option<UdpReceiveCallback>,
144-
udp_send_cb: Option<UdpSendCallback>
140+
async_cb: Option<AsyncCallback>
145141
}
146142

147143
pub trait WatcherInterop {
@@ -171,9 +167,7 @@ impl<H, W: Watcher + NativeHandle<*H>> WatcherInterop for W {
171167
alloc_cb: None,
172168
idle_cb: None,
173169
timer_cb: None,
174-
async_cb: None,
175-
udp_recv_cb: None,
176-
udp_send_cb: None
170+
async_cb: None
177171
};
178172
let data = transmute::<~WatcherData, *c_void>(data);
179173
uvll::set_data_for_uv_handle(self.native_handle(), data);
@@ -298,9 +292,6 @@ pub fn status_to_maybe_uv_error<T>(handle: *T, status: c_int) -> Option<UvError>
298292
/// The uv buffer type
299293
pub type Buf = uvll::uv_buf_t;
300294
301-
/// The uv IPv4 type
302-
pub type Ipv4 = uvll::sockaddr_in;
303-
304295
/// Borrow a slice to a Buf
305296
pub fn slice_to_uv_buf(v: &[u8]) -> Buf {
306297
let data = vec::raw::to_ptr(v);

0 commit comments

Comments
 (0)