Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1581 → Rev 1582

/kernel/trunk/generic/include/ipc/ipc.h
224,7 → 224,7
extern void ipc_call_static_init(call_t *call);
extern void task_print_list(void);
extern int ipc_forward(call_t *call, phone_t *newphone, answerbox_t *oldbox);
extern void ipc_cleanup(task_t *task);
void ipc_cleanup(void);
extern int ipc_phone_hangup(phone_t *phone, int aggressive);
extern void ipc_backsend_err(phone_t *phone, call_t *call, __native err);
extern void ipc_print_task(task_id_t taskid);
/kernel/trunk/generic/src/console/cmd.c
308,7 → 308,7
};
static cmd_info_t ipc_task_info = {
.name = "ipc_task",
.description = "Show memory zone structure.",
.description = "ipc_task <taskid> Show IPC information of given task",
.func = cmd_ipc_task,
.argc = 1,
.argv = &ipc_task_argv
/kernel/trunk/generic/src/ipc/ipc.c
369,31 → 369,32
}
}
 
/** Cleans up all IPC communication of the given task
/** Cleans up all IPC communication of the current task
*
*
* Note: ipc_hangup sets returning answerbox to TASK->answerbox, you
* have to change it as well if you want to cleanup other current then current.
*/
void ipc_cleanup(task_t *task)
void ipc_cleanup(void)
{
int i;
call_t *call;
phone_t *phone;
 
/* Disconnect all our phones ('ipc_phone_hangup') */
for (i=0;i < IPC_MAX_PHONES; i++)
ipc_phone_hangup(&task->phones[i], 1);
ipc_phone_hangup(&TASK->phones[i], 1);
 
/* Disconnect all connected irqs */
ipc_irq_cleanup(&task->answerbox);
ipc_irq_cleanup(&TASK->answerbox);
 
/* Disconnect all phones connected to our answerbox */
restart_phones:
spinlock_lock(&task->answerbox.lock);
while (!list_empty(&task->answerbox.connected_phones)) {
phone = list_get_instance(task->answerbox.connected_phones.next,
spinlock_lock(&TASK->answerbox.lock);
while (!list_empty(&TASK->answerbox.connected_phones)) {
phone = list_get_instance(TASK->answerbox.connected_phones.next,
phone_t, link);
if (! spinlock_trylock(&phone->lock)) {
spinlock_unlock(&task->answerbox.lock);
spinlock_unlock(&TASK->answerbox.lock);
goto restart_phones;
}
406,10 → 407,9
}
 
/* Answer all messages in 'calls' and 'dispatched_calls' queues */
spinlock_lock(&task->answerbox.lock);
ipc_cleanup_call_list(&task->answerbox.dispatched_calls);
ipc_cleanup_call_list(&task->answerbox.calls);
spinlock_unlock(&task->answerbox.lock);
ipc_cleanup_call_list(&TASK->answerbox.dispatched_calls);
ipc_cleanup_call_list(&TASK->answerbox.calls);
spinlock_unlock(&TASK->answerbox.lock);
/* Wait for all async answers to arrive */
while (1) {
417,10 → 417,14
/* Locking not needed, no one else should modify
* it, when we are in cleanup */
for (i=0;i < IPC_MAX_PHONES; i++) {
if (task->phones[i].state == IPC_PHONE_HUNGUP && \
atomic_get(&task->phones[i].active_calls) == 0)
task->phones[i].state = IPC_PHONE_FREE;
if (task->phones[i].state != IPC_PHONE_FREE)
if (TASK->phones[i].state == IPC_PHONE_HUNGUP && \
atomic_get(&TASK->phones[i].active_calls) == 0)
TASK->phones[i].state = IPC_PHONE_FREE;
if (TASK->phones[i].state == IPC_PHONE_CONNECTED)
ipc_phone_hangup(&TASK->phones[i], 1);
if (TASK->phones[i].state != IPC_PHONE_FREE)
break;
}
/* Voila, got into cleanup */
427,11 → 431,11
if (i == IPC_MAX_PHONES)
break;
call = ipc_wait_for_call(&task->answerbox, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
ASSERT((call->flags & IPC_CALL_ANSWERED) || (call->flags & IPC_CALL_NOTIF));
ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
atomic_dec(&task->active_calls);
atomic_dec(&TASK->active_calls);
ipc_call_free(call);
}
}