From 3d9023fa4ddc8dbb5d9be0e4e4ef5c284c6b077a Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 11 Nov 2011 15:34:35 -0800 Subject: rt: Take the task lock when dropping port refcounts Sucks, but otherwise there are races when one task drops the refcount to zero followed by another bumping it again --- src/rt/rust_task.cpp | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) (limited to 'src/rt/rust_task.cpp') diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 5164f6ac181..e5d43e7b308 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -127,15 +127,20 @@ rust_task::~rust_task() name, (uintptr_t)this, ref_count); if(user.notify_enabled) { - rust_port *target = - get_port_by_chan_handle(&user.notify_chan); - if(target) { - task_notification msg; - msg.id = user.id; - msg.result = failed ? tr_failure : tr_success; - - target->send(&msg); - target->deref(); + rust_task *target_task = kernel->get_task_by_id(user.notify_chan.task); + if (target_task) { + rust_port *target_port = + target_task->get_port_by_id(user.notify_chan.port); + if(target_port) { + task_notification msg; + msg.id = user.id; + msg.result = failed ? tr_failure : tr_success; + + target_port->send(&msg); + scoped_lock with(target_task->lock); + target_port->deref(); + } + target_task->deref(); } } @@ -553,8 +558,7 @@ rust_port_id rust_task::register_port(rust_port *port) { } void rust_task::release_port(rust_port_id id) { - I(sched, !lock.lock_held_by_current_thread()); - scoped_lock with(lock); + I(sched, lock.lock_held_by_current_thread()); port_table.remove(id); } @@ -569,15 +573,6 @@ rust_port *rust_task::get_port_by_id(rust_port_id id) { return port; } -rust_port *rust_task::get_port_by_chan_handle(chan_handle *handle) { - rust_task *target_task = kernel->get_task_by_id(handle->task); - if(target_task) { - rust_port *port = target_task->get_port_by_id(handle->port); - target_task->deref(); - return port; - } - return NULL; -} // Temporary routine to allow boxes on one task's shared heap to be reparented // to another. -- cgit 1.4.1-3-g733a5