rustuv: Fix a use-after-free bug

The queue has an async handle which must be destroyed before the loop is
destroyed, so use a little bit of an option dance to get around this
requirement.
This commit is contained in:
Alex Crichton 2013-12-15 00:56:29 -08:00
parent 51c03c1f35
commit e121d7556c

View File

@ -57,7 +57,7 @@ pub fn new() -> UvEventLoop {
UvEventLoop {
uvio: UvIoFactory {
loop_: loop_,
handle_pool: handle_pool,
handle_pool: Some(handle_pool),
}
}
}
@ -65,6 +65,10 @@ pub fn new() -> UvEventLoop {
impl Drop for UvEventLoop {
fn drop(&mut self) {
// Must first destroy the pool of handles before we destroy the loop
// because otherwise the contained async handle will be destroyed after
// the loop is free'd (use-after-free)
self.uvio.handle_pool.take();
self.uvio.loop_.close();
}
}
@ -117,14 +121,14 @@ fn test_callback_run_once() {
pub struct UvIoFactory {
loop_: Loop,
priv handle_pool: ~QueuePool,
priv handle_pool: Option<~QueuePool>,
}
impl UvIoFactory {
pub fn uv_loop<'a>(&mut self) -> *uvll::uv_loop_t { self.loop_.handle }
pub fn make_handle(&mut self) -> HomeHandle {
HomeHandle::new(self.id(), &mut *self.handle_pool)
HomeHandle::new(self.id(), &mut **self.handle_pool.get_mut_ref())
}
}