about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-12-05 17:25:48 -0800
committerPatrick Walton <pcwalton@mimiga.net>2013-12-10 15:13:12 -0800
commit6bd80f74505a3eb7c44753c69cbe253ff566d5c1 (patch)
treeacccb99cf7a8bae4571c1e866415c0731a6f0f37 /src/libstd/rt
parent8c2ebe1622681c2a93a2fcf2673a5671fd110ead (diff)
downloadrust-6bd80f74505a3eb7c44753c69cbe253ff566d5c1.tar.gz
rust-6bd80f74505a3eb7c44753c69cbe253ff566d5c1.zip
librustuv: Change `with_local_io` to use RAII.
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/basic.rs7
-rw-r--r--src/libstd/rt/rtio.rs71
2 files changed, 53 insertions, 25 deletions
diff --git a/src/libstd/rt/basic.rs b/src/libstd/rt/basic.rs
index 311138d15a2..87b776d3c1e 100644
--- a/src/libstd/rt/basic.rs
+++ b/src/libstd/rt/basic.rs
@@ -159,8 +159,11 @@ impl EventLoop for BasicLoop {
         ~BasicRemote::new(self.messages.clone(), id) as ~RemoteCallback
     }
 
-    fn io<'a>(&'a mut self, f: |&'a mut IoFactory|) {
-        f(self.io)
+    fn io(&mut self) -> &'static mut IoFactory:'static {
+        unsafe {
+            let factory: &mut IoFactory = self.io;
+            cast::transmute(factory)
+        }
     }
 }
 
diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs
index f83932f9ffa..c6942ab8388 100644
--- a/src/libstd/rt/rtio.rs
+++ b/src/libstd/rt/rtio.rs
@@ -9,15 +9,19 @@
 // except according to those terms.
 
 use c_str::CString;
+use cast;
 use comm::{SharedChan, PortOne, Port};
 use libc::c_int;
 use libc;
+use ops::Drop;
 use option::*;
 use path::Path;
 use result::*;
 
 use ai = io::net::addrinfo;
 use io::IoError;
+use io::native::NATIVE_IO_FACTORY;
+use io::native;
 use io::net::ip::{IpAddr, SocketAddr};
 use io::process::{ProcessConfig, ProcessExit};
 use io::signal::Signum;
@@ -34,9 +38,8 @@ pub trait EventLoop {
     fn pausible_idle_callback(&mut self, ~Callback) -> ~PausibleIdleCallback;
     fn remote_callback(&mut self, ~Callback) -> ~RemoteCallback;
 
-    /// The asynchronous I/O services. Not all event loops may provide one
-    // FIXME(#9382) this is an awful interface
-    fn io<'a>(&'a mut self, f: |&'a mut IoFactory|);
+    /// The asynchronous I/O services. Not all event loops may provide one.
+    fn io(&mut self) -> &'static mut IoFactory:'static;
 }
 
 pub trait RemoteCallback {
@@ -75,31 +78,53 @@ pub enum CloseBehavior {
     CloseAsynchronously,
 }
 
-pub fn with_local_io<T>(f: |&mut IoFactory| -> Option<T>) -> Option<T> {
-    use rt::sched::Scheduler;
-    use rt::local::Local;
-    use io::native;
-
-    unsafe {
-        // First, attempt to use the local scheduler's I/O services
-        let sched: Option<*mut Scheduler> = Local::try_unsafe_borrow();
-        match sched {
-            Some(sched) => {
-                let mut io = None;
-                (*sched).event_loop.io(|i| io = Some(i));
-                match io {
-                    Some(io) => return f(io),
-                    None => {}
+pub struct LocalIo {
+    factory: &'static mut IoFactory:'static,
+}
+
+#[unsafe_destructor]
+impl Drop for LocalIo {
+    fn drop(&mut self) {
+        // XXX(pcwalton): Do nothing here for now, but eventually we may want
+        // something. For now this serves to make `LocalIo` noncopyable.
+    }
+}
+
+impl LocalIo {
+    /// Returns the local I/O: either the local scheduler's I/O services or
+    /// the native I/O services.
+    pub fn borrow() -> LocalIo {
+        use rt::sched::Scheduler;
+        use rt::local::Local;
+
+        unsafe {
+            // First, attempt to use the local scheduler's I/O services
+            let sched: Option<*mut Scheduler> = Local::try_unsafe_borrow();
+            match sched {
+                Some(sched) => {
+                    return LocalIo {
+                        factory: (*sched).event_loop.io(),
+                    }
                 }
+                None => {}
+            }
+            // If we don't have a scheduler or the scheduler doesn't have I/O
+            // services, then fall back to the native I/O services.
+            let native_io: &'static mut native::IoFactory =
+                &mut NATIVE_IO_FACTORY;
+            LocalIo {
+                factory: native_io as &mut IoFactory:'static
             }
-            None => {}
         }
     }
 
-    // If we don't have a scheduler or the scheduler doesn't have I/O services,
-    // then fall back to the native I/O services.
-    let mut io = native::IoFactory;
-    f(&mut io as &mut IoFactory)
+    /// Returns the underlying I/O factory as a trait reference.
+    #[inline]
+    pub fn get(&mut self) -> &'static mut IoFactory {
+        unsafe {
+            cast::transmute_copy(&self.factory)
+        }
+    }
 }
 
 pub trait IoFactory {