Changeset cd671c3 in mainline for kernel/generic/src/ipc/ipc.c


Ignore:
Timestamp:
2012-09-05T22:36:48Z (12 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f1d5ef8
Parents:
239acce
Message:

Reference count call_t structures.
Add ipc_call_hold() and ipc_call_release().
Hold the forgotten call during the request_forget() callback.

File:
1 edited

Legend:

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

    r239acce rcd671c3  
    8080}
    8181
     82void ipc_call_hold(call_t *call)
     83{
     84        atomic_inc(&call->refcnt);
     85}
     86
     87void ipc_call_release(call_t *call)
     88{
     89        if (atomic_predec(&call->refcnt) == 0) {
     90                if (call->buffer)
     91                        free(call->buffer);
     92                slab_free(ipc_call_slab, call);
     93        }
     94}
     95
    8296/** Allocate and initialize a call structure.
    8397 *
     
    88102 *
    89103 * @return If flags permit it, return NULL, or initialized kernel
    90  *         call structure.
     104 *         call structure with one reference.
    91105 *
    92106 */
     
    94108{
    95109        call_t *call = slab_alloc(ipc_call_slab, flags);
    96         if (call)
     110        if (call) {
    97111                _ipc_call_init(call);
     112                ipc_call_hold(call);
     113        }
    98114       
    99115        return call;
     
    107123void ipc_call_free(call_t *call)
    108124{
    109         /* Check to see if we have data in the IPC_M_DATA_SEND buffer. */
    110         if (call->buffer)
    111                 free(call->buffer);
    112         slab_free(ipc_call_slab, call);
     125        ipc_call_release(call);
    113126}
    114127
     
    605618        list_remove(&call->ta_link);
    606619
     620        /*
     621         * The call may be freed by _ipc_answer_free_call() before we are done
     622         * with it; to avoid working with a destroyed call_t structure, we
     623         * must hold a reference to it.
     624         */
     625        ipc_call_hold(call);
     626
    607627        spinlock_unlock(&call->forget_lock);
    608628        spinlock_unlock(&TASK->active_calls_lock);
     
    613633        if (ops->request_forget)
    614634                ops->request_forget(call);
     635
     636        ipc_call_release(call);
    615637
    616638        goto restart;
Note: See TracChangeset for help on using the changeset viewer.