Subversion Repositories HelenOS-historic

Rev

Rev 1573 | Rev 1591 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1573 Rev 1582
Line 367... Line 367...
367
        IPC_SET_RETVAL(call->data, EHANGUP);
367
        IPC_SET_RETVAL(call->data, EHANGUP);
368
        _ipc_answer_free_call(call);
368
        _ipc_answer_free_call(call);
369
    }
369
    }
370
}
370
}
371
 
371
 
372
/** Cleans up all IPC communication of the given task
372
/** Cleans up all IPC communication of the current task
373
 *
-
 
374
 *
373
 *
-
 
374
 * Note: ipc_hangup sets returning answerbox to TASK->answerbox, you
-
 
375
 * have to change it as well if you want to cleanup other current then current.
375
 */
376
 */
376
void ipc_cleanup(task_t *task)
377
void ipc_cleanup(void)
377
{
378
{
378
    int i;
379
    int i;
379
    call_t *call;
380
    call_t *call;
380
    phone_t *phone;
381
    phone_t *phone;
381
   
382
 
382
    /* Disconnect all our phones ('ipc_phone_hangup') */
383
    /* Disconnect all our phones ('ipc_phone_hangup') */
383
    for (i=0;i < IPC_MAX_PHONES; i++)
384
    for (i=0;i < IPC_MAX_PHONES; i++)
384
        ipc_phone_hangup(&task->phones[i], 1);
385
        ipc_phone_hangup(&TASK->phones[i], 1);
385
 
386
 
386
    /* Disconnect all connected irqs */
387
    /* Disconnect all connected irqs */
387
    ipc_irq_cleanup(&task->answerbox);
388
    ipc_irq_cleanup(&TASK->answerbox);
388
 
389
 
389
    /* Disconnect all phones connected to our answerbox */
390
    /* Disconnect all phones connected to our answerbox */
390
restart_phones:
391
restart_phones:
391
    spinlock_lock(&task->answerbox.lock);
392
    spinlock_lock(&TASK->answerbox.lock);
392
    while (!list_empty(&task->answerbox.connected_phones)) {
393
    while (!list_empty(&TASK->answerbox.connected_phones)) {
393
        phone = list_get_instance(task->answerbox.connected_phones.next,
394
        phone = list_get_instance(TASK->answerbox.connected_phones.next,
394
                      phone_t, link);
395
                      phone_t, link);
395
        if (! spinlock_trylock(&phone->lock)) {
396
        if (! spinlock_trylock(&phone->lock)) {
396
            spinlock_unlock(&task->answerbox.lock);
397
            spinlock_unlock(&TASK->answerbox.lock);
397
            goto restart_phones;
398
            goto restart_phones;
398
        }
399
        }
399
       
400
       
400
        /* Disconnect phone */
401
        /* Disconnect phone */
401
        ASSERT(phone->state == IPC_PHONE_CONNECTED);
402
        ASSERT(phone->state == IPC_PHONE_CONNECTED);
Line 404... Line 405...
404
 
405
 
405
        spinlock_unlock(&phone->lock);
406
        spinlock_unlock(&phone->lock);
406
    }
407
    }
407
 
408
 
408
    /* Answer all messages in 'calls' and 'dispatched_calls' queues */
409
    /* Answer all messages in 'calls' and 'dispatched_calls' queues */
409
    spinlock_lock(&task->answerbox.lock);
-
 
410
    ipc_cleanup_call_list(&task->answerbox.dispatched_calls);
410
    ipc_cleanup_call_list(&TASK->answerbox.dispatched_calls);
411
    ipc_cleanup_call_list(&task->answerbox.calls);
411
    ipc_cleanup_call_list(&TASK->answerbox.calls);
412
    spinlock_unlock(&task->answerbox.lock);
412
    spinlock_unlock(&TASK->answerbox.lock);
413
   
413
   
414
    /* Wait for all async answers to arrive */
414
    /* Wait for all async answers to arrive */
415
    while (1) {
415
    while (1) {
416
        /* Go through all phones, until all are FREE... */
416
        /* Go through all phones, until all are FREE... */
417
        /* Locking not needed, no one else should modify
417
        /* Locking not needed, no one else should modify
418
         * it, when we are in cleanup */
418
         * it, when we are in cleanup */
419
        for (i=0;i < IPC_MAX_PHONES; i++) {
419
        for (i=0;i < IPC_MAX_PHONES; i++) {
420
            if (task->phones[i].state == IPC_PHONE_HUNGUP && \
420
            if (TASK->phones[i].state == IPC_PHONE_HUNGUP && \
421
                atomic_get(&task->phones[i].active_calls) == 0)
421
                atomic_get(&TASK->phones[i].active_calls) == 0)
422
                task->phones[i].state = IPC_PHONE_FREE;
422
                TASK->phones[i].state = IPC_PHONE_FREE;
-
 
423
           
-
 
424
            if (TASK->phones[i].state == IPC_PHONE_CONNECTED)
-
 
425
                ipc_phone_hangup(&TASK->phones[i], 1);
-
 
426
           
423
            if (task->phones[i].state != IPC_PHONE_FREE)
427
            if (TASK->phones[i].state != IPC_PHONE_FREE)
424
                break;
428
                break;
425
        }
429
        }
426
        /* Voila, got into cleanup */
430
        /* Voila, got into cleanup */
427
        if (i == IPC_MAX_PHONES)
431
        if (i == IPC_MAX_PHONES)
428
            break;
432
            break;
429
       
433
       
430
        call = ipc_wait_for_call(&task->answerbox, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
434
        call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
431
        ASSERT((call->flags & IPC_CALL_ANSWERED) || (call->flags & IPC_CALL_NOTIF));
435
        ASSERT((call->flags & IPC_CALL_ANSWERED) || (call->flags & IPC_CALL_NOTIF));
432
        ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
436
        ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
433
       
437
       
434
        atomic_dec(&task->active_calls);
438
        atomic_dec(&TASK->active_calls);
435
        ipc_call_free(call);
439
        ipc_call_free(call);
436
    }
440
    }
437
}
441
}
438
 
442
 
439
 
443