diff --git a/src/librustuv/async.rs b/src/librustuv/async.rs
index c75f84de01e..dcbd0baf6f3 100644
--- a/src/librustuv/async.rs
+++ b/src/librustuv/async.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use std::cast;
-use libc::c_int;
 use std::rt::rtio::{Callback, RemoteCallback};
 use std::unstable::sync::Exclusive;
 
@@ -54,8 +53,7 @@ impl UvHandle<uvll::uv_async_t> for AsyncWatcher {
     }
 }
 
-extern fn async_cb(handle: *uvll::uv_async_t, status: c_int) {
-    assert!(status == 0);
+extern fn async_cb(handle: *uvll::uv_async_t) {
     let payload: &mut Payload = unsafe {
         cast::transmute(uvll::get_data_for_uv_handle(handle))
     };
diff --git a/src/librustuv/file.rs b/src/librustuv/file.rs
index cde5cfa97c1..665d418ab2a 100644
--- a/src/librustuv/file.rs
+++ b/src/librustuv/file.rs
@@ -12,7 +12,7 @@ use std::c_str::CString;
 use std::c_str;
 use std::cast::transmute;
 use std::cast;
-use libc::{c_int, c_char, c_void, size_t, ssize_t};
+use libc::{c_int, c_char, c_void, ssize_t};
 use libc;
 use std::rt::task::BlockedTask;
 use std::io::{FileStat, IoError};
@@ -86,14 +86,12 @@ impl FsRequest {
             } else {
                 offset + written as i64
             };
+            let uvbuf = uvll::uv_buf_t {
+                base: buf.slice_from(written as uint).as_ptr(),
+                len: (buf.len() - written) as uvll::uv_buf_len_t,
+            };
             match execute(|req, cb| unsafe {
-                uvll::uv_fs_write(loop_.handle,
-                                  req,
-                                  fd,
-                                  buf.as_ptr().offset(written as int) as *c_void,
-                                  (buf.len() - written) as size_t,
-                                  offset,
-                                  cb)
+                uvll::uv_fs_write(loop_.handle, req, fd, &uvbuf, 1, offset, cb)
             }).map(|req| req.get_result()) {
                 Err(e) => return Err(e),
                 Ok(n) => { written += n as uint; }
@@ -106,9 +104,11 @@ impl FsRequest {
         -> Result<int, UvError>
     {
         execute(|req, cb| unsafe {
-            uvll::uv_fs_read(loop_.handle, req,
-                             fd, buf.as_ptr() as *c_void,
-                             buf.len() as size_t, offset, cb)
+            let uvbuf = uvll::uv_buf_t {
+                base: buf.as_ptr(),
+                len: buf.len() as uvll::uv_buf_len_t,
+            };
+            uvll::uv_fs_read(loop_.handle, req, fd, &uvbuf, 1, offset, cb)
         }).map(|req| {
             req.get_result() as int
         })
diff --git a/src/librustuv/idle.rs b/src/librustuv/idle.rs
index 0de6e479a8f..4d7da29aa9a 100644
--- a/src/librustuv/idle.rs
+++ b/src/librustuv/idle.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use std::cast;
-use libc::{c_int, c_void};
+use libc::c_void;
 
 use uvll;
 use super::{Loop, UvHandle};
@@ -46,8 +46,7 @@ impl IdleWatcher {
             assert_eq!(uvll::uv_idle_start(handle, onetime_cb), 0)
         }
 
-        extern fn onetime_cb(handle: *uvll::uv_idle_t, status: c_int) {
-            assert_eq!(status, 0);
+        extern fn onetime_cb(handle: *uvll::uv_idle_t) {
             unsafe {
                 let data = uvll::get_data_for_uv_handle(handle);
                 let f: ~proc() = cast::transmute(data);
@@ -82,8 +81,7 @@ impl UvHandle<uvll::uv_idle_t> for IdleWatcher {
     fn uv_handle(&self) -> *uvll::uv_idle_t { self.handle }
 }
 
-extern fn idle_cb(handle: *uvll::uv_idle_t, status: c_int) {
-    assert_eq!(status, 0);
+extern fn idle_cb(handle: *uvll::uv_idle_t) {
     let idle: &mut IdleWatcher = unsafe { UvHandle::from_uv_handle(&handle) };
     idle.callback.call();
 }
diff --git a/src/librustuv/net.rs b/src/librustuv/net.rs
index f8df9263be1..27a06911939 100644
--- a/src/librustuv/net.rs
+++ b/src/librustuv/net.rs
@@ -255,10 +255,9 @@ impl TcpWatcher {
             n => Err(UvError(n))
         };
 
-        extern fn timer_cb(handle: *uvll::uv_timer_t, status: c_int) {
+        extern fn timer_cb(handle: *uvll::uv_timer_t) {
             // Don't close the corresponding tcp request, just wake up the task
             // and let RAII take care of the pending watcher.
-            assert_eq!(status, 0);
             let cx: &mut Ctx = unsafe {
                 &mut *(uvll::get_data_for_uv_handle(handle) as *mut Ctx)
             };
@@ -599,8 +598,7 @@ impl rtio::RtioTcpAcceptor for TcpAcceptor {
         self.timeout_tx = Some(tx);
         self.timeout_rx = Some(rx);
 
-        extern fn timer_cb(timer: *uvll::uv_timer_t, status: c_int) {
-            assert_eq!(status, 0);
+        extern fn timer_cb(timer: *uvll::uv_timer_t) {
             let acceptor: &mut TcpAcceptor = unsafe {
                 &mut *(uvll::get_data_for_uv_handle(timer) as *mut TcpAcceptor)
             };
diff --git a/src/librustuv/queue.rs b/src/librustuv/queue.rs
index b6c7fbda8c8..9e75991434f 100644
--- a/src/librustuv/queue.rs
+++ b/src/librustuv/queue.rs
@@ -21,7 +21,7 @@
 #![allow(dead_code)]
 
 use std::cast;
-use libc::{c_void, c_int};
+use libc::c_void;
 use std::rt::task::BlockedTask;
 use std::unstable::mutex::NativeMutex;
 use std::sync::arc::UnsafeArc;
@@ -55,8 +55,7 @@ pub struct Queue {
     queue: UnsafeArc<State>,
 }
 
-extern fn async_cb(handle: *uvll::uv_async_t, status: c_int) {
-    assert_eq!(status, 0);
+extern fn async_cb(handle: *uvll::uv_async_t) {
     let pool: &mut QueuePool = unsafe {
         cast::transmute(uvll::get_data_for_uv_handle(handle))
     };
diff --git a/src/librustuv/timer.rs b/src/librustuv/timer.rs
index 65ab32c6965..5c34fd8cc12 100644
--- a/src/librustuv/timer.rs
+++ b/src/librustuv/timer.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use libc::c_int;
 use std::mem;
 use std::rt::rtio::RtioTimer;
 use std::rt::task::BlockedTask;
@@ -137,9 +136,8 @@ impl RtioTimer for TimerWatcher {
     }
 }
 
-extern fn timer_cb(handle: *uvll::uv_timer_t, status: c_int) {
+extern fn timer_cb(handle: *uvll::uv_timer_t) {
     let _f = ForbidSwitch::new("timer callback can't switch");
-    assert_eq!(status, 0);
     let timer: &mut TimerWatcher = unsafe { UvHandle::from_uv_handle(&handle) };
 
     match timer.action.take_unwrap() {
diff --git a/src/librustuv/tty.rs b/src/librustuv/tty.rs
index 95ecaa09a43..4f3e12b6974 100644
--- a/src/librustuv/tty.rs
+++ b/src/librustuv/tty.rs
@@ -40,7 +40,7 @@ impl TtyWatcher {
         // - https://github.com/joyent/libuv/issues/982
         // - https://github.com/joyent/libuv/issues/988
         let guess = unsafe { uvll::guess_handle(fd) };
-        if readable && guess != uvll::UV_TTY as libc::c_int {
+        if guess != uvll::UV_TTY as libc::c_int {
             return Err(UvError(uvll::EBADF));
         }
 
diff --git a/src/librustuv/uvio.rs b/src/librustuv/uvio.rs
index 3769a1b8d6d..3127a01d70e 100644
--- a/src/librustuv/uvio.rs
+++ b/src/librustuv/uvio.rs
@@ -23,7 +23,7 @@ use libc::{O_CREAT, O_APPEND, O_TRUNC, O_RDWR, O_RDONLY, O_WRONLY, S_IRUSR,
 use libc;
 use std::path::Path;
 use std::rt::rtio;
-use std::rt::rtio::IoFactory;
+use std::rt::rtio::{IoFactory, EventLoop};
 use ai = std::io::net::addrinfo;
 
 #[cfg(test)] use std::unstable::run_in_bare_thread;
@@ -69,14 +69,20 @@ impl Drop for UvEventLoop {
         // the loop is free'd (use-after-free). We also must free the uv handle
         // after the loop has been closed because during the closing of the loop
         // the handle is required to be used apparently.
+        //
+        // Lastly, after we've closed the pool of handles we pump the event loop
+        // one last time to run any closing callbacks to make sure the loop
+        // shuts down cleanly.
         let handle = self.uvio.handle_pool.get_ref().handle();
         drop(self.uvio.handle_pool.take());
+        self.run();
+
         self.uvio.loop_.close();
         unsafe { uvll::free_handle(handle) }
     }
 }
 
-impl rtio::EventLoop for UvEventLoop {
+impl EventLoop for UvEventLoop {
     fn run(&mut self) {
         self.uvio.loop_.run();
     }
@@ -110,7 +116,6 @@ impl rtio::EventLoop for UvEventLoop {
 
 #[test]
 fn test_callback_run_once() {
-    use std::rt::rtio::EventLoop;
     run_in_bare_thread(proc() {
         let mut event_loop = UvEventLoop::new();
         let mut count = 0;
diff --git a/src/librustuv/uvll.rs b/src/librustuv/uvll.rs
index 04bc53004d0..57f4bd9d7eb 100644
--- a/src/librustuv/uvll.rs
+++ b/src/librustuv/uvll.rs
@@ -212,8 +212,7 @@ impl uv_stat_t {
     }
 }
 
-pub type uv_idle_cb = extern "C" fn(handle: *uv_idle_t,
-                                    status: c_int);
+pub type uv_idle_cb = extern "C" fn(handle: *uv_idle_t);
 pub type uv_alloc_cb = extern "C" fn(stream: *uv_stream_t,
                                      suggested_size: size_t,
                                      buf: *mut uv_buf_t);
@@ -230,14 +229,12 @@ pub type uv_udp_recv_cb = extern "C" fn(handle: *uv_udp_t,
 pub type uv_close_cb = extern "C" fn(handle: *uv_handle_t);
 pub type uv_walk_cb = extern "C" fn(handle: *uv_handle_t,
                                     arg: *c_void);
-pub type uv_async_cb = extern "C" fn(handle: *uv_async_t,
-                                     status: c_int);
+pub type uv_async_cb = extern "C" fn(handle: *uv_async_t);
 pub type uv_connect_cb = extern "C" fn(handle: *uv_connect_t,
                                        status: c_int);
 pub type uv_connection_cb = extern "C" fn(handle: *uv_connection_t,
                                           status: c_int);
-pub type uv_timer_cb = extern "C" fn(handle: *uv_timer_t,
-                                     status: c_int);
+pub type uv_timer_cb = extern "C" fn(handle: *uv_timer_t);
 pub type uv_write_cb = extern "C" fn(handle: *uv_write_t,
                                      status: c_int);
 pub type uv_getaddrinfo_cb = extern "C" fn(req: *uv_getaddrinfo_t,
@@ -597,10 +594,12 @@ extern {
                       flags: c_int, mode: c_int, cb: uv_fs_cb) -> c_int;
     pub fn uv_fs_unlink(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char,
                         cb: uv_fs_cb) -> c_int;
-    pub fn uv_fs_write(l: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void,
-                       len: size_t, offset: i64, cb: uv_fs_cb) -> c_int;
-    pub fn uv_fs_read(l: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void,
-                      len: size_t, offset: i64, cb: uv_fs_cb) -> c_int;
+    pub fn uv_fs_write(l: *uv_loop_t, req: *uv_fs_t, fd: c_int,
+                       bufs: *uv_buf_t, nbufs: c_uint,
+                       offset: i64, cb: uv_fs_cb) -> c_int;
+    pub fn uv_fs_read(l: *uv_loop_t, req: *uv_fs_t, fd: c_int,
+                      bufs: *uv_buf_t, nbufs: c_uint,
+                      offset: i64, cb: uv_fs_cb) -> c_int;
     pub fn uv_fs_close(l: *uv_loop_t, req: *uv_fs_t, fd: c_int,
                        cb: uv_fs_cb) -> c_int;
     pub fn uv_fs_stat(l: *uv_loop_t, req: *uv_fs_t, path: *c_char,
diff --git a/src/libstd/hash/sip.rs b/src/libstd/hash/sip.rs
index 794c4ee62ff..eae13735809 100644
--- a/src/libstd/hash/sip.rs
+++ b/src/libstd/hash/sip.rs
@@ -364,7 +364,7 @@ mod tests {
     use option::{Some, None};
     use str::{Str,StrSlice};
     use strbuf::StrBuf;
-    use slice::{Vector, ImmutableVector, OwnedVector};
+    use slice::{Vector, ImmutableVector};
     use self::test::Bencher;
 
     use super::super::Hash;
diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs
index 8b9b8a7498b..824d9e5ec92 100644
--- a/src/libstd/rt/args.rs
+++ b/src/libstd/rt/args.rs
@@ -67,9 +67,9 @@ mod imp {
     use clone::Clone;
     use option::{Option, Some, None};
     use iter::Iterator;
-    use str::StrSlice;
     use unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
     use mem;
+    #[cfg(not(test))] use str::StrSlice;
     #[cfg(not(test))] use ptr::RawPtr;
 
     static mut global_args_ptr: uint = 0;
diff --git a/src/libuv b/src/libuv
index 800b56fe6af..43495892ded 160000
--- a/src/libuv
+++ b/src/libuv
@@ -1 +1 @@
-Subproject commit 800b56fe6af21ffd8e56aee8cf12dd758f5bbdf1
+Subproject commit 43495892ded622de51eba7362c5ffae1ed50c9cc
diff --git a/src/rt/libuv-auto-clean-trigger b/src/rt/libuv-auto-clean-trigger
index 961455b9093..8bd7aa54751 100644
--- a/src/rt/libuv-auto-clean-trigger
+++ b/src/rt/libuv-auto-clean-trigger
@@ -1,2 +1,2 @@
 # Change the contents of this file to force a full rebuild of libuv
-2014-02-16
+2014-04-18