Changeset ca687ad in mainline for generic/src/ipc/ipc.c


Ignore:
Timestamp:
2006-03-31T13:53:36Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0cb56f5d
Parents:
296cc1b
Message:

Completed ipc_cleanup, it should be somehow integrated into
cleanup of task. The function can sleep.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • generic/src/ipc/ipc.c

    r296cc1b rca687ad  
    323323                list_append(&request->list, &box->dispatched_calls);
    324324        } else {
     325                /* This can happen regularly after ipc_cleanup, remove
     326                 * the warning in the future when the IPC is
     327                 * more debugged */
    325328                printf("WARNING: Spurious IPC wakeup.\n");
    326329                spinlock_unlock(&box->lock);
     
    340343}
    341344
     345/** Answer all calls from list with EHANGUP msg */
     346static void ipc_cleanup_call_list(link_t *lst)
     347{
     348        call_t *call;
     349
     350        while (!list_empty(lst)) {
     351                call = list_get_instance(lst->next, call_t, list);
     352                list_remove(&call->list);
     353
     354                IPC_SET_RETVAL(call->data, EHANGUP);
     355                _ipc_answer_free_call(call);
     356        }
     357}
     358
    342359/** Cleans up all IPC communication of the given task
    343360 *
     
    347364{
    348365        int i;
    349 
     366        call_t *call;
     367        phone_t *phone;
     368       
    350369        /* Disconnect all our phones ('ipc_phone_hangup') */
    351370        for (i=0;i < IPC_MAX_PHONES; i++)
    352371                ipc_phone_hangup(&task->phones[i]);
    353372
    354         /* Disconnect all phones connected to answerbox */
     373        /* Disconnect all phones connected to our answerbox */
     374restart_phones:
     375        spinlock_lock(&task->answerbox.lock);
     376        while (!list_empty(&task->answerbox.connected_phones)) {
     377                phone = list_get_instance(task->answerbox.connected_phones.next,
     378                                          phone_t,
     379                                          list);
     380                if (! spinlock_trylock(&phone->lock)) {
     381                        spinlock_unlock(&task->answerbox.lock);
     382                        goto restart_phones;
     383                }
     384               
     385                /* Disconnect phone */
     386                phone->callee = NULL;
     387                list_remove(&phone->list);
     388
     389                spinlock_unlock(&phone->lock);
     390        }
    355391
    356392        /* Answer all messages in 'calls' and 'dispatched_calls' queues */
     393        spinlock_lock(&task->answerbox.lock);
     394        ipc_cleanup_call_list(&task->answerbox.dispatched_calls);
     395        ipc_cleanup_call_list(&task->answerbox.calls);
     396        spinlock_unlock(&task->answerbox.lock);
    357397       
    358398        /* Wait for all async answers to arrive */
    359 }
     399        while (atomic_get(&task->active_calls)) {
     400                call = ipc_wait_for_call(&task->answerbox, 0);
     401                ASSERT(call->flags & IPC_CALL_ANSWERED);
     402                ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
     403               
     404                atomic_dec(&task->active_calls);
     405                ipc_call_free(call);
     406        }
     407}
Note: See TracChangeset for help on using the changeset viewer.