45,6 → 45,7 |
|
void ipc_kbox_cleanup(void) |
{ |
ipl_t ipl; |
bool have_kb_thread; |
|
/* Only hold kb_cleanup_lock while setting kb_finished - this is enough */ |
64,6 → 65,17 |
*/ |
ipc_answerbox_slam_phones(&TASK->kernel_box, have_kb_thread); |
|
/* |
* If the task was being debugged, clean up debugging session. |
* This is necessarry as slamming the phones won't force |
* kbox thread to clean it up since sender != debugger. |
*/ |
ipl = interrupts_disable(); |
spinlock_lock(&TASK->lock); |
udebug_task_cleanup(TASK); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
|
if (have_kb_thread) { |
LOG("join kb_thread..\n"); |
thread_join(TASK->kb_thread); |
79,32 → 91,18 |
spinlock_unlock(&TASK->kernel_box.lock); |
} |
|
|
static void kbox_thread_proc(void *arg) |
/** Handle hangup message in kbox. |
* |
* @param call The IPC_M_PHONE_HUNGUP call structure. |
* @param last Output, the function stores @c true here if |
* this was the last phone, @c false otherwise. |
**/ |
static void kbox_proc_phone_hungup(call_t *call, bool *last) |
{ |
call_t *call; |
int method; |
bool done; |
ipl_t ipl; |
|
(void)arg; |
LOG("kbox_thread_proc()\n"); |
done = false; |
LOG("kbox_proc_phone_hungup()\n"); |
|
while (!done) { |
call = ipc_wait_for_call(&TASK->kernel_box, SYNCH_NO_TIMEOUT, |
SYNCH_FLAGS_NONE); |
|
if (call != NULL) { |
method = IPC_GET_METHOD(call->data); |
|
if (method == IPC_M_DEBUG_ALL) { |
udebug_call_receive(call); |
} |
|
if (method == IPC_M_PHONE_HUNGUP) { |
LOG("kbox: handle hangup message\n"); |
|
/* Was it our debugger, who hung up? */ |
if (call->sender == TASK->udebug.debugger) { |
/* Terminate debugging session (if any) */ |
126,15 → 124,73 |
spinlock_lock(&TASK->lock); |
spinlock_lock(&TASK->answerbox.lock); |
if (list_empty(&TASK->answerbox.connected_phones)) { |
/* Last phone has been disconnected */ |
/* |
* Last phone has been disconnected. Detach this thread so it |
* gets freed and signal to the caller. |
*/ |
|
/* Only detach kbox thread unless already terminating. */ |
mutex_lock(&TASK->kb_cleanup_lock); |
if (&TASK->kb_finished == false) { |
/* Detach kbox thread so it gets freed from memory. */ |
thread_detach(TASK->kb_thread); |
TASK->kb_thread = NULL; |
done = true; |
} |
mutex_unlock(&TASK->kb_cleanup_lock); |
|
LOG("phone list is empty\n"); |
*last = true; |
} else { |
*last = false; |
} |
|
spinlock_unlock(&TASK->answerbox.lock); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
} |
|
/** Implementing function for the kbox thread. |
* |
* This function listens for debug requests. It terminates |
* when all phones are disconnected from the kbox. |
* |
* @param arg Ignored. |
*/ |
static void kbox_thread_proc(void *arg) |
{ |
call_t *call; |
bool done; |
|
(void)arg; |
LOG("kbox_thread_proc()\n"); |
done = false; |
|
while (!done) { |
call = ipc_wait_for_call(&TASK->kernel_box, SYNCH_NO_TIMEOUT, |
SYNCH_FLAGS_NONE); |
|
if (call == NULL) |
continue; /* Try again. */ |
|
switch (IPC_GET_METHOD(call->data)) { |
|
case IPC_M_DEBUG_ALL: |
/* Handle debug call. */ |
udebug_call_receive(call); |
break; |
|
case IPC_M_PHONE_HUNGUP: |
/* |
* Process the hangup call. If this was the last |
* phone, done will be set to true and the |
* while loop will terminate. |
*/ |
kbox_proc_phone_hungup(call, &done); |
break; |
|
default: |
/* Ignore */ |
break; |
} |
} |
|