diff options
author | Flávio Cruz <flaviocruz@gmail.com> | 2015-08-28 01:34:01 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2015-08-28 01:37:51 +0200 |
commit | 2c1cccc529737527ad9ef981952d2c14d3dd13ec (patch) | |
tree | d39bfb7d7ed794c8bbb092f3245fe5b0522460da /kern/exception.c | |
parent | eec39c5f50fb1b4e2025025773f77293f3466492 (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.c | 32 |
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); |