Make IO thread-safe.

Each IO handle has a home event loop, which created it.
When a task wants to use an IO handle, it must first make sure it is on that home event loop.
It uses the scheduler handle in the IO handle to send itself there before starting the IO action.
Once the IO action completes, the task restores its previous home state.
If it is an AnySched task, then it will be executed on the new scheduler.
If it has a normal home, then it will return there before executing any more code after the IO action.
This commit is contained in:
Eric Reed 2013-08-08 18:58:18 -07:00
parent d09412ab89
commit 35e844ffc1
4 changed files with 654 additions and 661 deletions

View File

@ -41,7 +41,7 @@ impl Timer {
}
impl RtioTimer for Timer {
fn sleep(&self, msecs: u64) {
fn sleep(&mut self, msecs: u64) {
(**self).sleep(msecs);
}
}
@ -50,15 +50,11 @@ impl RtioTimer for Timer {
mod test {
use super::*;
use rt::test::*;
use option::{Some, None};
#[test]
fn test_io_timer_sleep_simple() {
do run_in_newsched_task {
let timer = Timer::new();
match timer {
Some(t) => t.sleep(1),
None => assert!(false)
}
do timer.map_move |mut t| { t.sleep(1) };
}
}
}
}

View File

@ -22,7 +22,7 @@ pub type RemoteCallbackObject = uvio::UvRemoteCallback;
pub type IoFactoryObject = uvio::UvIoFactory;
pub type RtioTcpStreamObject = uvio::UvTcpStream;
pub type RtioTcpListenerObject = uvio::UvTcpListener;
pub type RtioUdpSocketObject = uvio::HomedUvUdpSocket; //uvio::UvUdpSocket;
pub type RtioUdpSocketObject = uvio::UvUdpSocket;
pub type RtioTimerObject = uvio::UvTimer;
pub trait EventLoop {
@ -88,5 +88,5 @@ pub trait RtioUdpSocket : RtioSocket {
}
pub trait RtioTimer {
fn sleep(&self, msecs: u64);
fn sleep(&mut self, msecs: u64);
}

File diff suppressed because it is too large Load Diff

View File

@ -288,7 +288,7 @@ pub unsafe fn get_udp_handle_from_send_req(send_req: *uv_udp_send_t) -> *uv_udp_
return rust_uv_get_udp_handle_from_send_req(send_req);
}
pub unsafe fn udp_get_sockname(handle: *uv_udp_t, name: *sockaddr_storage) -> c_int {
pub unsafe fn udp_getsockname(handle: *uv_udp_t, name: *sockaddr_storage) -> c_int {
#[fixed_stack_segment]; #[inline(never)];
return rust_uv_udp_getsockname(handle, name);