summaryrefslogtreecommitdiff
path: root/kern/exception.c
diff options
context:
space:
mode:
authorFlávio Cruz <flaviocruz@gmail.com>2015-08-28 01:34:01 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2015-08-28 01:37:51 +0200
commit2c1cccc529737527ad9ef981952d2c14d3dd13ec (patch)
treed39bfb7d7ed794c8bbb092f3245fe5b0522460da /kern/exception.c
parenteec39c5f50fb1b4e2025025773f77293f3466492 (diff)
Make sure the reply port's reference is released when the thread needs to be halted.
* kern/thread.h (thread_halt_self): Add continuation_t parameter. * kern/thread.c (thread_halt_self): Pass continuation_t parameter to thread_block instead of thread_exception_return. * kern/ast.c (ast_taken): Pass thread_exception_return to thread_halt_self. * kern/profile.c (profile_thread): Likewise. * kern/exception.c (exception_no_server): Likewise. (thread_release_and_exception_return): New function. (exception_raise_continue_slow): Pass thread_release_and_exception_return to thread_halt_self.
Diffstat (limited to 'kern/exception.c')
-rw-r--r--kern/exception.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/kern/exception.c b/kern/exception.c
index 6cb3bfb..63a63d6 100644
--- a/kern/exception.c
+++ b/kern/exception.c
@@ -231,7 +231,7 @@ exception_no_server(void)
*/
while (thread_should_halt(self))
- thread_halt_self();
+ thread_halt_self(thread_exception_return);
#if 0
@@ -257,7 +257,7 @@ exception_no_server(void)
*/
(void) task_terminate(self->task);
- thread_halt_self();
+ thread_halt_self(thread_exception_return);
panic("terminating the task didn't kill us");
/*NOTREACHED*/
}
@@ -848,6 +848,26 @@ exception_raise_continue(void)
}
/*
+ * Routine: thread_release_and_exception_return
+ * Purpose:
+ * Continue after thread was halted.
+ * Conditions:
+ * Nothing locked. We are running on a new kernel stack and
+ * control goes back to thread_exception_return.
+ * Returns:
+ * Doesn't return.
+ */
+static void
+thread_release_and_exception_return(void)
+{
+ ipc_thread_t self = current_thread();
+ /* reply port must be released */
+ ipc_port_release(self->ith_port);
+ thread_exception_return();
+ /*NOTREACHED*/
+}
+
+/*
* Routine: exception_raise_continue_slow
* Purpose:
* Continue after finishing an ipc_mqueue_receive
@@ -876,10 +896,14 @@ exception_raise_continue_slow(
*/
while (thread_should_halt(self)) {
- /* don't terminate while holding a reference */
+ /* if thread is about to terminate, release the port */
if (self->ast & AST_TERMINATE)
ipc_port_release(reply_port);
- thread_halt_self();
+ /*
+ * Use the continuation to release the port in
+ * case the thread is about to halt.
+ */
+ thread_halt_self(thread_release_and_exception_return);
}
ip_lock(reply_port);