Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 33adc6ce in mainline


Ignore:
Timestamp:
2009-11-21T10:26:29Z (12 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master
Children:
fd1210a
Parents:
c70ce74
Message:

Introduce the per-task list of active synchronous answerboxes and make
ipc_cleanup() aware of it.

Location:
kernel/generic
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/ipc/ipc.h

    rc70ce74 r33adc6ce  
    264264
    265265        waitq_t wq;
     266
     267        /** Linkage for the list of task's synchronous answerboxes. */
     268        link_t sync_box_link;
    266269
    267270        /** Phones connected to this answerbox. */
  • kernel/generic/include/proc/task.h

    rc70ce74 r33adc6ce  
    9898         */
    9999        atomic_t active_calls;
     100        /** List of synchronous answerboxes. */
     101        link_t sync_box_head;
    100102
    101103#ifdef CONFIG_UDEBUG
  • kernel/generic/src/ipc/ipc.c

    rc70ce74 r33adc6ce  
    119119        spinlock_initialize(&box->irq_lock, "ipc_box_irqlock");
    120120        waitq_initialize(&box->wq);
     121        link_initialize(&box->sync_box_link);
    121122        list_initialize(&box->connected_phones);
    122123        list_initialize(&box->calls);
     
    169170{
    170171        answerbox_t *sync_box;
     172        ipl_t ipl;
    171173
    172174        sync_box = slab_alloc(ipc_answerbox_slab, 0);
    173175        ipc_answerbox_init(sync_box, TASK);
     176
     177        /*
     178         * Put the answerbox on the TASK's list of synchronous answerboxes so
     179         * that it can be cleaned up if the call is interrupted.
     180         */
     181        ipl = interrupts_disable();
     182        spinlock_lock(&TASK->lock);
     183        list_append(&sync_box->sync_box_link, &TASK->sync_box_head);
     184        spinlock_unlock(&TASK->lock);
     185        interrupts_restore(ipl);
    174186
    175187        /* We will receive data in a special box. */
     
    179191        if (!ipc_wait_for_call(sync_box, SYNCH_NO_TIMEOUT,
    180192            SYNCH_FLAGS_INTERRUPTIBLE)) {
    181                 /* The asnwerbox will be freed by someone else. */
     193                /* The answerbox and the call will be freed by ipc_cleanup(). */
    182194                return EINTR;
    183195        }
     196
     197        /*
     198         * The answer arrived without interruption so we can remove the
     199         * answerbox from the TASK's list of synchronous answerboxes.
     200         */
     201        (void) interrupts_disable();
     202        spinlock_lock(&TASK->lock);
     203        list_remove(&sync_box->sync_box_link);
     204        spinlock_unlock(&TASK->lock);
     205        interrupts_restore(ipl);
     206
    184207        slab_free(ipc_answerbox_slab, sync_box);
    185208        return EOK;
     
    513536        int i;
    514537        call_t *call;
     538        ipl_t ipl;
    515539
    516540        /* Disconnect all our phones ('ipc_phone_hangup') */
     
    538562        spinlock_unlock(&TASK->answerbox.lock);
    539563       
    540         /* Wait for all async answers to arrive */
     564        /* Wait for all answers to interrupted synchronous calls to arrive */
     565        ipl = interrupts_disable();
     566        while (!list_empty(&TASK->sync_box_head)) {
     567                answerbox_t *box = list_get_instance(TASK->sync_box_head.next,
     568                    answerbox_t, sync_box_link);
     569
     570                list_remove(&box->sync_box_link);
     571                call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,
     572                    SYNCH_FLAGS_NONE);
     573                ipc_call_free(call);
     574                slab_free(ipc_answerbox_slab, box);
     575        }
     576        interrupts_restore(ipl);
     577
     578        /* Wait for all answers to asynchronous calls to arrive */
    541579        while (1) {
    542580                /* Go through all phones, until all are FREE... */
  • kernel/generic/src/ipc/sysipc.c

    rc70ce74 r33adc6ce  
    559559#endif
    560560                if (rc != EOK) {
    561                         /* The call will be freed by someone else. */
     561                        /* The call will be freed by ipc_cleanup(). */
    562562                        return rc;
    563563                }
     
    612612#endif
    613613                if (rc != EOK) {
    614                         /* The call will be freed by someone else. */
     614                        /* The call will be freed by ipc_cleanup(). */
    615615                        return rc;
    616616                }
  • kernel/generic/src/proc/task.c

    rc70ce74 r33adc6ce  
    178178                ipc_phone_connect(&ta->phones[0], ipc_phone_0);
    179179        atomic_set(&ta->active_calls, 0);
     180        list_initialize(&ta->sync_box_head);
    180181
    181182        mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE);
Note: See TracChangeset for help on using the changeset viewer.