From 6bd80f74505a3eb7c44753c69cbe253ff566d5c1 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 5 Dec 2013 17:25:48 -0800 Subject: librustuv: Change `with_local_io` to use RAII. --- src/libstd/rt/basic.rs | 7 +++-- src/libstd/rt/rtio.rs | 71 ++++++++++++++++++++++++++++++++++---------------- 2 files changed, 53 insertions(+), 25 deletions(-) (limited to 'src/libstd/rt') 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(f: |&mut IoFactory| -> Option) -> Option { - 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 { -- cgit 1.4.1-3-g733a5