about summary refs log tree commit diff
path: root/src/libnative
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-06-04 00:01:40 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-06-06 23:00:01 -0700
commit75014f7b1790e7ebdf13d38acc04dfdab6e450e9 (patch)
tree46fb046e002a37ba60f6e8b8ef5ee0675fbb7fd8 /src/libnative
parentd743b8831e6dc5b390af112cc23159d667cf583b (diff)
downloadrust-75014f7b1790e7ebdf13d38acc04dfdab6e450e9.tar.gz
rust-75014f7b1790e7ebdf13d38acc04dfdab6e450e9.zip
libs: Fix miscellaneous fallout of librustrt
Diffstat (limited to 'src/libnative')
-rw-r--r--src/libnative/io/addrinfo.rs2
-rw-r--r--src/libnative/io/file_win32.rs158
-rw-r--r--src/libnative/io/net.rs6
-rw-r--r--src/libnative/io/pipe_win32.rs37
-rw-r--r--src/libnative/io/process.rs24
-rw-r--r--src/libnative/io/timer_win32.rs21
6 files changed, 114 insertions, 134 deletions
diff --git a/src/libnative/io/addrinfo.rs b/src/libnative/io/addrinfo.rs
index b79061dd9d6..255c3f4bd21 100644
--- a/src/libnative/io/addrinfo.rs
+++ b/src/libnative/io/addrinfo.rs
@@ -92,8 +92,6 @@ extern "system" {
     fn freeaddrinfo(res: *mut libc::addrinfo);
     #[cfg(not(windows))]
     fn gai_strerror(errcode: c_int) -> *c_char;
-    #[cfg(windows)]
-    fn WSAGetLastError() -> c_int;
 }
 
 #[cfg(windows)]
diff --git a/src/libnative/io/file_win32.rs b/src/libnative/io/file_win32.rs
index 2cf54ab4007..2a5b78e5506 100644
--- a/src/libnative/io/file_win32.rs
+++ b/src/libnative/io/file_win32.rs
@@ -14,17 +14,14 @@ use alloc::arc::Arc;
 use libc::{c_int, c_void};
 use libc;
 use std::c_str::CString;
-use std::io::IoError;
-use std::io;
 use std::mem;
 use std::os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
 use std::ptr;
 use std::rt::rtio;
+use std::rt::rtio::IoResult;
 use std::str;
 use std::vec;
 
-use io::IoResult;
-
 pub type fd_t = libc::c_int;
 
 struct Inner {
@@ -52,7 +49,7 @@ impl FileDesc {
         }) }
     }
 
-    pub fn inner_read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
+    pub fn inner_read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         let mut read = 0;
         let ret = unsafe {
             libc::ReadFile(self.handle(), buf.as_ptr() as libc::LPVOID,
@@ -65,7 +62,7 @@ impl FileDesc {
             Err(super::last_error())
         }
     }
-    pub fn inner_write(&mut self, buf: &[u8]) -> Result<(), IoError> {
+    pub fn inner_write(&mut self, buf: &[u8]) -> IoResult<()> {
         let mut cur = buf.as_ptr();
         let mut remaining = buf.len();
         while remaining > 0 {
@@ -93,11 +90,11 @@ impl FileDesc {
 
     // A version of seek that takes &self so that tell can call it
     //   - the private seek should of course take &mut self.
-    fn seek_common(&self, pos: i64, style: io::SeekStyle) -> Result<u64, IoError> {
+    fn seek_common(&self, pos: i64, style: rtio::SeekStyle) -> IoResult<u64> {
         let whence = match style {
-            io::SeekSet => libc::FILE_BEGIN,
-            io::SeekEnd => libc::FILE_END,
-            io::SeekCur => libc::FILE_CURRENT,
+            rtio::SeekSet => libc::FILE_BEGIN,
+            rtio::SeekEnd => libc::FILE_END,
+            rtio::SeekCur => libc::FILE_CURRENT,
         };
         unsafe {
             let mut newpos = 0;
@@ -111,27 +108,15 @@ impl FileDesc {
 
 }
 
-impl io::Reader for FileDesc {
-    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
-        self.inner_read(buf)
-    }
-}
-
-impl io::Writer for FileDesc {
-    fn write(&mut self, buf: &[u8]) -> io::IoResult<()> {
-        self.inner_write(buf)
-    }
-}
-
 impl rtio::RtioFileStream for FileDesc {
-    fn read(&mut self, buf: &mut [u8]) -> Result<int, IoError> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<int> {
         self.inner_read(buf).map(|i| i as int)
     }
-    fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         self.inner_write(buf)
     }
 
-    fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError> {
+    fn pread(&mut self, buf: &mut [u8], offset: u64) -> IoResult<int> {
         let mut read = 0;
         let mut overlap: libc::OVERLAPPED = unsafe { mem::zeroed() };
         overlap.Offset = offset as libc::DWORD;
@@ -147,7 +132,7 @@ impl rtio::RtioFileStream for FileDesc {
             Err(super::last_error())
         }
     }
-    fn pwrite(&mut self, buf: &[u8], mut offset: u64) -> Result<(), IoError> {
+    fn pwrite(&mut self, buf: &[u8], mut offset: u64) -> IoResult<()> {
         let mut cur = buf.as_ptr();
         let mut remaining = buf.len();
         let mut overlap: libc::OVERLAPPED = unsafe { mem::zeroed() };
@@ -171,36 +156,36 @@ impl rtio::RtioFileStream for FileDesc {
         Ok(())
     }
 
-    fn seek(&mut self, pos: i64, style: io::SeekStyle) -> Result<u64, IoError> {
+    fn seek(&mut self, pos: i64, style: rtio::SeekStyle) -> IoResult<u64> {
         self.seek_common(pos, style)
     }
 
-    fn tell(&self) -> Result<u64, IoError> {
-        self.seek_common(0, io::SeekCur)
+    fn tell(&self) -> IoResult<u64> {
+        self.seek_common(0, rtio::SeekCur)
     }
 
-    fn fsync(&mut self) -> Result<(), IoError> {
+    fn fsync(&mut self) -> IoResult<()> {
         super::mkerr_winbool(unsafe {
             libc::FlushFileBuffers(self.handle())
         })
     }
 
-    fn datasync(&mut self) -> Result<(), IoError> { return self.fsync(); }
+    fn datasync(&mut self) -> IoResult<()> { return self.fsync(); }
 
-    fn truncate(&mut self, offset: i64) -> Result<(), IoError> {
+    fn truncate(&mut self, offset: i64) -> IoResult<()> {
         let orig_pos = try!(self.tell());
-        let _ = try!(self.seek(offset, io::SeekSet));
+        let _ = try!(self.seek(offset, rtio::SeekSet));
         let ret = unsafe {
             match libc::SetEndOfFile(self.handle()) {
                 0 => Err(super::last_error()),
                 _ => Ok(())
             }
         };
-        let _ = self.seek(orig_pos as i64, io::SeekSet);
+        let _ = self.seek(orig_pos as i64, rtio::SeekSet);
         return ret;
     }
 
-    fn fstat(&mut self) -> IoResult<io::FileStat> {
+    fn fstat(&mut self) -> IoResult<rtio::FileStat> {
         let mut stat: libc::stat = unsafe { mem::zeroed() };
         match unsafe { libc::fstat(self.fd(), &mut stat) } {
             0 => Ok(mkstat(&stat)),
@@ -210,10 +195,10 @@ impl rtio::RtioFileStream for FileDesc {
 }
 
 impl rtio::RtioPipe for FileDesc {
-    fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         self.inner_read(buf)
     }
-    fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         self.inner_write(buf)
     }
     fn clone(&self) -> Box<rtio::RtioPipe:Send> {
@@ -225,10 +210,10 @@ impl rtio::RtioPipe for FileDesc {
     // std::io::PipeStream. If the functionality is exposed in the future, then
     // these methods will need to be implemented.
     fn close_read(&mut self) -> IoResult<()> {
-        Err(io::standard_error(io::InvalidInput))
+        Err(super::unimpl())
     }
     fn close_write(&mut self) -> IoResult<()> {
-        Err(io::standard_error(io::InvalidInput))
+        Err(super::unimpl())
     }
     fn set_timeout(&mut self, _t: Option<u64>) {}
     fn set_read_timeout(&mut self, _t: Option<u64>) {}
@@ -236,16 +221,16 @@ impl rtio::RtioPipe for FileDesc {
 }
 
 impl rtio::RtioTTY for FileDesc {
-    fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         self.inner_read(buf)
     }
-    fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         self.inner_write(buf)
     }
-    fn set_raw(&mut self, _raw: bool) -> Result<(), IoError> {
+    fn set_raw(&mut self, _raw: bool) -> IoResult<()> {
         Err(super::unimpl())
     }
-    fn get_winsize(&mut self) -> Result<(int, int), IoError> {
+    fn get_winsize(&mut self) -> IoResult<(int, int)> {
         Err(super::unimpl())
     }
     fn isatty(&self) -> bool { false }
@@ -268,24 +253,24 @@ impl Drop for Inner {
     }
 }
 
-pub fn open(path: &CString, fm: io::FileMode, fa: io::FileAccess)
+pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess)
         -> IoResult<FileDesc> {
     // Flags passed to open_osfhandle
     let flags = match fm {
-        io::Open => 0,
-        io::Append => libc::O_APPEND,
-        io::Truncate => libc::O_TRUNC,
+        rtio::Open => 0,
+        rtio::Append => libc::O_APPEND,
+        rtio::Truncate => libc::O_TRUNC,
     };
     let flags = match fa {
-        io::Read => flags | libc::O_RDONLY,
-        io::Write => flags | libc::O_WRONLY | libc::O_CREAT,
-        io::ReadWrite => flags | libc::O_RDWR | libc::O_CREAT,
+        rtio::Read => flags | libc::O_RDONLY,
+        rtio::Write => flags | libc::O_WRONLY | libc::O_CREAT,
+        rtio::ReadWrite => flags | libc::O_RDWR | libc::O_CREAT,
     };
 
     let mut dwDesiredAccess = match fa {
-        io::Read => libc::FILE_GENERIC_READ,
-        io::Write => libc::FILE_GENERIC_WRITE,
-        io::ReadWrite => libc::FILE_GENERIC_READ | libc::FILE_GENERIC_WRITE
+        rtio::Read => libc::FILE_GENERIC_READ,
+        rtio::Write => libc::FILE_GENERIC_WRITE,
+        rtio::ReadWrite => libc::FILE_GENERIC_READ | libc::FILE_GENERIC_WRITE
     };
 
     // libuv has a good comment about this, but the basic idea is what we try to
@@ -295,15 +280,15 @@ pub fn open(path: &CString, fm: io::FileMode, fa: io::FileAccess)
                       libc::FILE_SHARE_DELETE;
 
     let dwCreationDisposition = match (fm, fa) {
-        (io::Truncate, io::Read) => libc::TRUNCATE_EXISTING,
-        (io::Truncate, _) => libc::CREATE_ALWAYS,
-        (io::Open, io::Read) => libc::OPEN_EXISTING,
-        (io::Open, _) => libc::OPEN_ALWAYS,
-        (io::Append, io::Read) => {
+        (rtio::Truncate, rtio::Read) => libc::TRUNCATE_EXISTING,
+        (rtio::Truncate, _) => libc::CREATE_ALWAYS,
+        (rtio::Open, rtio::Read) => libc::OPEN_EXISTING,
+        (rtio::Open, _) => libc::OPEN_ALWAYS,
+        (rtio::Append, rtio::Read) => {
             dwDesiredAccess |= libc::FILE_APPEND_DATA;
             libc::OPEN_EXISTING
         }
-        (io::Append, _) => {
+        (rtio::Append, _) => {
             dwDesiredAccess &= !libc::FILE_WRITE_DATA;
             dwDesiredAccess |= libc::FILE_APPEND_DATA;
             libc::OPEN_ALWAYS
@@ -338,7 +323,7 @@ pub fn open(path: &CString, fm: io::FileMode, fa: io::FileAccess)
     }
 }
 
-pub fn mkdir(p: &CString, _mode: io::FilePermission) -> IoResult<()> {
+pub fn mkdir(p: &CString, _mode: uint) -> IoResult<()> {
     super::mkerr_winbool(unsafe {
         // FIXME: turn mode into something useful? #2623
         as_utf16_p(p.as_str().unwrap(), |buf| {
@@ -413,9 +398,9 @@ pub fn rename(old: &CString, new: &CString) -> IoResult<()> {
     })
 }
 
-pub fn chmod(p: &CString, mode: io::FilePermission) -> IoResult<()> {
+pub fn chmod(p: &CString, mode: uint) -> IoResult<()> {
     super::mkerr_libc(as_utf16_p(p.as_str().unwrap(), |p| unsafe {
-        libc::wchmod(p, mode.bits() as libc::c_int)
+        libc::wchmod(p, mode as libc::c_int)
     }))
 }
 
@@ -430,7 +415,7 @@ pub fn chown(_p: &CString, _uid: int, _gid: int) -> IoResult<()> {
     Ok(())
 }
 
-pub fn readlink(p: &CString) -> IoResult<Path> {
+pub fn readlink(p: &CString) -> IoResult<CString> {
     // FIXME: I have a feeling that this reads intermediate symlinks as well.
     use io::c::compat::kernel32::GetFinalPathNameByHandleW;
     let handle = unsafe {
@@ -457,9 +442,9 @@ pub fn readlink(p: &CString) -> IoResult<Path> {
     });
     let ret = match ret {
         Some(ref s) if s.as_slice().starts_with(r"\\?\") => {
-            Ok(Path::new(s.as_slice().slice_from(4)))
+            Ok(Path::new(s.as_slice().slice_from(4)).to_c_str())
         }
-        Some(s) => Ok(Path::new(s)),
+        Some(s) => Ok(Path::new(s).to_c_str()),
         None => Err(super::last_error()),
     };
     assert!(unsafe { libc::CloseHandle(handle) } != 0);
@@ -483,39 +468,28 @@ pub fn link(src: &CString, dst: &CString) -> IoResult<()> {
     }))
 }
 
-fn mkstat(stat: &libc::stat) -> io::FileStat {
-    let kind = match (stat.st_mode as c_int) & libc::S_IFMT {
-        libc::S_IFREG => io::TypeFile,
-        libc::S_IFDIR => io::TypeDirectory,
-        libc::S_IFIFO => io::TypeNamedPipe,
-        libc::S_IFBLK => io::TypeBlockSpecial,
-        libc::S_IFLNK => io::TypeSymlink,
-        _ => io::TypeUnknown,
-    };
-
-    io::FileStat {
+fn mkstat(stat: &libc::stat) -> rtio::FileStat {
+    rtio::FileStat {
         size: stat.st_size as u64,
-        kind: kind,
-        perm: io::FilePermission::from_bits_truncate(stat.st_mode as u32),
+        kind: stat.st_mode as u64,
+        perm: stat.st_mode as u64,
         created: stat.st_ctime as u64,
         modified: stat.st_mtime as u64,
         accessed: stat.st_atime as u64,
-        unstable: io::UnstableFileStat {
-            device: stat.st_dev as u64,
-            inode: stat.st_ino as u64,
-            rdev: stat.st_rdev as u64,
-            nlink: stat.st_nlink as u64,
-            uid: stat.st_uid as u64,
-            gid: stat.st_gid as u64,
-            blksize: 0,
-            blocks: 0,
-            flags: 0,
-            gen: 0,
-        }
+        device: stat.st_dev as u64,
+        inode: stat.st_ino as u64,
+        rdev: stat.st_rdev as u64,
+        nlink: stat.st_nlink as u64,
+        uid: stat.st_uid as u64,
+        gid: stat.st_gid as u64,
+        blksize: 0,
+        blocks: 0,
+        flags: 0,
+        gen: 0,
     }
 }
 
-pub fn stat(p: &CString) -> IoResult<io::FileStat> {
+pub fn stat(p: &CString) -> IoResult<rtio::FileStat> {
     let mut stat: libc::stat = unsafe { mem::zeroed() };
     as_utf16_p(p.as_str().unwrap(), |up| {
         match unsafe { libc::wstat(up, &mut stat) } {
@@ -525,7 +499,7 @@ pub fn stat(p: &CString) -> IoResult<io::FileStat> {
     })
 }
 
-pub fn lstat(_p: &CString) -> IoResult<io::FileStat> {
+pub fn lstat(_p: &CString) -> IoResult<rtio::FileStat> {
     // FIXME: implementation is missing
     Err(super::unimpl())
 }
diff --git a/src/libnative/io/net.rs b/src/libnative/io/net.rs
index 68cc5273b5e..24956e514ec 100644
--- a/src/libnative/io/net.rs
+++ b/src/libnative/io/net.rs
@@ -135,10 +135,12 @@ pub fn getsockopt<T: Copy>(fd: sock_t, opt: libc::c_int,
 }
 
 #[cfg(windows)]
-fn last_error() -> IoError {
+pub fn last_error() -> IoError {
+    use std::os;
     let code = unsafe { c::WSAGetLastError() as uint };
     IoError {
         code: code,
+        extra: 0,
         detail: Some(os::error_string(code)),
     }
 }
@@ -225,7 +227,7 @@ pub fn init() {}
 pub fn init() {
 
     unsafe {
-        use std::unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
+        use std::rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
         static mut INITIALIZED: bool = false;
         static mut LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
 
diff --git a/src/libnative/io/pipe_win32.rs b/src/libnative/io/pipe_win32.rs
index cd4cbf2c90f..a5694436b97 100644
--- a/src/libnative/io/pipe_win32.rs
+++ b/src/libnative/io/pipe_win32.rs
@@ -87,16 +87,15 @@
 use alloc::arc::Arc;
 use libc;
 use std::c_str::CString;
-use std::io;
 use std::mem;
 use std::os::win32::as_utf16_p;
 use std::os;
 use std::ptr;
 use std::rt::rtio;
+use std::rt::rtio::{IoResult, IoError};
 use std::sync::atomics;
-use std::unstable::mutex;
+use std::rt::mutex;
 
-use super::IoResult;
 use super::c;
 use super::util;
 
@@ -190,6 +189,14 @@ pub fn await(handle: libc::HANDLE, deadline: u64,
     }
 }
 
+fn epipe() -> IoError {
+    IoError {
+        code: libc::ERROR_BROKEN_PIPE as uint,
+        extra: 0,
+        detail: None,
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Unix Streams
 ////////////////////////////////////////////////////////////////////////////////
@@ -355,7 +362,7 @@ impl rtio::RtioPipe for UnixStream {
         // See comments in close_read() about why this lock is necessary.
         let guard = unsafe { self.inner.lock.lock() };
         if self.read_closed() {
-            return Err(io::standard_error(io::EndOfFile))
+            return Err(util::eof())
         }
 
         // Issue a nonblocking requests, succeeding quickly if it happened to
@@ -403,10 +410,10 @@ impl rtio::RtioPipe for UnixStream {
             // If the reading half is now closed, then we're done. If we woke up
             // because the writing half was closed, keep trying.
             if !succeeded {
-                return Err(io::standard_error(io::TimedOut))
+                return Err(util::timeout("read timed out"))
             }
             if self.read_closed() {
-                return Err(io::standard_error(io::EndOfFile))
+                return Err(util::eof())
             }
         }
     }
@@ -431,7 +438,7 @@ impl rtio::RtioPipe for UnixStream {
             // See comments in close_read() about why this lock is necessary.
             let guard = unsafe { self.inner.lock.lock() };
             if self.write_closed() {
-                return Err(io::standard_error(io::BrokenPipe))
+                return Err(epipe())
             }
             let ret = unsafe {
                 libc::WriteFile(self.handle(),
@@ -445,7 +452,11 @@ impl rtio::RtioPipe for UnixStream {
 
             if ret == 0 {
                 if err != libc::ERROR_IO_PENDING as uint {
-                    return Err(io::IoError::from_errno(err, true));
+                    return Err(IoError {
+                        code: err as uint,
+                        extra: 0,
+                        detail: Some(os::error_string(err as uint)),
+                    })
                 }
                 // Process a timeout if one is pending
                 let succeeded = await(self.handle(), self.write_deadline,
@@ -466,17 +477,17 @@ impl rtio::RtioPipe for UnixStream {
                     if !succeeded {
                         let amt = offset + bytes_written as uint;
                         return if amt > 0 {
-                            Err(io::IoError {
-                                kind: io::ShortWrite(amt),
-                                desc: "short write during write",
-                                detail: None,
+                            Err(IoError {
+                                code: libc::ERROR_OPERATION_ABORTED as uint,
+                                extra: amt,
+                                detail: Some("short write during write".to_str()),
                             })
                         } else {
                             Err(util::timeout("write timed out"))
                         }
                     }
                     if self.write_closed() {
-                        return Err(io::standard_error(io::BrokenPipe))
+                        return Err(epipe())
                     }
                     continue // retry
                 }
diff --git a/src/libnative/io/process.rs b/src/libnative/io/process.rs
index 8b3f4debe5d..2c2b7cec1de 100644
--- a/src/libnative/io/process.rs
+++ b/src/libnative/io/process.rs
@@ -210,23 +210,23 @@ unsafe fn killpid(pid: pid_t, signal: int) -> IoResult<()> {
             if ret == 0 {
                 Err(super::last_error())
             } else if status != libc::STILL_ACTIVE {
-                Err(io::IoError {
-                    kind: io::OtherIoError,
-                    desc: "process no longer alive",
+                Err(IoError {
+                    code: libc::ERROR_NOTHING_TO_TERMINATE as uint,
+                    extra: 0,
                     detail: None,
                 })
             } else {
                 Ok(())
             }
         }
-        io::process::PleaseExitSignal | io::process::MustDieSignal => {
+        15 | 9 => { // sigterm or sigkill
             let ret = libc::TerminateProcess(handle, 1);
             super::mkerr_winbool(ret)
         }
-        _ => Err(io::IoError {
-            kind: io::OtherIoError,
-            desc: "unsupported signal on windows",
-            detail: None,
+        _ => Err(IoError {
+            code: libc::ERROR_CALL_NOT_IMPLEMENTED as uint,
+            extra: 0,
+            detail: Some("unsupported signal on windows".to_string()),
         })
     };
     let _ = libc::CloseHandle(handle);
@@ -266,10 +266,10 @@ fn spawn_process_os(cfg: ProcessConfig,
     use std::mem;
 
     if cfg.gid.is_some() || cfg.uid.is_some() {
-        return Err(io::IoError {
-            kind: io::OtherIoError,
-            desc: "unsupported gid/uid requested on windows",
-            detail: None,
+        return Err(IoError {
+            code: libc::ERROR_CALL_NOT_IMPLEMENTED as uint,
+            extra: 0,
+            detail: Some("unsupported gid/uid requested on windows".to_str()),
         })
     }
 
diff --git a/src/libnative/io/timer_win32.rs b/src/libnative/io/timer_win32.rs
index e7130de05c2..d175060dd98 100644
--- a/src/libnative/io/timer_win32.rs
+++ b/src/libnative/io/timer_win32.rs
@@ -23,10 +23,10 @@
 use libc;
 use std::ptr;
 use std::rt::rtio;
+use std::rt::rtio::{IoResult, Callback};
 use std::comm;
 
 use io::helper_thread::Helper;
-use io::IoResult;
 
 helper_init!(static mut HELPER: Helper<Req>)
 
@@ -36,7 +36,7 @@ pub struct Timer {
 }
 
 pub enum Req {
-    NewTimer(libc::HANDLE, Sender<()>, bool),
+    NewTimer(libc::HANDLE, Box<Callback:Send>, bool),
     RemoveTimer(libc::HANDLE, Sender<()>),
 }
 
@@ -79,8 +79,8 @@ fn helper(input: libc::HANDLE, messages: Receiver<Req>, _: ()) {
             }
         } else {
             let remove = {
-                match chans.get(idx as uint - 1) {
-                    &(ref c, oneshot) => c.send_opt(()).is_err() || oneshot
+                match chans.get_mut(idx as uint - 1) {
+                    &(ref mut c, oneshot) => { c.call(); oneshot }
                 }
             };
             if remove {
@@ -148,9 +148,8 @@ impl rtio::RtioTimer for Timer {
         let _ = unsafe { imp::WaitForSingleObject(self.obj, libc::INFINITE) };
     }
 
-    fn oneshot(&mut self, msecs: u64) -> Receiver<()> {
+    fn oneshot(&mut self, msecs: u64, cb: Box<Callback:Send>) {
         self.remove();
-        let (tx, rx) = channel();
 
         // see above for the calculation
         let due = -(msecs as i64 * 10000) as libc::LARGE_INTEGER;
@@ -159,14 +158,12 @@ impl rtio::RtioTimer for Timer {
                                   ptr::mut_null(), 0)
         }, 1);
 
-        unsafe { HELPER.send(NewTimer(self.obj, tx, true)) }
+        unsafe { HELPER.send(NewTimer(self.obj, cb, true)) }
         self.on_worker = true;
-        return rx;
     }
 
-    fn period(&mut self, msecs: u64) -> Receiver<()> {
+    fn period(&mut self, msecs: u64, cb: Box<Callback:Send>) {
         self.remove();
-        let (tx, rx) = channel();
 
         // see above for the calculation
         let due = -(msecs as i64 * 10000) as libc::LARGE_INTEGER;
@@ -175,10 +172,8 @@ impl rtio::RtioTimer for Timer {
                                   ptr::null(), ptr::mut_null(), 0)
         }, 1);
 
-        unsafe { HELPER.send(NewTimer(self.obj, tx, false)) }
+        unsafe { HELPER.send(NewTimer(self.obj, cb, false)) }
         self.on_worker = true;
-
-        return rx;
     }
 }