Changeset 67f11a0 in mainline


Ignore:
Timestamp:
2018-03-15T17:40:20Z (6 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
530f2de, e9e4068
Parents:
30f1a25 (diff), a36f442 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Jakub Jermar <jakub@…> (2018-03-15 17:25:56)
git-committer:
Jakub Jermar <jakub@…> (2018-03-15 17:40:20)
Message:

Merge branch 'noreclaimers'

This commit removes the left-over from the original IPC phone life-cycle
management in which phones were freed lazily during an attempt to
allocate a new phone when the allocator found a hung-up phone with zero
active calls. This mechanism is the reason why kernel objects had to
have the reclaim method. This commit changes the behavior in that phones
are deallocated with their last reference. At the same time it makes
sure that each active call has its own reference on the phone.

This change also makes sure that each connected phone has a capability
via which it can be hung up by the user or cleaned up in ipc_cleanup().
A special mode for phone_alloc() was introduced that allows calls such
as IPC_M_CONNECT_ME_TO and IPC_M_CONNECT_TO_ME to allocate an
unpublished capability and publish it only when the phone is
successfully connected. This fixes a nasty race condition when the user
destroys the capability before the phone is connected and then this
phone becomes essentially invisible for ipc_cleanup().

Last but not least, ipc_cleanup() was slightly streamlined in that it
now knows for how many calls it has to wait from the answerbox's active
call count.

Location:
kernel/generic
Files:
12 edited

Legend:

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

    r30f1a25 r67f11a0  
    6464struct phone;
    6565
    66 struct kobject;
    6766typedef struct kobject_ops {
    68         bool (*reclaim)(struct kobject *);
    6967        void (*destroy)(void *);
    7068} kobject_ops_t;
  • kernel/generic/include/ipc/ipc.h

    r30f1a25 r67f11a0  
    8282        waitq_t wq;
    8383
     84        /**
     85         * Number of answers the answerbox is expecting to eventually arrive.
     86         */
     87        atomic_t active_calls;
     88
    8489        /** Phones connected to this answerbox. */
    8590        list_t connected_phones;
     
    177182extern slab_cache_t *phone_cache;
    178183
    179 extern answerbox_t *ipc_phone_0;
     184extern answerbox_t *ipc_box_0;
    180185
    181186extern void ipc_init(void);
  • kernel/generic/include/ipc/ipcrsc.h

    r30f1a25 r67f11a0  
    4040#include <cap/cap.h>
    4141
    42 extern errno_t phone_alloc(task_t *, cap_handle_t *);
    43 extern bool phone_connect(cap_handle_t, answerbox_t *);
     42extern errno_t phone_alloc(task_t *, bool, cap_handle_t *, kobject_t **);
    4443extern void phone_dealloc(cap_handle_t);
    4544
  • kernel/generic/src/cap/cap.c

    r30f1a25 r67f11a0  
    235235}
    236236
    237 static bool cap_reclaimer(ht_link_t *link, void *arg)
    238 {
    239         cap_t **result = (cap_t **) arg;
    240         cap_t *cap = hash_table_get_inst(link, cap_t, caps_link);
    241 
    242         if (cap->state == CAP_STATE_PUBLISHED && cap->kobject->ops->reclaim &&
    243             cap->kobject->ops->reclaim(cap->kobject)) {
    244                 kobject_t *kobj = cap_unpublish(cap->task, cap->handle,
    245                     cap->kobject->type);
    246                 kobject_put(kobj);
    247                 cap_initialize(cap, cap->task, cap->handle);
    248                 *result = cap;
    249                 return false;
    250         }
    251 
    252         return true;
    253 }
    254 
    255237/** Allocate new capability
    256238 *
     
    263245errno_t cap_alloc(task_t *task, cap_handle_t *handle)
    264246{
    265         cap_t *cap = NULL;
    266 
    267         /*
    268          * First of all, see if we can reclaim a capability. Note that this
    269          * feature is only temporary and capability reclamaition will eventually
    270          * be phased out.
    271          */
    272         mutex_lock(&task->cap_info->lock);
    273         hash_table_apply(&task->cap_info->caps, cap_reclaimer, &cap);
    274 
    275         /*
    276          * If we don't have a capability by now, try to allocate a new one.
    277          */
     247        mutex_lock(&task->cap_info->lock);
     248        cap_t *cap = slab_alloc(cap_cache, FRAME_ATOMIC);
    278249        if (!cap) {
    279                 cap = slab_alloc(cap_cache, FRAME_ATOMIC);
    280                 if (!cap) {
    281                         mutex_unlock(&task->cap_info->lock);
    282                         return ENOMEM;
    283                 }
    284                 uintptr_t hbase;
    285                 if (!ra_alloc(task->cap_info->handles, 1, 1, &hbase)) {
    286                         slab_free(cap_cache, cap);
    287                         mutex_unlock(&task->cap_info->lock);
    288                         return ENOMEM;
    289                 }
    290                 cap_initialize(cap, task, (cap_handle_t) hbase);
    291                 hash_table_insert(&task->cap_info->caps, &cap->caps_link);
    292         }
     250                mutex_unlock(&task->cap_info->lock);
     251                return ENOMEM;
     252        }
     253        uintptr_t hbase;
     254        if (!ra_alloc(task->cap_info->handles, 1, 1, &hbase)) {
     255                slab_free(cap_cache, cap);
     256                mutex_unlock(&task->cap_info->lock);
     257                return ENOMEM;
     258        }
     259        cap_initialize(cap, task, (cap_handle_t) hbase);
     260        hash_table_insert(&task->cap_info->caps, &cap->caps_link);
    293261
    294262        cap->state = CAP_STATE_ALLOCATED;
  • kernel/generic/src/ipc/ipc.c

    r30f1a25 r67f11a0  
    6363static void ipc_forget_call(call_t *);
    6464
    65 /** Open channel that is assigned automatically to new tasks */
    66 answerbox_t *ipc_phone_0 = NULL;
     65/** Answerbox that new tasks are automatically connected to */
     66answerbox_t *ipc_box_0 = NULL;
    6767
    6868static slab_cache_t *call_cache;
     
    147147        list_initialize(&box->answers);
    148148        list_initialize(&box->irq_notifs);
     149        atomic_set(&box->active_calls, 0);
    149150        box->task = task;
    150151}
     
    160161bool ipc_phone_connect(phone_t *phone, answerbox_t *box)
    161162{
    162         bool active;
     163        bool connected;
    163164
    164165        mutex_lock(&phone->lock);
    165166        irq_spinlock_lock(&box->lock, true);
    166167
    167         active = box->active;
    168         if (active) {
     168        connected = box->active && (phone->state == IPC_PHONE_CONNECTING);
     169        if (connected) {
    169170                phone->state = IPC_PHONE_CONNECTED;
    170171                phone->callee = box;
     
    176177        mutex_unlock(&phone->lock);
    177178
    178         if (!active) {
     179        if (!connected) {
    179180                /* We still have phone->kobject's reference; drop it */
    180181                kobject_put(phone->kobject);
    181182        }
    182183
    183         return active;
     184        return connected;
    184185}
    185186
     
    350351        } else {
    351352                atomic_inc(&phone->active_calls);
     353                if (call->callerbox)
     354                        atomic_inc(&call->callerbox->active_calls);
     355                else
     356                        atomic_inc(&caller->answerbox.active_calls);
     357                kobject_add_ref(phone->kobject);
    352358                call->sender = caller;
    353359                call->active = true;
     
    439445/** Disconnect phone from answerbox.
    440446 *
    441  * This call leaves the phone in the HUNGUP state. The change to 'free' is done
    442  * lazily later.
     447 * This call leaves the phone in the hung-up state. The phone is destroyed when
     448 * its last active call is answered and there are no references to it.
    443449 *
    444450 * @param phone Phone structure to be hung up.
     
    563569                list_remove(&request->ab_link);
    564570                atomic_dec(&request->caller_phone->active_calls);
     571                atomic_dec(&box->active_calls);
     572                kobject_put(request->caller_phone->kobject);
    565573        } else if (!list_empty(&box->calls)) {
    566574                /* Count received call */
     
    707715
    708716        atomic_dec(&call->caller_phone->active_calls);
     717        atomic_dec(&TASK->answerbox.active_calls);
     718        kobject_put(call->caller_phone->kobject);
    709719
    710720        SYSIPC_OP(request_forget, call);
     
    746756}
    747757
    748 static bool phone_cap_wait_cb(cap_t *cap, void *arg)
    749 {
    750         phone_t *phone = cap->kobject->phone;
    751         bool *restart = (bool *) arg;
    752 
    753         mutex_lock(&phone->lock);
    754         if ((phone->state == IPC_PHONE_HUNGUP) &&
    755             (atomic_get(&phone->active_calls) == 0)) {
    756                 phone->state = IPC_PHONE_FREE;
    757                 phone->callee = NULL;
    758         }
    759 
    760         /*
    761          * We might have had some IPC_PHONE_CONNECTING phones at the beginning
    762          * of ipc_cleanup(). Depending on whether these were forgotten or
    763          * answered, they will eventually enter the IPC_PHONE_FREE or
    764          * IPC_PHONE_CONNECTED states, respectively.  In the latter case, the
    765          * other side may slam the open phones at any time, in which case we
    766          * will get an IPC_PHONE_SLAMMED phone.
    767          */
    768         if ((phone->state == IPC_PHONE_CONNECTED) ||
    769             (phone->state == IPC_PHONE_SLAMMED)) {
    770                 mutex_unlock(&phone->lock);
    771                 ipc_phone_hangup(phone);
    772                 /*
    773                  * Now there may be one extra active call, which needs to be
    774                  * forgotten.
    775                  */
    776                 ipc_forget_all_active_calls();
    777                 *restart = true;
    778                 return false;
    779         }
    780 
    781         /*
    782          * If the hangup succeeded, it has sent a HANGUP message, the IPC is now
    783          * in HUNGUP state, we wait for the reply to come
    784          */
    785         if (phone->state != IPC_PHONE_FREE) {
    786                 mutex_unlock(&phone->lock);
    787                 return false;
    788         }
    789 
    790         mutex_unlock(&phone->lock);
    791         return true;
    792 }
    793 
    794 /** Wait for all answers to asynchronous calls to arrive. */
    795 static void ipc_wait_for_all_answered_calls(void)
    796 {
    797         call_t *call;
    798         bool restart;
    799 
    800 restart:
    801         /*
    802          * Go through all phones, until they are all free.
    803          * Locking is needed as there may be connection handshakes in progress.
    804          */
    805         restart = false;
    806         if (caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_PHONE,
    807             phone_cap_wait_cb, &restart)) {
    808                 /* Got into cleanup */
    809                 return;
    810         }
    811         if (restart)
    812                 goto restart;
    813 
    814         call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT,
    815             SYNCH_FLAGS_NONE);
    816         assert(call->flags & (IPC_CALL_ANSWERED | IPC_CALL_NOTIF));
    817 
    818         SYSIPC_OP(answer_process, call);
    819 
    820         kobject_put(call->kobject);
    821         goto restart;
    822 }
    823 
    824758static bool phone_cap_cleanup_cb(cap_t *cap, void *arg)
    825759{
     
    830764        cap_free(cap->task, cap->handle);
    831765        return true;
     766}
     767
     768/** Wait for all answers to asynchronous calls to arrive. */
     769static void ipc_wait_for_all_answered_calls(void)
     770{
     771        while (atomic_get(&TASK->answerbox.active_calls) != 0) {
     772                call_t *call = ipc_wait_for_call(&TASK->answerbox,
     773                    SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
     774                assert(call->flags & (IPC_CALL_ANSWERED | IPC_CALL_NOTIF));
     775
     776                SYSIPC_OP(answer_process, call);
     777
     778                kobject_put(call->kobject);
     779
     780                /*
     781                 * Now there may be some new phones and new hangup calls to
     782                 * immediately forget.
     783                 */
     784                caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_PHONE,
     785                    phone_cap_cleanup_cb, NULL);
     786                ipc_forget_all_active_calls();
     787        }
    832788}
    833789
     
    869825        irq_spinlock_unlock(&TASK->answerbox.lock, true);
    870826
    871         /* Disconnect all our phones ('ipc_phone_hangup') */
     827        /* Hangup all phones and destroy all phone capabilities */
    872828        caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_PHONE,
    873829            phone_cap_cleanup_cb, NULL);
    874830
    875         /* Unsubscribe from any event notifications. */
     831        /* Unsubscribe from any event notifications */
    876832        event_cleanup_answerbox(&TASK->answerbox);
    877833
     
    899855        ipc_forget_all_active_calls();
    900856        ipc_wait_for_all_answered_calls();
     857
     858        assert(atomic_get(&TASK->answerbox.active_calls) == 0);
    901859}
    902860
     
    968926                        break;
    969927                case IPC_PHONE_HUNGUP:
    970                         printf("hung up by %p", phone->callee);
     928                        printf("hung up to %p", phone->callee);
    971929                        break;
    972930                default:
     
    1004962        irq_spinlock_lock(&task->lock, true);
    1005963        irq_spinlock_lock(&task->answerbox.lock, false);
     964
     965        printf("Active calls: %" PRIun "\n",
     966            atomic_get(&task->answerbox.active_calls));
    1006967
    1007968#ifdef __32_BITS__
  • kernel/generic/src/ipc/ipcrsc.c

    r30f1a25 r67f11a0  
    3939 *
    4040 * The pattern of usage of the resources is:
    41  * - allocate empty phone capability slot, connect | deallocate slot
     41 * - allocate a capability and phone kernel object (do not publish yet),
     42 *   connect to the answerbox, and finally publish the capability
    4243 * - disconnect connected phone (some messages might be on the fly)
    43  * - find phone in slot and send a message using phone
     44 * - find phone capability and send a message using phone
    4445 * - answer message to phone
    4546 * - hangup phone (the caller has hung up)
     
    5354 *   atomic on all platforms)
    5455 *
    55  * - To find an empty phone capability slot, the TASK must be locked
    5656 * - To answer a message, the answerbox must be locked
    5757 * - The locking of phone and answerbox is done at the ipc_ level.
     
    7373 * *** Connect_me_to ***
    7474 * The caller sends IPC_M_CONNECT_ME_TO to an answerbox. The server receives
    75  * 'phoneid' of the connecting phone as an ARG5. If it answers with RETVAL=0,
    76  * the phonecall is accepted, otherwise it is refused.
     75 * 'phoneid' of the connecting phone as an ARG5. If it answers with RETVAL=EOK,
     76 * the phone call is accepted, otherwise it is refused.
    7777 *
    7878 * *** Connect_to_me ***
    7979 * The caller sends IPC_M_CONNECT_TO_ME.
    8080 * The server receives an automatically opened phoneid. If it accepts
    81  * (RETVAL=0), it can use the phoneid immediately. Possible race condition can
     81 * (RETVAL=EOK), it can use the phoneid immediately. Possible race condition can
    8282 * arise, when the client receives messages from new connection before getting
    8383 * response for connect_to_me message. Userspace should implement handshake
     
    9595 * - The phone is disconnected. EHANGUP response code is sent to the calling
    9696 *   task. All new calls through this phone get a EHUNGUP error code, the task
    97  *   is expected to send an sys_ipc_hangup after cleaning up its internal
     97 *   is expected to call sys_ipc_hangup after cleaning up its internal
    9898 *   structures.
    9999 *
     
    137137#include <mm/slab.h>
    138138
    139 static bool phone_reclaim(kobject_t *kobj)
    140 {
    141         bool gc = false;
    142 
    143         mutex_lock(&kobj->phone->lock);
    144         if (kobj->phone->state == IPC_PHONE_HUNGUP &&
    145             atomic_get(&kobj->phone->active_calls) == 0)
    146                 gc = true;
    147         mutex_unlock(&kobj->phone->lock);
    148 
    149         return gc;
    150 }
    151 
    152139static void phone_destroy(void *arg)
    153140{
     
    157144
    158145static kobject_ops_t phone_kobject_ops = {
    159         .reclaim = phone_reclaim,
    160146        .destroy = phone_destroy
    161147};
     
    164150/** Allocate new phone in the specified task.
    165151 *
    166  * @param task  Task for which to allocate a new phone.
    167  *
    168  * @param[out] out_handle  New phone capability handle.
     152 * @param[in]  task     Task for which to allocate a new phone.
     153 * @param[in]  publish  If true, the new capability will be published.
     154 * @param[out] phandle  New phone capability handle.
     155 * @param[out] kobject  New phone kobject.
    169156 *
    170157 * @return  An error code if a new capability cannot be allocated.
    171158 */
    172 errno_t phone_alloc(task_t *task, cap_handle_t *out_handle)
     159errno_t phone_alloc(task_t *task, bool publish, cap_handle_t *phandle,
     160    kobject_t **kobject)
    173161{
    174162        cap_handle_t handle;
     
    180168                        return ENOMEM;
    181169                }
    182                 kobject_t *kobject = malloc(sizeof(kobject_t), FRAME_ATOMIC);
    183                 if (!kobject) {
     170                kobject_t *kobj = malloc(sizeof(kobject_t), FRAME_ATOMIC);
     171                if (!kobj) {
    184172                        cap_free(TASK, handle);
    185173                        slab_free(phone_cache, phone);
     
    190178                phone->state = IPC_PHONE_CONNECTING;
    191179
    192                 kobject_initialize(kobject, KOBJECT_TYPE_PHONE, phone,
     180                kobject_initialize(kobj, KOBJECT_TYPE_PHONE, phone,
    193181                    &phone_kobject_ops);
    194                 phone->kobject = kobject;
    195 
    196                 cap_publish(task, handle, kobject);
    197 
    198                 *out_handle = handle;
     182                phone->kobject = kobj;
     183
     184                if (publish)
     185                        cap_publish(task, handle, kobj);
     186
     187                *phandle = handle;
     188                if (kobject)
     189                        *kobject = kobj;
    199190        }
    200191        return rc;
     
    214205                return;
    215206
    216         assert(kobj->phone);
    217         assert(kobj->phone->state == IPC_PHONE_CONNECTING);
    218 
    219207        kobject_put(kobj);
    220208        cap_free(TASK, handle);
    221209}
    222210
    223 /** Connect phone to a given answerbox.
    224  *
    225  * @param handle  Capability handle of the phone to be connected.
    226  * @param box     Answerbox to which to connect the phone.
    227  * @return        True if the phone was connected, false otherwise.
    228  */
    229 bool phone_connect(cap_handle_t handle, answerbox_t *box)
    230 {
    231         kobject_t *phone_obj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
    232         if (!phone_obj)
    233                 return false;
    234 
    235         assert(phone_obj->phone->state == IPC_PHONE_CONNECTING);
    236 
    237         /* Hand over phone_obj reference to the answerbox */
    238         return ipc_phone_connect(phone_obj->phone, box);
    239 }
    240 
    241211/** @}
    242212 */
  • kernel/generic/src/ipc/kbox.c

    r30f1a25 r67f11a0  
    253253        /* Allocate a new phone. */
    254254        cap_handle_t phone_handle;
    255         errno_t rc = phone_alloc(TASK, &phone_handle);
     255        errno_t rc = phone_alloc(TASK, true, &phone_handle, NULL);
    256256        if (rc != EOK) {
    257257                mutex_unlock(&task->kb.cleanup_lock);
  • kernel/generic/src/ipc/ops/conctmeto.c

    r30f1a25 r67f11a0  
    4242static errno_t request_preprocess(call_t *call, phone_t *phone)
    4343{
     44        /*
     45         * Create the new phone and capability, but don't publish them yet.
     46         * That will be done once the phone is connected.
     47         */
    4448        cap_handle_t phone_handle;
    45         errno_t rc = phone_alloc(TASK, &phone_handle);
    46 
    47         /* Remember the phone capability or that an error occured. */
    48         call->priv = (rc == EOK) ? phone_handle : -1;
    49 
     49        kobject_t *phone_obj;
     50        errno_t rc = phone_alloc(TASK, false, &phone_handle, &phone_obj);
    5051        if (rc != EOK) {
     52                call->priv = -1;
    5153                return rc;
    5254        }
    5355
    54         /* Set arg5 for server */
    55         kobject_t *phone_obj = kobject_get(TASK, phone_handle,
    56             KOBJECT_TYPE_PHONE);
    5756        /* Hand over phone_obj's reference to ARG5 */
    5857        IPC_SET_ARG5(call->data, (sysarg_t) phone_obj->phone);
     58
     59        /* Remember the handle */
     60        call->priv = phone_handle;
    5961
    6062        return EOK;
     
    6567        cap_handle_t phone_handle = (cap_handle_t) call->priv;
    6668
    67         if (phone_handle < 0) {
     69        if (phone_handle < 0)
    6870                return EOK;
    69         }
    7071
    71         phone_dealloc(phone_handle);
    7272        /* Hand over reference from ARG5 to phone->kobject */
    7373        phone_t *phone = (phone_t *) IPC_GET_ARG5(call->data);
    74         /* Drop phone_obj's reference */
     74        /* Drop phone->kobject's reference */
    7575        kobject_put(phone->kobject);
     76        cap_free(TASK, phone_handle);
     77
    7678        return EOK;
    7779}
     
    8284        phone_t *phone = (phone_t *) IPC_GET_ARG5(*olddata);
    8385
    84         /* If the user accepted call, connect */
     86        /*
     87         * Get an extra reference and pass it in the answer data.
     88         */
     89        kobject_add_ref(phone->kobject);
     90        IPC_SET_ARG5(answer->data, (sysarg_t) phone);
     91
     92        /* If the user accepted the call, connect */
    8593        if (IPC_GET_RETVAL(answer->data) == EOK) {
    8694                /* Hand over reference from phone to the answerbox */
     
    96104{
    97105        cap_handle_t phone_handle = (cap_handle_t) answer->priv;
     106        phone_t *phone = (phone_t *) IPC_GET_ARG5(answer->data);
    98107
    99108        if (IPC_GET_RETVAL(answer->data)) {
    100109                if (phone_handle >= 0) {
    101110                        /*
    102                          * The phone was indeed allocated and now needs
    103                          * to be deallocated.
     111                         * Cleanup the unpublished capability and drop
     112                         * phone->kobject's reference.
    104113                         */
    105                         phone_dealloc(phone_handle);
     114                        kobject_put(phone->kobject);
     115                        cap_free(TASK, phone_handle);
    106116                }
    107117        } else {
     118                /*
     119                 * Publish the capability. Publishing the capability this late
     120                 * is important for ipc_cleanup() where we want to have a
     121                 * capability for each phone that wasn't hung up by the user.
     122                 */
     123                cap_publish(TASK, phone_handle, phone->kobject);
     124
    108125                IPC_SET_ARG5(answer->data, phone_handle);
    109126        }
  • kernel/generic/src/ipc/ops/concttome.c

    r30f1a25 r67f11a0  
    4343{
    4444        cap_handle_t phone_handle;
    45         errno_t rc = phone_alloc(TASK, &phone_handle);
     45        kobject_t *phone_obj;
     46        errno_t rc = phone_alloc(TASK, false, &phone_handle, &phone_obj);
     47        call->priv = (sysarg_t) phone_obj;
    4648        IPC_SET_ARG5(call->data, (rc == EOK) ? phone_handle : -1);
    4749        return 0;
     
    5153{
    5254        cap_handle_t phone_handle = (cap_handle_t) IPC_GET_ARG5(*olddata);
     55        kobject_t *phone_obj = (kobject_t *) answer->priv;
    5356
    54         if (phone_handle >= 0)
    55                 phone_dealloc(phone_handle);
     57        if (phone_handle >= 0) {
     58                kobject_put(phone_obj);
     59                cap_free(TASK, phone_handle);
     60        }
    5661
    5762        return EOK;
     
    6166{
    6267        cap_handle_t phone_handle = (cap_handle_t) IPC_GET_ARG5(*olddata);
     68        kobject_t *phone_obj = (kobject_t *) answer->priv;
    6369
    6470        if (IPC_GET_RETVAL(answer->data) != EOK) {
     
    6672                answer_cleanup(answer, olddata);
    6773        } else if (phone_handle >= 0) {
    68                 /* The connection was accepted */
    69                 if (phone_connect(phone_handle, &answer->sender->answerbox)) {
     74                /*
     75                 * The connection was accepted
     76                 */
     77
     78                /*
     79                 * We need to create another reference as the one we have now
     80                 * will be consumed by ipc_phone_connect().
     81                 */
     82                kobject_add_ref(phone_obj);
     83
     84                if (ipc_phone_connect(phone_obj->phone,
     85                    &answer->sender->answerbox)) {
     86                        /* Pass the reference to the capability */
     87                        cap_publish(TASK, phone_handle, phone_obj);
    7088                        /* Set 'phone hash' as ARG5 of response */
    71                         kobject_t *phone_obj = kobject_get(TASK, phone_handle,
    72                             KOBJECT_TYPE_PHONE);
    7389                        IPC_SET_ARG5(answer->data,
    7490                            (sysarg_t) phone_obj->phone);
    75                         kobject_put(phone_obj);
    7691                } else {
    7792                        /* The answerbox is shutting down. */
  • kernel/generic/src/ipc/sysipc.c

    r30f1a25 r67f11a0  
    724724sys_errno_t sys_ipc_hangup(sysarg_t handle)
    725725{
    726         kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     726        kobject_t *kobj = cap_unpublish(TASK, handle, KOBJECT_TYPE_PHONE);
    727727        if (!kobj)
    728728                return ENOENT;
     
    730730        errno_t rc = ipc_phone_hangup(kobj->phone);
    731731        kobject_put(kobj);
     732        cap_free(TASK, handle);
    732733        return rc;
    733734}
  • kernel/generic/src/main/kinit.c

    r30f1a25 r67f11a0  
    265265                                    PERM_IO_MANAGER | PERM_IRQ_REG);
    266266
    267                                 if (!ipc_phone_0) {
    268                                         ipc_phone_0 = &programs[i].task->answerbox;
     267                                if (!ipc_box_0) {
     268                                        ipc_box_0 = &programs[i].task->answerbox;
    269269                                        /*
    270                                          * Hold the first task so that the
    271                                          * ipc_phone_0 remains a valid pointer
     270                                         * Hold the first task so that
     271                                         * ipc_box_0 remains a valid pointer
    272272                                         * even if the first task exits for
    273273                                         * whatever reason.
  • kernel/generic/src/proc/task.c

    r30f1a25 r67f11a0  
    129129        size_t tasks_left;
    130130
    131         if (ipc_phone_0) {
    132                 task_t *task_0 = ipc_phone_0->task;
    133                 ipc_phone_0 = NULL;
     131        if (ipc_box_0) {
     132                task_t *task_0 = ipc_box_0->task;
     133                ipc_box_0 = NULL;
    134134                /*
    135135                 * The first task is held by kinit(), we need to release it or
     
    243243#endif
    244244
    245         if ((ipc_phone_0) &&
    246             (container_check(ipc_phone_0->task->container, task->container))) {
     245        if ((ipc_box_0) &&
     246            (container_check(ipc_box_0->task->container, task->container))) {
    247247                cap_handle_t phone_handle;
    248                 errno_t rc = phone_alloc(task, &phone_handle);
     248                errno_t rc = phone_alloc(task, true, &phone_handle, NULL);
    249249                if (rc != EOK) {
    250250                        task->as = NULL;
     
    256256                kobject_t *phone_obj = kobject_get(task, phone_handle,
    257257                    KOBJECT_TYPE_PHONE);
    258                 (void) ipc_phone_connect(phone_obj->phone, ipc_phone_0);
     258                (void) ipc_phone_connect(phone_obj->phone, ipc_box_0);
    259259        }
    260260
Note: See TracChangeset for help on using the changeset viewer.