diff options
| author | toddaaro <github@opprobrio.us> | 2013-07-19 14:25:05 -0700 |
|---|---|---|
| committer | toddaaro <github@opprobrio.us> | 2013-08-01 15:14:00 -0700 |
| commit | f7eed223873a4280c9abea937e60ef1aaedf0162 (patch) | |
| tree | d1dea92a84b12741e7796cf91938edbae906fd8e /src/libstd/rt/uv | |
| parent | 82b24559e6aa0914f8a49e0a9dbfb3cf35372515 (diff) | |
A major refactoring that changes the way the runtime uses TLS. In the
old design the TLS held the scheduler struct, and the scheduler struct held the active task. This posed all sorts of weird problems due to how we wanted to use the contents of TLS. The cleaner approach is to leave the active task in TLS and have the task hold the scheduler. To make this work out the scheduler has to run inside a regular task, and then once that is the case the context switching code is massively simplified, as instead of three possible paths there is only one. The logical flow is also easier to follow, as the scheduler struct acts somewhat like a "token" indicating what is active. These changes also necessitated changing a large number of runtime tests, and rewriting most of the runtime testing helpers. Polish level is "low", as I will very soon start on more scheduler changes that will require wiping the polish off. That being said there should be sufficient comments around anything complex to make this entirely respectable as a standalone commit.
Diffstat (limited to 'src/libstd/rt/uv')
| -rw-r--r-- | src/libstd/rt/uv/mod.rs | 5 | ||||
| -rw-r--r-- | src/libstd/rt/uv/uvio.rs | 40 |
2 files changed, 19 insertions, 26 deletions
diff --git a/src/libstd/rt/uv/mod.rs b/src/libstd/rt/uv/mod.rs index 638d510614a..fa5c497a877 100644 --- a/src/libstd/rt/uv/mod.rs +++ b/src/libstd/rt/uv/mod.rs @@ -51,7 +51,7 @@ use rt::io::net::ip::IpAddr; use rt::io::IoError; -#[cfg(test)] use unstable::run_in_bare_thread; +//#[cfg(test)] use unstable::run_in_bare_thread; pub use self::file::FsRequest; pub use self::net::{StreamWatcher, TcpWatcher, UdpWatcher}; @@ -333,7 +333,7 @@ pub fn vec_from_uv_buf(buf: Buf) -> Option<~[u8]> { return None; } } - +/* #[test] fn test_slice_to_uv_buf() { let slice = [0, .. 20]; @@ -360,3 +360,4 @@ fn loop_smoke_test() { loop_.close(); } } +*/ diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs index 53ccd20186d..27970cc52af 100644 --- a/src/libstd/rt/uv/uvio.rs +++ b/src/libstd/rt/uv/uvio.rs @@ -33,7 +33,7 @@ use unstable::sync::Exclusive; #[cfg(test)] use container::Container; #[cfg(test)] use uint; #[cfg(test)] use unstable::run_in_bare_thread; -#[cfg(test)] use rt::test::{spawntask_immediately, +#[cfg(test)] use rt::test::{spawntask, next_test_ip4, run_in_newsched_task}; @@ -251,13 +251,11 @@ impl IoFactory for UvIoFactory { let result_cell_ptr: *Cell<Result<~RtioTcpStreamObject, IoError>> = &result_cell; let scheduler = Local::take::<Scheduler>(); - assert!(scheduler.in_task_context()); // Block this task and take ownership, switch to scheduler context - do scheduler.deschedule_running_task_and_then |sched, task| { + do scheduler.deschedule_running_task_and_then |_sched, task| { rtdebug!("connect: entered scheduler context"); - assert!(!sched.in_task_context()); let mut tcp_watcher = TcpWatcher::new(self.uv_loop()); let task_cell = Cell::new(task); @@ -458,11 +456,9 @@ impl RtioTcpStream for UvTcpStream { let result_cell_ptr: *Cell<Result<uint, IoError>> = &result_cell; let scheduler = Local::take::<Scheduler>(); - assert!(scheduler.in_task_context()); let buf_ptr: *&mut [u8] = &buf; - do scheduler.deschedule_running_task_and_then |sched, task| { + do scheduler.deschedule_running_task_and_then |_sched, task| { rtdebug!("read: entered scheduler context"); - assert!(!sched.in_task_context()); let task_cell = Cell::new(task); // XXX: We shouldn't reallocate these callbacks every // call to read @@ -500,7 +496,6 @@ impl RtioTcpStream for UvTcpStream { let result_cell = Cell::new_empty(); let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell; let scheduler = Local::take::<Scheduler>(); - assert!(scheduler.in_task_context()); let buf_ptr: *&[u8] = &buf; do scheduler.deschedule_running_task_and_then |_, task| { let task_cell = Cell::new(task); @@ -602,11 +597,9 @@ impl RtioUdpSocket for UvUdpSocket { let result_cell_ptr: *Cell<Result<(uint, IpAddr), IoError>> = &result_cell; let scheduler = Local::take::<Scheduler>(); - assert!(scheduler.in_task_context()); let buf_ptr: *&mut [u8] = &buf; - do scheduler.deschedule_running_task_and_then |sched, task| { + do scheduler.deschedule_running_task_and_then |_sched, task| { rtdebug!("recvfrom: entered scheduler context"); - assert!(!sched.in_task_context()); let task_cell = Cell::new(task); let alloc: AllocCallback = |_| unsafe { slice_to_uv_buf(*buf_ptr) }; do self.recv_start(alloc) |mut watcher, nread, _buf, addr, flags, status| { @@ -637,7 +630,6 @@ impl RtioUdpSocket for UvUdpSocket { let result_cell = Cell::new_empty(); let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell; let scheduler = Local::take::<Scheduler>(); - assert!(scheduler.in_task_context()); let buf_ptr: *&[u8] = &buf; do scheduler.deschedule_running_task_and_then |_, task| { let task_cell = Cell::new(task); @@ -845,7 +837,7 @@ fn test_simple_tcp_server_and_client() { let addr = next_test_ip4(); // Start the server first so it's listening when we connect - do spawntask_immediately { + do spawntask { unsafe { let io = Local::unsafe_borrow::<IoFactoryObject>(); let mut listener = (*io).tcp_bind(addr).unwrap(); @@ -860,7 +852,7 @@ fn test_simple_tcp_server_and_client() { } } - do spawntask_immediately { + do spawntask { unsafe { let io = Local::unsafe_borrow::<IoFactoryObject>(); let mut stream = (*io).tcp_connect(addr).unwrap(); @@ -876,7 +868,7 @@ fn test_simple_udp_server_and_client() { let server_addr = next_test_ip4(); let client_addr = next_test_ip4(); - do spawntask_immediately { + do spawntask { unsafe { let io = Local::unsafe_borrow::<IoFactoryObject>(); let mut server_socket = (*io).udp_bind(server_addr).unwrap(); @@ -891,7 +883,7 @@ fn test_simple_udp_server_and_client() { } } - do spawntask_immediately { + do spawntask { unsafe { let io = Local::unsafe_borrow::<IoFactoryObject>(); let mut client_socket = (*io).udp_bind(client_addr).unwrap(); @@ -906,7 +898,7 @@ fn test_read_and_block() { do run_in_newsched_task { let addr = next_test_ip4(); - do spawntask_immediately { + do spawntask { let io = unsafe { Local::unsafe_borrow::<IoFactoryObject>() }; let mut listener = unsafe { (*io).tcp_bind(addr).unwrap() }; let mut stream = listener.accept().unwrap(); @@ -939,7 +931,7 @@ fn test_read_and_block() { assert!(reads > 1); } - do spawntask_immediately { + do spawntask { unsafe { let io = Local::unsafe_borrow::<IoFactoryObject>(); let mut stream = (*io).tcp_connect(addr).unwrap(); @@ -959,7 +951,7 @@ fn test_read_read_read() { let addr = next_test_ip4(); static MAX: uint = 500000; - do spawntask_immediately { + do spawntask { unsafe { let io = Local::unsafe_borrow::<IoFactoryObject>(); let mut listener = (*io).tcp_bind(addr).unwrap(); @@ -973,7 +965,7 @@ fn test_read_read_read() { } } - do spawntask_immediately { + do spawntask { unsafe { let io = Local::unsafe_borrow::<IoFactoryObject>(); let mut stream = (*io).tcp_connect(addr).unwrap(); @@ -999,7 +991,7 @@ fn test_udp_twice() { let server_addr = next_test_ip4(); let client_addr = next_test_ip4(); - do spawntask_immediately { + do spawntask { unsafe { let io = Local::unsafe_borrow::<IoFactoryObject>(); let mut client = (*io).udp_bind(client_addr).unwrap(); @@ -1008,7 +1000,7 @@ fn test_udp_twice() { } } - do spawntask_immediately { + do spawntask { unsafe { let io = Local::unsafe_borrow::<IoFactoryObject>(); let mut server = (*io).udp_bind(server_addr).unwrap(); @@ -1036,7 +1028,7 @@ fn test_udp_many_read() { let client_in_addr = next_test_ip4(); static MAX: uint = 500_000; - do spawntask_immediately { + do spawntask { unsafe { let io = Local::unsafe_borrow::<IoFactoryObject>(); let mut server_out = (*io).udp_bind(server_out_addr).unwrap(); @@ -1059,7 +1051,7 @@ fn test_udp_many_read() { } } - do spawntask_immediately { + do spawntask { unsafe { let io = Local::unsafe_borrow::<IoFactoryObject>(); let mut client_out = (*io).udp_bind(client_out_addr).unwrap(); |
