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

Changeset 48bcf49 in mainline


Ignore:
Timestamp:
2017-09-28T22:08:15Z (4 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master
Children:
6636fb19
Parents:
dd20cbb
Message:

Introduce reference-counted kobjects

Capabilities are thus reduced to task-local names for references to kobjects.

Location:
kernel/generic
Files:
14 edited

Legend:

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

    rdd20cbb r48bcf49  
    3737
    3838#include <typedefs.h>
    39 #include <ipc/ipc.h>
    4039#include <adt/list.h>
    4140#include <synch/mutex.h>
     41#include <atomic.h>
    4242
    4343#define MAX_CAPS  64
    4444
     45typedef int cap_handle_t;
     46
    4547typedef enum {
    46         CAP_TYPE_INVALID,
    47         CAP_TYPE_ALLOCATED,
    48         CAP_TYPE_PHONE,
    49         CAP_TYPE_IRQ,
    50         CAP_TYPE_MAX
    51 } cap_type_t;
     48        CAP_STATE_FREE,
     49        CAP_STATE_ALLOCATED,
     50        CAP_STATE_PUBLISHED
     51} cap_state_t;
     52
     53typedef enum {
     54        KOBJECT_TYPE_PHONE,
     55        KOBJECT_TYPE_IRQ,
     56        KOBJECT_TYPE_MAX
     57} kobject_type_t;
     58
     59struct task;
     60struct phone;
     61struct irq;
     62
     63struct kobject;
     64typedef struct kobject_ops {
     65        bool (*reclaim)(struct kobject *);
     66        void (*destroy)(void *);
     67} kobject_ops_t;
     68
     69typedef struct kobject {
     70        kobject_type_t type;
     71        atomic_t refcnt;
     72
     73        kobject_ops_t *ops;
     74
     75        union {
     76                void *raw;
     77                struct phone *phone;
     78                struct irq *irq;
     79        };
     80} kobject_t;
    5281
    5382typedef struct cap {
    54         cap_type_t type;
    55         int handle;
     83        cap_state_t state;
    5684
    57         bool (* can_reclaim)(struct cap *);
     85        cap_handle_t handle;
    5886
    59         /* Link to the task's capabilities of the same type. */
     87        /* Link to the task's capabilities of the same kobject type. */
    6088        link_t link;
    6189
    6290        /* The underlying kernel object. */
    63         void *kobject;
     91        kobject_t *kobject;
    6492} cap_t;
    6593
     
    6795        mutex_t lock;
    6896
    69         list_t type_list[CAP_TYPE_MAX];
     97        list_t type_list[KOBJECT_TYPE_MAX];
    7098
    7199        cap_t *caps;
    72100} cap_info_t;
    73101
    74 struct task;
    75 
    76102extern void caps_task_alloc(struct task *);
    77103extern void caps_task_free(struct task *);
    78104extern void caps_task_init(struct task *);
    79 extern bool caps_apply_to_type(struct task *, cap_type_t,
     105extern bool caps_apply_to_kobject_type(struct task *, kobject_type_t,
    80106    bool (*)(cap_t *, void *), void *);
    81 extern void caps_lock(struct task *);
    82 extern void caps_unlock(struct task *);
    83107
    84 extern void cap_initialize(cap_t *, int);
    85 extern cap_t *cap_get(struct task *, int, cap_type_t);
    86 extern int cap_alloc(struct task *);
    87 extern void cap_publish(struct task *, int, cap_type_t, void *);
    88 extern cap_t *cap_unpublish(struct task *, int, cap_type_t);
    89 extern void cap_free(struct task *, int);
     108extern void cap_initialize(cap_t *, cap_handle_t);
     109extern cap_handle_t cap_alloc(struct task *);
     110extern void cap_publish(struct task *, cap_handle_t, kobject_t *);
     111extern kobject_t *cap_unpublish(struct task *, cap_handle_t, kobject_type_t);
     112extern void cap_free(struct task *, cap_handle_t);
     113
     114extern void kobject_initialize(kobject_t *, kobject_type_t, void *,
     115    kobject_ops_t *);
     116extern kobject_t *kobject_get(struct task *, cap_handle_t, kobject_type_t);
     117extern void kobject_put(kobject_t *);
    90118
    91119#endif
  • kernel/generic/include/ddi/irq.h

    rdd20cbb r48bcf49  
    8181        /** When false, notifications are not sent. */
    8282        bool notify;
     83        /** True if the structure is in irq_uspace_hash_table_table */
     84        bool hashed_in;
    8385        /** Answerbox for notifications. */
    8486        answerbox_t *answerbox;
  • kernel/generic/include/ipc/ipc.h

    rdd20cbb r48bcf49  
    4343#include <typedefs.h>
    4444#include <mm/slab.h>
     45#include <cap/cap.h>
    4546
    4647struct answerbox;
     
    6162
    6263/** Structure identifying phone (in TASK structure) */
    63 typedef struct {
     64typedef struct phone {
    6465        mutex_t lock;
    6566        link_t link;
     
    6869        ipc_phone_state_t state;
    6970        atomic_t active_calls;
     71        kobject_t *kobject;
    7072} phone_t;
    7173
  • kernel/generic/include/ipc/ipcrsc.h

    rdd20cbb r48bcf49  
    3838#include <proc/task.h>
    3939#include <ipc/ipc.h>
     40#include <cap/cap.h>
    4041
    4142extern call_t *get_call(sysarg_t);
    42 extern phone_t *phone_get_current(int);
    43 extern phone_t *phone_get(task_t *, int);
    44 extern int phone_alloc(task_t *);
    45 extern bool phone_connect(int, answerbox_t *);
    46 extern void phone_dealloc(int);
     43extern cap_handle_t phone_alloc(task_t *);
     44extern bool phone_connect(cap_handle_t, answerbox_t *);
     45extern void phone_dealloc(cap_handle_t);
    4746
    4847#endif
  • kernel/generic/src/cap/cap.c

    rdd20cbb r48bcf49  
    4040#include <adt/list.h>
    4141
    42 void cap_initialize(cap_t *cap, int handle)
    43 {
    44         cap->type = CAP_TYPE_INVALID;
     42static kobject_t *cap_unpublish_locked(task_t *, cap_handle_t, kobject_type_t);
     43
     44void cap_initialize(cap_t *cap, cap_handle_t handle)
     45{
     46        cap->state = CAP_STATE_FREE;
    4547        cap->handle = handle;
    46         cap->can_reclaim = NULL;
    4748        link_initialize(&cap->link);
    4849}
     
    5859        mutex_initialize(&task->cap_info->lock, MUTEX_PASSIVE);
    5960
    60         for (int i = 0; i < CAP_TYPE_MAX; i++)
    61                 list_initialize(&task->cap_info->type_list[i]);
    62 
    63         for (int i = 0; i < MAX_CAPS; i++)
    64                 cap_initialize(&task->cap_info->caps[i], i);
     61        for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++)
     62                list_initialize(&task->cap_info->type_list[t]);
     63
     64        for (cap_handle_t h = 0; h < MAX_CAPS; h++)
     65                cap_initialize(&task->cap_info->caps[h], h);
    6566}
    6667
     
    7172}
    7273
    73 bool caps_apply_to_type(task_t *task, cap_type_t type,
     74bool caps_apply_to_kobject_type(task_t *task, kobject_type_t type,
    7475    bool (*cb)(cap_t *, void *), void *arg)
    7576{
     
    8889}
    8990
    90 void caps_lock(task_t *task)
    91 {
    92         mutex_lock(&task->cap_info->lock);
    93 }
    94 
    95 void caps_unlock(task_t *task)
    96 {
    97         mutex_unlock(&task->cap_info->lock);
    98 }
    99 
    100 cap_t *cap_get(task_t *task, int handle, cap_type_t type)
     91static cap_t *cap_get(task_t *task, cap_handle_t handle, cap_state_t state)
    10192{
    10293        assert(mutex_locked(&task->cap_info->lock));
     
    10495        if ((handle < 0) || (handle >= MAX_CAPS))
    10596                return NULL;
    106         if (task->cap_info->caps[handle].type != type)
     97        if (task->cap_info->caps[handle].state != state)
    10798                return NULL;
    10899        return &task->cap_info->caps[handle];
    109100}
    110101
    111 int cap_alloc(task_t *task)
    112 {
    113         int handle;
    114 
    115         mutex_lock(&task->cap_info->lock);
    116         for (handle = 0; handle < MAX_CAPS; handle++) {
     102cap_handle_t cap_alloc(task_t *task)
     103{
     104        mutex_lock(&task->cap_info->lock);
     105        for (cap_handle_t handle = 0; handle < MAX_CAPS; handle++) {
    117106                cap_t *cap = &task->cap_info->caps[handle];
    118                 if (cap->type > CAP_TYPE_ALLOCATED) {
    119                         if (cap->can_reclaim && cap->can_reclaim(cap)) {
    120                                 list_remove(&cap->link);
    121                                 cap_initialize(cap, handle);
    122                         }
    123                 }
    124                 if (cap->type == CAP_TYPE_INVALID) {
    125                         cap->type = CAP_TYPE_ALLOCATED;
     107                /* See if the capability should be garbage-collected */
     108                if (cap->state == CAP_STATE_PUBLISHED &&
     109                    cap->kobject->ops->reclaim &&
     110                    cap->kobject->ops->reclaim(cap->kobject)) {
     111                        kobject_t *kobj = cap_unpublish_locked(task, handle,
     112                            cap->kobject->type);
     113                        kobject_put(kobj);
     114                        cap_initialize(&task->cap_info->caps[handle], handle);
     115                }
     116                if (cap->state == CAP_STATE_FREE) {
     117                        cap->state = CAP_STATE_ALLOCATED;
    126118                        mutex_unlock(&task->cap_info->lock);
    127119                        return handle;
     
    133125}
    134126
    135 void cap_publish(task_t *task, int handle, cap_type_t type, void *kobject)
    136 {
    137         mutex_lock(&task->cap_info->lock);
    138         cap_t *cap = cap_get(task, handle, CAP_TYPE_ALLOCATED);
     127void
     128cap_publish(task_t *task, cap_handle_t handle, kobject_t *kobj)
     129{
     130        mutex_lock(&task->cap_info->lock);
     131        cap_t *cap = cap_get(task, handle, CAP_STATE_ALLOCATED);
    139132        assert(cap);
    140         cap->type = type;
    141         cap->kobject = kobject;
    142         list_append(&cap->link, &task->cap_info->type_list[type]);
    143         mutex_unlock(&task->cap_info->lock);
    144 }
    145 
    146 cap_t *cap_unpublish(task_t *task, int handle, cap_type_t type)
    147 {
    148         cap_t *cap;
    149 
    150         mutex_lock(&task->cap_info->lock);
    151         cap = cap_get(task, handle, type);
     133        cap->state = CAP_STATE_PUBLISHED;
     134        /* Hand over kobj's reference to cap */
     135        cap->kobject = kobj;
     136        list_append(&cap->link, &task->cap_info->type_list[kobj->type]);
     137        mutex_unlock(&task->cap_info->lock);
     138}
     139
     140static kobject_t *
     141cap_unpublish_locked(task_t *task, cap_handle_t handle, kobject_type_t type)
     142{
     143        kobject_t *kobj = NULL;
     144
     145        cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED);
    152146        if (cap) {
    153                 list_remove(&cap->link);
    154                 cap->type = CAP_TYPE_ALLOCATED;
    155         }
    156         mutex_unlock(&task->cap_info->lock);
    157 
    158         return cap;
    159 }
    160 
    161 void cap_free(task_t *task, int handle)
     147                if (cap->kobject->type == type) {
     148                        /* Hand over cap's reference to kobj */
     149                        kobj = cap->kobject;
     150                        cap->kobject = NULL;
     151                        list_remove(&cap->link);
     152                        cap->state = CAP_STATE_ALLOCATED;
     153                }
     154        }
     155
     156        return kobj;
     157}
     158kobject_t *cap_unpublish(task_t *task, cap_handle_t handle, kobject_type_t type)
     159{
     160
     161        mutex_lock(&task->cap_info->lock);
     162        kobject_t *kobj = cap_unpublish_locked(task, handle, type);
     163        mutex_unlock(&task->cap_info->lock);
     164
     165        return kobj;
     166}
     167
     168void cap_free(task_t *task, cap_handle_t handle)
    162169{
    163170        assert(handle >= 0);
    164171        assert(handle < MAX_CAPS);
    165         assert(task->cap_info->caps[handle].type == CAP_TYPE_ALLOCATED);
     172        assert(task->cap_info->caps[handle].state == CAP_STATE_ALLOCATED);
    166173
    167174        mutex_lock(&task->cap_info->lock);
     
    170177}
    171178
     179void kobject_initialize(kobject_t *kobj, kobject_type_t type, void *raw,
     180    kobject_ops_t *ops)
     181{
     182        atomic_set(&kobj->refcnt, 1);
     183        kobj->type = type;
     184        kobj->raw = raw;
     185        kobj->ops = ops;
     186}
     187
     188kobject_t *
     189kobject_get(struct task *task, cap_handle_t handle, kobject_type_t type)
     190{
     191        kobject_t *kobj = NULL;
     192
     193        mutex_lock(&task->cap_info->lock);
     194        cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED);
     195        if (cap) {
     196                if (cap->kobject->type == type) {
     197                        kobj = cap->kobject;
     198                        atomic_inc(&kobj->refcnt);
     199                }
     200        }
     201        mutex_unlock(&task->cap_info->lock);
     202
     203        return kobj;
     204}
     205
     206void kobject_put(kobject_t *kobj)
     207{
     208        if (atomic_postdec(&kobj->refcnt) == 1) {
     209                kobj->ops->destroy(kobj->raw);
     210                free(kobj);
     211        }
     212}
     213
    172214/** @}
    173215 */
  • kernel/generic/src/ipc/ipc.c

    rdd20cbb r48bcf49  
    154154/** Connect a phone to an answerbox.
    155155 *
    156  * @param phone Initialized phone structure.
    157  * @param box   Initialized answerbox structure.
    158  * @return      True if the phone was connected, false otherwise.
     156 * This function must be passed a reference to phone->kobject.
     157 *
     158 * @param phone  Initialized phone structure.
     159 * @param box    Initialized answerbox structure.
     160 * @return       True if the phone was connected, false otherwise.
    159161 */
    160162bool ipc_phone_connect(phone_t *phone, answerbox_t *box)
     
    169171                phone->state = IPC_PHONE_CONNECTED;
    170172                phone->callee = box;
     173                /* Pass phone->kobject reference to box->connected_phones */
    171174                list_append(&phone->link, &box->connected_phones);
    172175        }
     
    174177        irq_spinlock_unlock(&box->lock, true);
    175178        mutex_unlock(&phone->lock);
     179
     180        if (!active) {
     181                /* We still have phone->kobject's reference; drop it */
     182                kobject_put(phone->kobject);
     183        }
    176184
    177185        return active;
     
    191199        phone->state = IPC_PHONE_FREE;
    192200        atomic_set(&phone->active_calls, 0);
     201        phone->kobject = NULL;
    193202}
    194203
     
    456465                list_remove(&phone->link);
    457466                irq_spinlock_unlock(&box->lock, true);
     467
     468                /* Drop the answerbox reference */
     469                kobject_put(phone->kobject);
    458470               
    459471                call_t *call = ipc_call_alloc(0);
     
    658670
    659671                        task_release(phone->caller);
     672
     673                        kobject_put(phone->kobject);
    660674                       
    661675                        /* Must start again */
     
    664678               
    665679                mutex_unlock(&phone->lock);
     680                kobject_put(phone->kobject);
    666681        }
    667682       
     
    734749static bool phone_cap_wait_cb(cap_t *cap, void *arg)
    735750{
    736         phone_t *phone = (phone_t *) cap->kobject;
     751        phone_t *phone = cap->kobject->phone;
    737752        bool *restart = (bool *) arg;
    738753
     
    790805         */
    791806        restart = false;
    792         if (caps_apply_to_type(TASK, CAP_TYPE_PHONE, phone_cap_wait_cb,
    793             &restart)) {
     807        if (caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_PHONE,
     808            phone_cap_wait_cb, &restart)) {
    794809                /* Got into cleanup */
    795810                return;
     
    810825static bool phone_cap_cleanup_cb(cap_t *cap, void *arg)
    811826{
    812         phone_t *phone = (phone_t *) cap->kobject;
    813         ipc_phone_hangup(phone);
     827        ipc_phone_hangup(cap->kobject->phone);
    814828        return true;
    815829}
     
    840854
    841855        /* Disconnect all our phones ('ipc_phone_hangup') */
    842         caps_apply_to_type(TASK, CAP_TYPE_PHONE, phone_cap_cleanup_cb, NULL);
     856        caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_PHONE,
     857            phone_cap_cleanup_cb, NULL);
    843858       
    844859        /* Unsubscribe from any event notifications. */
     
    846861       
    847862        /* Disconnect all connected IRQs */
    848         caps_apply_to_type(TASK, CAP_TYPE_IRQ, irq_cap_cleanup_cb, NULL);
     863        caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_IRQ, irq_cap_cleanup_cb,
     864            NULL);
    849865       
    850866        /* Disconnect all phones connected to our regular answerbox */
     
    912928static bool print_task_phone_cb(cap_t *cap, void *arg)
    913929{
    914         phone_t *phone = (phone_t *) cap->kobject;
     930        phone_t *phone = cap->kobject->phone;
    915931
    916932        mutex_lock(&phone->lock);
     
    963979        printf("[phone cap] [calls] [state\n");
    964980       
    965         caps_apply_to_type(task, CAP_TYPE_PHONE, print_task_phone_cb, NULL);
     981        caps_apply_to_kobject_type(task, KOBJECT_TYPE_PHONE,
     982            print_task_phone_cb, NULL);
    966983       
    967984        irq_spinlock_lock(&task->lock, true);
  • kernel/generic/src/ipc/ipcrsc.c

    rdd20cbb r48bcf49  
    164164}
    165165
    166 /** Get phone from the current task by capability handle.
    167  *
    168  * @param handle  Phone capability handle.
    169  * @param phone   Place to store pointer to phone.
    170  *
    171  * @return  Address of the phone kernel object.
    172  * @return  NULL if the capability is invalid.
    173  *
    174  */
    175 phone_t *phone_get(task_t *task, int handle)
    176 {
    177         phone_t *phone;
    178 
    179         caps_lock(task);
    180         cap_t *cap = cap_get(task, handle, CAP_TYPE_PHONE);
    181         phone = (phone_t *) cap->kobject;
    182         caps_unlock(task);
    183         if (!cap)
    184                 return NULL;
    185        
    186         return phone;
    187 }
    188 
    189 phone_t *phone_get_current(int handle)
    190 {
    191         return phone_get(TASK, handle);
    192 }
    193 
    194 static bool phone_can_reclaim(cap_t *cap)
    195 {
    196         assert(cap->type == CAP_TYPE_PHONE);
    197 
    198         phone_t *phone = (phone_t *) cap->kobject;
    199 
    200         return (phone->state == IPC_PHONE_HUNGUP) &&
    201             (atomic_get(&phone->active_calls) == 0);
    202 }
     166static bool phone_reclaim(kobject_t *kobj)
     167{
     168        bool gc = false;
     169
     170        mutex_lock(&kobj->phone->lock);
     171        if (kobj->phone->state == IPC_PHONE_HUNGUP &&
     172            atomic_get(&kobj->phone->active_calls) == 0)
     173                gc = true;
     174        mutex_unlock(&kobj->phone->lock);
     175
     176        return gc;
     177}
     178
     179static void phone_destroy(void *arg)
     180{
     181        phone_t *phone = (phone_t *) arg;
     182        slab_free(phone_slab, phone);
     183}
     184
     185static kobject_ops_t phone_kobject_ops = {
     186        .reclaim = phone_reclaim,
     187        .destroy = phone_destroy
     188};
     189
    203190
    204191/** Allocate new phone in the specified task.
     
    209196 * @return  Negative error code if a new capability cannot be allocated.
    210197 */
    211 int phone_alloc(task_t *task)
    212 {
    213         int handle = cap_alloc(task);
     198cap_handle_t phone_alloc(task_t *task)
     199{
     200        cap_handle_t handle = cap_alloc(task);
    214201        if (handle >= 0) {
    215202                phone_t *phone = slab_alloc(phone_slab, FRAME_ATOMIC);
     
    218205                        return ENOMEM;
    219206                }
    220                
     207                kobject_t *kobject = malloc(sizeof(kobject_t), FRAME_ATOMIC);
     208                if (!kobject) {
     209                        cap_free(TASK, handle);
     210                        slab_free(phone_slab, phone);
     211                        return ENOMEM;
     212                }
     213
    221214                ipc_phone_init(phone, task);
    222215                phone->state = IPC_PHONE_CONNECTING;
     216
     217                kobject_initialize(kobject, KOBJECT_TYPE_PHONE, phone,
     218                    &phone_kobject_ops);
     219                phone->kobject = kobject;
    223220               
    224                 // FIXME: phase this out eventually
    225                 mutex_lock(&task->cap_info->lock);
    226                 cap_t *cap = cap_get(task, handle, CAP_TYPE_ALLOCATED);
    227                 cap->can_reclaim = phone_can_reclaim;
    228                 mutex_unlock(&task->cap_info->lock);
    229 
    230                 cap_publish(task, handle, CAP_TYPE_PHONE, phone);
     221                cap_publish(task, handle, kobject);
    231222        }
    232223       
     
    241232 *
    242233 */
    243 void phone_dealloc(int handle)
    244 {
    245         cap_t *cap = cap_unpublish(TASK, handle, CAP_TYPE_PHONE);
    246         assert(cap);
    247        
    248         phone_t *phone = (phone_t *) cap->kobject;
    249        
    250         assert(phone);
    251         assert(phone->state == IPC_PHONE_CONNECTING);
    252        
    253         slab_free(phone_slab, phone);
     234void phone_dealloc(cap_handle_t handle)
     235{
     236        kobject_t *kobj = cap_unpublish(TASK, handle, KOBJECT_TYPE_PHONE);
     237        if (!kobj)
     238                return;
     239       
     240        assert(kobj->phone);
     241        assert(kobj->phone->state == IPC_PHONE_CONNECTING);
     242       
     243        kobject_put(kobj);
    254244        cap_free(TASK, handle);
    255245}
     
    260250 * @param box     Answerbox to which to connect the phone.
    261251 * @return        True if the phone was connected, false otherwise.
    262  *
    263  * The procedure _enforces_ that the user first marks the phone busy (e.g. via
    264  * phone_alloc) and then connects the phone, otherwise race condition may
    265  * appear.
    266  *
    267  */
    268 bool phone_connect(int handle, answerbox_t *box)
    269 {
    270         phone_t *phone = phone_get_current(handle);
    271        
    272         assert(phone);
    273         assert(phone->state == IPC_PHONE_CONNECTING);
    274        
    275         return ipc_phone_connect(phone, box);
     252 */
     253bool phone_connect(cap_handle_t handle, answerbox_t *box)
     254{
     255        kobject_t *phone_obj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     256        if (!phone_obj)
     257                return false;
     258       
     259        assert(phone_obj->phone->state == IPC_PHONE_CONNECTING);
     260       
     261        /* Hand over phone_obj reference to the answerbox */
     262        return ipc_phone_connect(phone_obj->phone, box);
    276263}
    277264
  • kernel/generic/src/ipc/irq.c

    rdd20cbb r48bcf49  
    271271}
    272272
     273static void irq_destroy(void *arg)
     274{
     275        irq_t *irq = (irq_t *) arg;
     276
     277        /* Free up the IRQ code and associated structures. */
     278        code_free(irq->notif_cfg.code);
     279        slab_free(irq_slab, irq);
     280}
     281
     282static kobject_ops_t irq_kobject_ops = {
     283        .destroy = irq_destroy
     284};
     285
    273286/** Subscribe an answerbox as a receiving end for IRQ notifications.
    274287 *
     
    304317         * Allocate and populate the IRQ kernel object.
    305318         */
    306         int handle = cap_alloc(TASK);
     319        cap_handle_t handle = cap_alloc(TASK);
    307320        if (handle < 0)
    308321                return handle;
     
    311324        if (!irq) {
    312325                cap_free(TASK, handle);
     326                return ENOMEM;
     327        }
     328
     329        kobject_t *kobject = malloc(sizeof(kobject_t), FRAME_ATOMIC);
     330        if (!kobject) {
     331                cap_free(TASK, handle);
     332                slab_free(irq_slab, irq);
    313333                return ENOMEM;
    314334        }
     
    330350        irq_spinlock_lock(&irq->lock, false);
    331351       
     352        irq->notif_cfg.hashed_in = true;
    332353        hash_table_insert(&irq_uspace_hash_table, key, &irq->link);
    333354       
     
    335356        irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
    336357
    337         cap_publish(TASK, handle, CAP_TYPE_IRQ, irq);
     358        kobject_initialize(kobject, KOBJECT_TYPE_IRQ, irq, &irq_kobject_ops);
     359        cap_publish(TASK, handle, kobject);
    338360       
    339361        return handle;
     
    350372int ipc_irq_unsubscribe(answerbox_t *box, int handle)
    351373{
    352         cap_t *cap = cap_unpublish(TASK, handle, CAP_TYPE_IRQ);
    353         if (!cap)
     374        kobject_t *kobj = cap_unpublish(TASK, handle, KOBJECT_TYPE_IRQ);
     375        if (!kobj)
    354376                return ENOENT;
    355377       
    356         irq_t *irq = (irq_t *) cap->kobject;
    357        
     378        assert(kobj->irq->notif_cfg.answerbox == box);
     379
    358380        irq_spinlock_lock(&irq_uspace_hash_table_lock, true);
    359         irq_spinlock_lock(&irq->lock, false);
    360        
    361         assert(irq->notif_cfg.answerbox == box);
    362        
    363         /* Remove the IRQ from the uspace IRQ hash table. */
    364         hash_table_remove_item(&irq_uspace_hash_table, &irq->link);
    365        
    366         /* irq->lock unlocked by the hash table remove_callback */
     381        irq_spinlock_lock(&kobj->irq->lock, false);
     382       
     383        if (kobj->irq->notif_cfg.hashed_in) {
     384                /* Remove the IRQ from the uspace IRQ hash table. */
     385                hash_table_remove_item(&irq_uspace_hash_table,
     386                    &kobj->irq->link);
     387                kobj->irq->notif_cfg.hashed_in = false;
     388        }
     389
     390        /* kobj->irq->lock unlocked by the hash table remove_callback */
    367391        irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
    368        
    369         /* Free up the IRQ code and associated structures. */
    370         code_free(irq->notif_cfg.code);
    371        
    372         /* Free up the IRQ capability and the underlying kernel object. */
    373         slab_free(irq_slab, cap->kobject);
     392
     393        kobject_put(kobj);
    374394        cap_free(TASK, handle);
    375395       
  • kernel/generic/src/ipc/kbox.c

    rdd20cbb r48bcf49  
    206206 * cleanup code.
    207207 *
    208  * @return Phone capability on success, or negative error code.
     208 * @return Phone capability handle on success, or negative error code.
    209209 *
    210210 */
     
    236236        }
    237237       
    238         int cap = phone_alloc(TASK);
    239         if (cap < 0) {
    240                 mutex_unlock(&task->kb.cleanup_lock);
    241                 return ELIMIT;
    242         }
    243        
     238        cap_handle_t phone_handle = phone_alloc(TASK);
     239        if (phone_handle < 0) {
     240                mutex_unlock(&task->kb.cleanup_lock);
     241                return phone_handle;
     242        }
     243       
     244        kobject_t *phone_obj = kobject_get(TASK, phone_handle,
     245            KOBJECT_TYPE_PHONE);
    244246        /* Connect the newly allocated phone to the kbox */
    245         (void) ipc_phone_connect(phone_get_current(cap), &task->kb.box);
     247        /* Hand over phone_obj's reference to ipc_phone_connect() */
     248        (void) ipc_phone_connect(phone_obj->phone, &task->kb.box);
    246249       
    247250        if (task->kb.thread != NULL) {
    248251                mutex_unlock(&task->kb.cleanup_lock);
    249                 return cap;
     252                return phone_handle;
    250253        }
    251254       
     
    263266        mutex_unlock(&task->kb.cleanup_lock);
    264267       
    265         return cap;
     268        return phone_handle;
    266269}
    267270
  • kernel/generic/src/ipc/ops/conctmeto.c

    rdd20cbb r48bcf49  
    11/*
    22 * Copyright (c) 2006 Ondrej Palkovsky
    3  * Copyright (c) 2012 Jakub Jermar 
     3 * Copyright (c) 2012 Jakub Jermar
    44 * All rights reserved.
    55 *
     
    4242static int request_preprocess(call_t *call, phone_t *phone)
    4343{
    44         int cap = phone_alloc(TASK);
     44        cap_handle_t phone_handle = phone_alloc(TASK);
    4545
    4646        /* Remember the phone capability or the error. */
    47         call->priv = cap;
    48         if (cap < 0)
    49                 return ELIMIT;
    50                
     47        call->priv = phone_handle;
     48        if (phone_handle < 0)
     49                return phone_handle;
     50
    5151        /* Set arg5 for server */
    52         IPC_SET_ARG5(call->data, (sysarg_t) phone_get_current(cap));
     52        kobject_t *phone_obj = kobject_get(TASK, phone_handle,
     53            KOBJECT_TYPE_PHONE);
     54        /* Hand over phone_obj's reference to ARG5 */
     55        IPC_SET_ARG5(call->data, (sysarg_t) phone_obj->phone);
    5356
    5457        return EOK;
     
    5760static int request_forget(call_t *call)
    5861{
    59         phone_dealloc(call->priv);
     62        cap_handle_t phone_handle = (cap_handle_t) call->priv;
     63        phone_dealloc(phone_handle);
     64        /* Hand over reference from ARG5 to phone->kobject */
     65        phone_t *phone = (phone_t *) IPC_GET_ARG5(call->data);
     66        /* Drop phone_obj's reference */
     67        kobject_put(phone->kobject);
    6068        return EOK;
    6169}
     
    6371static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
    6472{
     73        /* Hand over reference from ARG5 to phone */
    6574        phone_t *phone = (phone_t *) IPC_GET_ARG5(*olddata);
    6675
    6776        /* If the user accepted call, connect */
    68         if (IPC_GET_RETVAL(answer->data) == EOK)
     77        if (IPC_GET_RETVAL(answer->data) == EOK) {
     78                /* Hand over reference from phone to the answerbox */
    6979                (void) ipc_phone_connect(phone, &TASK->answerbox);
     80        } else {
     81                kobject_put(phone->kobject);
     82        }
    7083
    7184        return EOK;
     
    7487static int answer_process(call_t *answer)
    7588{
    76         int cap = (int) answer->priv;
     89        cap_handle_t phone_handle = (cap_handle_t) answer->priv;
    7790
    7891        if (IPC_GET_RETVAL(answer->data)) {
    79                 if (cap >= 0) {
     92                if (phone_handle >= 0) {
    8093                        /*
    8194                         * The phone was indeed allocated and now needs
    8295                         * to be deallocated.
    8396                         */
    84                         phone_dealloc(cap);
     97                        phone_dealloc(phone_handle);
    8598                }
    8699        } else {
    87                 IPC_SET_ARG5(answer->data, cap);
     100                IPC_SET_ARG5(answer->data, phone_handle);
    88101        }
    89102       
  • kernel/generic/src/ipc/ops/concttome.c

    rdd20cbb r48bcf49  
    11/*
    22 * Copyright (c) 2006 Ondrej Palkovsky
    3  * Copyright (c) 2012 Jakub Jermar 
     3 * Copyright (c) 2012 Jakub Jermar
    44 * All rights reserved.
    55 *
     
    4242static int request_process(call_t *call, answerbox_t *box)
    4343{
    44         int cap = phone_alloc(TASK);
     44        cap_handle_t phone_handle = phone_alloc(TASK);
    4545
    46         IPC_SET_ARG5(call->data, cap);
     46        IPC_SET_ARG5(call->data, phone_handle);
    4747       
    4848        return EOK;
     
    5151static int answer_cleanup(call_t *answer, ipc_data_t *olddata)
    5252{
    53         int cap = (int) IPC_GET_ARG5(*olddata);
     53        cap_handle_t phone_handle = (cap_handle_t) IPC_GET_ARG5(*olddata);
    5454
    55         if (cap >= 0)
    56                 phone_dealloc(cap);
     55        if (phone_handle >= 0)
     56                phone_dealloc(phone_handle);
    5757
    5858        return EOK;
     
    6161static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
    6262{
    63         int cap = (int) IPC_GET_ARG5(*olddata);
     63        cap_handle_t phone_handle = (cap_handle_t) IPC_GET_ARG5(*olddata);
    6464
    6565        if (IPC_GET_RETVAL(answer->data) != EOK) {
    6666                /* The connection was not accepted */
    6767                answer_cleanup(answer, olddata);
    68         } else if (cap >= 0) {
     68        } else if (phone_handle >= 0) {
    6969                /* The connection was accepted */
    70                 if (phone_connect(cap, &answer->sender->answerbox)) {
    71                         /* Set 'phone hash' as arg5 of response */
     70                if (phone_connect(phone_handle, &answer->sender->answerbox)) {
     71                        /* Set 'phone hash' as ARG5 of response */
     72                        kobject_t *phone_obj = kobject_get(TASK, phone_handle,
     73                            KOBJECT_TYPE_PHONE);
    7274                        IPC_SET_ARG5(answer->data,
    73                             (sysarg_t) phone_get_current(cap));
     75                            (sysarg_t) phone_obj->phone);
     76                        kobject_put(phone_obj);
    7477                } else {
    7578                        /* The answerbox is shutting down. */
  • kernel/generic/src/ipc/ops/stchngath.c

    rdd20cbb r48bcf49  
    4545        task_t *other_task_s;
    4646
    47         phone_t *sender_phone = phone_get_current(IPC_GET_ARG5(call->data));
    48         if (!sender_phone)
     47        kobject_t *sender_obj = kobject_get(TASK, IPC_GET_ARG5(call->data),
     48            KOBJECT_TYPE_PHONE);
     49        if (!sender_obj)
    4950                return ENOENT;
    5051
    51         mutex_lock(&sender_phone->lock);
    52         if (sender_phone->state != IPC_PHONE_CONNECTED) {
    53                 mutex_unlock(&sender_phone->lock);
     52        mutex_lock(&sender_obj->phone->lock);
     53        if (sender_obj->phone->state != IPC_PHONE_CONNECTED) {
     54                mutex_unlock(&sender_obj->phone->lock);
     55                kobject_put(sender_obj);
    5456                return EINVAL;
    5557        }
    5658
    57         other_task_s = sender_phone->callee->task;
     59        other_task_s = sender_obj->phone->callee->task;
    5860
    59         mutex_unlock(&sender_phone->lock);
     61        mutex_unlock(&sender_obj->phone->lock);
    6062
    6163        /* Remember the third party task hash. */
    6264        IPC_SET_ARG5(call->data, (sysarg_t) other_task_s);
    6365
     66        kobject_put(sender_obj);
    6467        return EOK;
    6568}
     
    7174        if (!IPC_GET_RETVAL(answer->data)) {
    7275                /* The recipient authorized the change of state. */
    73                 phone_t *recipient_phone;
    7476                task_t *other_task_s;
    7577                task_t *other_task_r;
    7678
    77                 recipient_phone = phone_get_current(IPC_GET_ARG1(answer->data));
    78                 if (!recipient_phone) {
     79                kobject_t *recipient_obj = kobject_get(TASK,
     80                    IPC_GET_ARG1(answer->data), KOBJECT_TYPE_PHONE);
     81                if (!recipient_obj) {
    7982                        IPC_SET_RETVAL(answer->data, ENOENT);
    8083                        return ENOENT;
    8184                }
    8285
    83                 mutex_lock(&recipient_phone->lock);
    84                 if (recipient_phone->state != IPC_PHONE_CONNECTED) {
    85                         mutex_unlock(&recipient_phone->lock);
     86                mutex_lock(&recipient_obj->phone->lock);
     87                if (recipient_obj->phone->state != IPC_PHONE_CONNECTED) {
     88                        mutex_unlock(&recipient_obj->phone->lock);
    8689                        IPC_SET_RETVAL(answer->data, EINVAL);
     90                        kobject_put(recipient_obj);
    8791                        return EINVAL;
    8892                }
    8993
    90                 other_task_r = recipient_phone->callee->task;
     94                other_task_r = recipient_obj->phone->callee->task;
    9195                other_task_s = (task_t *) IPC_GET_ARG5(*olddata);
    9296
     
    109113                }
    110114
    111                 mutex_unlock(&recipient_phone->lock);
     115                mutex_unlock(&recipient_obj->phone->lock);
     116                kobject_put(recipient_obj);
    112117        }
    113118
  • kernel/generic/src/ipc/sysipc.c

    rdd20cbb r48bcf49  
    260260/** Make a call over IPC and wait for reply.
    261261 *
    262  * @param phone_cap    Phone capability for the call.
     262 * @param handle       Phone capability handle for the call.
    263263 * @param data[inout]  Structure with request/reply data.
    264264 * @param priv         Value to be stored in call->priv.
     
    268268 *
    269269 */
    270 int ipc_req_internal(int phone_cap, ipc_data_t *data, sysarg_t priv)
    271 {
    272         phone_t *phone = phone_get_current(phone_cap);
    273         if (!phone)
     270int ipc_req_internal(cap_handle_t handle, ipc_data_t *data, sysarg_t priv)
     271{
     272        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     273        if (!kobj->phone)
    274274                return ENOENT;
    275275       
     
    278278        memcpy(call->data.args, data->args, sizeof(data->args));
    279279       
    280         int rc = request_preprocess(call, phone);
     280        int rc = request_preprocess(call, kobj->phone);
    281281        if (!rc) {
    282282#ifdef CONFIG_UDEBUG
     
    285285
    286286                ipc_call_hold(call);
    287                 rc = ipc_call_sync(phone, call);
     287                rc = ipc_call_sync(kobj->phone, call);
    288288                spinlock_lock(&call->forget_lock);
    289289                bool forgotten = call->forget;
     
    312312                                assert(rc == EINTR);
    313313                        }
    314                         return rc;     
     314                        kobject_put(kobj);
     315                        return rc;
    315316                }
    316317
     
    321322        memcpy(data->args, call->data.args, sizeof(data->args));
    322323        ipc_call_free(call);
     324        kobject_put(kobj);
    323325       
    324326        return EOK;
     
    346348 * the generic function sys_ipc_call_async_slow().
    347349 *
    348  * @param phone_cap  Phone capability for the call.
    349  * @param imethod    Interface and method of the call.
    350  * @param arg1       Service-defined payload argument.
    351  * @param arg2       Service-defined payload argument.
    352  * @param arg3       Service-defined payload argument.
    353  * @param arg4       Service-defined payload argument.
     350 * @param handle   Phone capability handle for the call.
     351 * @param imethod  Interface and method of the call.
     352 * @param arg1     Service-defined payload argument.
     353 * @param arg2     Service-defined payload argument.
     354 * @param arg3     Service-defined payload argument.
     355 * @param arg4     Service-defined payload argument.
    354356 *
    355357 * @return Call hash on success.
     
    359361 *
    360362 */
    361 sysarg_t sys_ipc_call_async_fast(sysarg_t phone_cap, sysarg_t imethod,
     363sysarg_t sys_ipc_call_async_fast(sysarg_t handle, sysarg_t imethod,
    362364    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
    363365{
    364         phone_t *phone = phone_get_current(phone_cap);
    365         if (!phone)
     366        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     367        if (!kobj)
    366368                return IPC_CALLRET_FATAL;
    367369       
    368         if (check_call_limit(phone))
     370        if (check_call_limit(kobj->phone)) {
     371                kobject_put(kobj);
    369372                return IPC_CALLRET_TEMPORARY;
     373        }
    370374       
    371375        call_t *call = ipc_call_alloc(0);
     
    382386        IPC_SET_ARG5(call->data, 0);
    383387       
    384         int res = request_preprocess(call, phone);
     388        int res = request_preprocess(call, kobj->phone);
    385389       
    386390        if (!res)
    387                 ipc_call(phone, call);
     391                ipc_call(kobj->phone, call);
    388392        else
    389                 ipc_backsend_err(phone, call, res);
    390        
     393                ipc_backsend_err(kobj->phone, call, res);
     394       
     395        kobject_put(kobj);
    391396        return (sysarg_t) call;
    392397}
     
    394399/** Make an asynchronous IPC call allowing to transmit the entire payload.
    395400 *
    396  * @param phone_cap  Phone capability for the call.
    397  * @param data       Userspace address of call data with the request.
     401 * @param handle  Phone capability for the call.
     402 * @param data    Userspace address of call data with the request.
    398403 *
    399404 * @return See sys_ipc_call_async_fast().
    400405 *
    401406 */
    402 sysarg_t sys_ipc_call_async_slow(sysarg_t phone_cap, ipc_data_t *data)
    403 {
    404         phone_t *phone = phone_get_current(phone_cap);
    405         if (!phone)
     407sysarg_t sys_ipc_call_async_slow(sysarg_t handle, ipc_data_t *data)
     408{
     409        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     410        if (!kobj)
    406411                return IPC_CALLRET_FATAL;
    407412
    408         if (check_call_limit(phone))
     413        if (check_call_limit(kobj->phone)) {
     414                kobject_put(kobj);
    409415                return IPC_CALLRET_TEMPORARY;
     416        }
    410417
    411418        call_t *call = ipc_call_alloc(0);
     
    414421        if (rc != 0) {
    415422                ipc_call_free(call);
     423                kobject_put(kobj);
    416424                return (sysarg_t) rc;
    417425        }
    418426       
    419         int res = request_preprocess(call, phone);
     427        int res = request_preprocess(call, kobj->phone);
    420428       
    421429        if (!res)
    422                 ipc_call(phone, call);
     430                ipc_call(kobj->phone, call);
    423431        else
    424                 ipc_backsend_err(phone, call, res);
    425        
     432                ipc_backsend_err(kobj->phone, call, res);
     433       
     434        kobject_put(kobj);
    426435        return (sysarg_t) call;
    427436}
     
    431440 * Common code for both the fast and the slow version.
    432441 *
    433  * @param callid     Hash of the call to forward.
    434  * @param phone_cap  Phone capability to use for forwarding.
    435  * @param imethod    New interface and method to use for the forwarded call.
    436  * @param arg1       New value of the first argument for the forwarded call.
    437  * @param arg2       New value of the second argument for the forwarded call.
    438  * @param arg3       New value of the third argument for the forwarded call.
    439  * @param arg4       New value of the fourth argument for the forwarded call.
    440  * @param arg5       New value of the fifth argument for the forwarded call.
    441  * @param mode       Flags that specify mode of the forward operation.
    442  * @param slow       If true, arg3, arg4 and arg5 are considered. Otherwise
    443  *                   the function considers only the fast version arguments:
    444  *                   i.e. arg1 and arg2.
     442 * @param callid   Hash of the call to forward.
     443 * @param handle   Phone capability to use for forwarding.
     444 * @param imethod  New interface and method to use for the forwarded call.
     445 * @param arg1     New value of the first argument for the forwarded call.
     446 * @param arg2     New value of the second argument for the forwarded call.
     447 * @param arg3     New value of the third argument for the forwarded call.
     448 * @param arg4     New value of the fourth argument for the forwarded call.
     449 * @param arg5     New value of the fifth argument for the forwarded call.
     450 * @param mode     Flags that specify mode of the forward operation.
     451 * @param slow     If true, arg3, arg4 and arg5 are considered. Otherwise
     452 *                 the function considers only the fast version arguments:
     453 *                 i.e. arg1 and arg2.
    445454 *
    446455 * @return 0 on succes, otherwise an error code.
     
    449458 *
    450459 */
    451 static sysarg_t sys_ipc_forward_common(sysarg_t callid, sysarg_t phone_cap,
     460static sysarg_t sys_ipc_forward_common(sysarg_t callid, sysarg_t handle,
    452461    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
    453462    sysarg_t arg4, sysarg_t arg5, unsigned int mode, bool slow)
     
    465474        int rc;
    466475
    467         phone_t *phone = phone_get_current(phone_cap);
    468         if (!phone) {
     476        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     477        if (!kobj) {
    469478                rc = ENOENT;
    470479                goto error;
     
    512521        }
    513522       
    514         rc = ipc_forward(call, phone, &TASK->answerbox, mode);
     523        rc = ipc_forward(call, kobj->phone, &TASK->answerbox, mode);
    515524        if (rc != EOK) {
    516525                after_forward = true;
     
    518527        }
    519528
     529        kobject_put(kobj);
    520530        return EOK;
    521531
     
    528538                ipc_answer(&TASK->answerbox, call);
    529539
     540        if (kobj)
     541                kobject_put(kobj);
    530542        return rc;
    531543}
     
    540552 * arguments are not set and these values are ignored.
    541553 *
    542  * @param callid  Hash of the call to forward.
    543  * @param phoneid Phone handle to use for forwarding.
    544  * @param imethod New interface and method to use for the forwarded call.
    545  * @param arg1    New value of the first argument for the forwarded call.
    546  * @param arg2    New value of the second argument for the forwarded call.
    547  * @param mode    Flags that specify mode of the forward operation.
     554 * @param callid   Hash of the call to forward.
     555 * @param handle  Phone handle to use for forwarding.
     556 * @param imethod  New interface and method to use for the forwarded call.
     557 * @param arg1     New value of the first argument for the forwarded call.
     558 * @param arg2     New value of the second argument for the forwarded call.
     559 * @param mode     Flags that specify mode of the forward operation.
    548560 *
    549561 * @return 0 on succes, otherwise an error code.
    550562 *
    551563 */
    552 sysarg_t sys_ipc_forward_fast(sysarg_t callid, sysarg_t phoneid,
     564sysarg_t sys_ipc_forward_fast(sysarg_t callid, sysarg_t handle,
    553565    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode)
    554566{
    555         return sys_ipc_forward_common(callid, phoneid, imethod, arg1, arg2, 0, 0,
     567        return sys_ipc_forward_common(callid, handle, imethod, arg1, arg2, 0, 0,
    556568            0, mode, false);
    557569}
     
    567579 *
    568580 * @param callid  Hash of the call to forward.
    569  * @param phoneid Phone handle to use for forwarding.
     581 * @param handle Phone handle to use for forwarding.
    570582 * @param data    Userspace address of the new IPC data.
    571583 * @param mode    Flags that specify mode of the forward operation.
     
    574586 *
    575587 */
    576 sysarg_t sys_ipc_forward_slow(sysarg_t callid, sysarg_t phoneid,
     588sysarg_t sys_ipc_forward_slow(sysarg_t callid, sysarg_t handle,
    577589    ipc_data_t *data, unsigned int mode)
    578590{
     
    583595                return (sysarg_t) rc;
    584596       
    585         return sys_ipc_forward_common(callid, phoneid,
     597        return sys_ipc_forward_common(callid, handle,
    586598            IPC_GET_IMETHOD(newdata), IPC_GET_ARG1(newdata),
    587599            IPC_GET_ARG2(newdata), IPC_GET_ARG3(newdata),
     
    681693/** Hang up a phone.
    682694 *
    683  * @param phone_cap  Phone capability of the phone to be hung up.
     695 * @param handle  Phone capability handle of the phone to be hung up.
    684696 *
    685697 * @return 0 on success or an error code.
    686698 *
    687699 */
    688 sysarg_t sys_ipc_hangup(sysarg_t phone_cap)
    689 {
    690         phone_t *phone = phone_get_current(phone_cap);
    691         if (!phone)
     700sysarg_t sys_ipc_hangup(sysarg_t handle)
     701{
     702        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     703        if (!kobj)
    692704                return ENOENT;
    693705       
    694         if (ipc_phone_hangup(phone))
     706        if (ipc_phone_hangup(kobj->phone)) {
     707                kobject_put(kobj);
    695708                return -1;
    696        
     709        }
     710       
     711        kobject_put(kobj);
    697712        return 0;
    698713}
  • kernel/generic/src/proc/task.c

    rdd20cbb r48bcf49  
    239239        if ((ipc_phone_0) &&
    240240            (container_check(ipc_phone_0->task->container, task->container))) {
    241                 int cap = phone_alloc(task);
    242                 assert(cap == 0);
    243                 (void) ipc_phone_connect(phone_get(task, 0), ipc_phone_0);
     241                cap_handle_t phone_handle = phone_alloc(task);
     242                kobject_t *phone_obj = kobject_get(task, phone_handle,
     243                    KOBJECT_TYPE_PHONE);
     244                (void) ipc_phone_connect(phone_obj->phone, ipc_phone_0);
    244245        }
    245246       
Note: See TracChangeset for help on using the changeset viewer.