Ignore:
File:
1 edited

Legend:

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

    rc1f68b0 rcde999a  
    6666answerbox_t *ipc_phone_0 = NULL;
    6767
    68 static slab_cache_t *call_slab;
    69 static slab_cache_t *answerbox_slab;
    70 
    71 slab_cache_t *phone_slab = NULL;
     68static slab_cache_t *call_cache;
     69static slab_cache_t *answerbox_cache;
     70
     71slab_cache_t *phone_cache = NULL;
    7272
    7373/** Initialize a call structure.
     
    8787}
    8888
    89 void ipc_call_hold(call_t *call)
    90 {
    91         atomic_inc(&call->refcnt);
    92 }
    93 
    94 void ipc_call_release(call_t *call)
    95 {
    96         if (atomic_predec(&call->refcnt) == 0) {
    97                 if (call->buffer)
    98                         free(call->buffer);
    99                 if (call->caller_phone)
    100                         kobject_put(call->caller_phone->kobject);
    101                 slab_free(call_slab, call);
    102         }
    103 }
     89static void call_destroy(void *arg)
     90{
     91        call_t *call = (call_t *) arg;
     92
     93        if (call->buffer)
     94                free(call->buffer);
     95        if (call->caller_phone)
     96                kobject_put(call->caller_phone->kobject);
     97        slab_free(call_cache, call);
     98}
     99
     100static kobject_ops_t call_kobject_ops = {
     101        .destroy = call_destroy
     102};
    104103
    105104/** Allocate and initialize a call structure.
     
    116115call_t *ipc_call_alloc(unsigned int flags)
    117116{
    118         call_t *call = slab_alloc(call_slab, flags);
    119         if (call) {
    120                 _ipc_call_init(call);
    121                 ipc_call_hold(call);
    122         }
     117        call_t *call = slab_alloc(call_cache, flags);
     118        if (!call)
     119                return NULL;
     120        kobject_t *kobj = (kobject_t *) malloc(sizeof(kobject_t), flags);
     121        if (!kobj) {
     122                slab_free(call_cache, call);
     123                return NULL;
     124        }
     125
     126        _ipc_call_init(call);
     127        kobject_initialize(kobj, KOBJECT_TYPE_CALL, call, &call_kobject_ops);
     128        call->kobject = kobj;
    123129       
    124130        return call;
    125 }
    126 
    127 /** Deallocate a call structure.
    128  *
    129  * @param call Call structure to be freed.
    130  *
    131  */
    132 void ipc_call_free(call_t *call)
    133 {
    134         ipc_call_release(call);
    135131}
    136132
     
    209205 * @param request Call structure with request.
    210206 *
    211  * @return EOK on success or a negative error code.
     207 * @return EOK on success or an error code.
    212208 *
    213209 */
    214210int ipc_call_sync(phone_t *phone, call_t *request)
    215211{
    216         answerbox_t *mybox = slab_alloc(answerbox_slab, 0);
     212        answerbox_t *mybox = slab_alloc(answerbox_cache, 0);
    217213        ipc_answerbox_init(mybox, TASK);
    218214       
     
    222218        int rc = ipc_call(phone, request);
    223219        if (rc != EOK) {
    224                 slab_free(answerbox_slab, mybox);
     220                slab_free(answerbox_cache, mybox);
    225221                return rc;
    226222        }
     
    269265        assert(!answer || request == answer);
    270266       
    271         slab_free(answerbox_slab, mybox);
     267        slab_free(answerbox_cache, mybox);
    272268        return rc;
    273269}
     
    290286                /* This is a forgotten call and call->sender is not valid. */
    291287                spinlock_unlock(&call->forget_lock);
    292                 ipc_call_free(call);
     288                kobject_put(call->kobject);
    293289                return;
    294290        } else {
     
    375371 *
    376372 */
    377 void ipc_backsend_err(phone_t *phone, call_t *call, sysarg_t err)
     373void ipc_backsend_err(phone_t *phone, call_t *call, int err)
    378374{
    379375        _ipc_call_actions_internal(phone, call, false);
     
    448444 * @param phone Phone structure to be hung up.
    449445 *
    450  * @return 0 if the phone is disconnected.
    451  * @return -1 if the phone was already disconnected.
     446 * @return EOK if the phone is disconnected.
     447 * @return EINVAL if the phone was already disconnected.
    452448 *
    453449 */
     
    459455            phone->state == IPC_PHONE_CONNECTING) {
    460456                mutex_unlock(&phone->lock);
    461                 return -1;
     457                return EINVAL;
    462458        }
    463459       
     
    482478        mutex_unlock(&phone->lock);
    483479       
    484         return 0;
     480        return EOK;
    485481}
    486482
     
    542538       
    543539restart:
    544         rc = waitq_sleep_timeout(&box->wq, usec, flags);
    545         if (SYNCH_FAILED(rc))
     540        rc = waitq_sleep_timeout(&box->wq, usec, flags, NULL);
     541        if (rc != EOK)
    546542                return NULL;
    547543       
     
    642638                phone = list_get_instance(list_first(&box->connected_phones),
    643639                    phone_t, link);
    644                 if (SYNCH_FAILED(mutex_trylock(&phone->lock))) {
     640                if (mutex_trylock(&phone->lock) != EOK) {
    645641                        irq_spinlock_unlock(&box->lock, true);
    646642                        DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD);
     
    705701         * must hold a reference to it.
    706702         */
    707         ipc_call_hold(call);
     703        kobject_add_ref(call->kobject);
    708704
    709705        spinlock_unlock(&call->forget_lock);
     
    714710        SYSIPC_OP(request_forget, call);
    715711
    716         ipc_call_release(call);
     712        kobject_put(call->kobject);
    717713}
    718714
     
    822818        SYSIPC_OP(answer_process, call);
    823819
    824         ipc_call_free(call);
     820        kobject_put(call->kobject);
    825821        goto restart;
    826822}
     
    839835{
    840836        ipc_irq_unsubscribe(&TASK->answerbox, cap->handle);
     837        return true;
     838}
     839
     840static bool call_cap_cleanup_cb(cap_t *cap, void *arg)
     841{
     842        /*
     843         * Here we just free the capability and release the kobject.
     844         * The kernel answers the remaining calls elsewhere in ipc_cleanup().
     845         */
     846        kobject_t *kobj = cap_unpublish(cap->task, cap->handle,
     847            KOBJECT_TYPE_CALL);
     848        kobject_put(kobj);
     849        cap_free(cap->task, cap->handle);
    841850        return true;
    842851}
     
    878887        ipc_kbox_cleanup();
    879888#endif
     889
     890        /* Destroy all call capabilities */
     891        caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_CALL, call_cap_cleanup_cb,
     892            NULL);
    880893       
    881894        /* Answer all messages in 'calls' and 'dispatched_calls' queues */
     
    893906void ipc_init(void)
    894907{
    895         call_slab = slab_cache_create("call_t", sizeof(call_t), 0, NULL,
     908        call_cache = slab_cache_create("call_t", sizeof(call_t), 0, NULL,
    896909            NULL, 0);
    897         phone_slab = slab_cache_create("phone_t", sizeof(phone_t), 0, NULL,
     910        phone_cache = slab_cache_create("phone_t", sizeof(phone_t), 0, NULL,
    898911            NULL, 0);
    899         answerbox_slab = slab_cache_create("answerbox_t", sizeof(answerbox_t),
     912        answerbox_cache = slab_cache_create("answerbox_t", sizeof(answerbox_t),
    900913            0, NULL, NULL, 0);
    901914}
Note: See TracChangeset for help on using the changeset viewer.