Changeset 50dd854 in mainline


Ignore:
Timestamp:
2018-03-13T18:01:48Z (6 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
334c103
Parents:
1b4196d
git-author:
Jakub Jermar <jakub@…> (2018-03-10 17:56:32)
git-committer:
Jakub Jermar <jakub@…> (2018-03-13 18:01:48)
Message:

Publish capability only after phone connects

In IPC_M_CONNECT_ME_TO it is desirable to publish the new phone
capability only after the phone gets connected. Otherwise we might have
open phones without capabilities and no way to hang them up in
ipc_cleanup().

File:
1 edited

Legend:

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

    r1b4196d r50dd854  
    4444        cap_handle_t phone_handle;
    4545        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 
    5046        if (rc != EOK) {
     47                call->priv = -1;
    5148                return rc;
    5249        }
    5350
    54         /* Set ARG5 for server */
    55         kobject_t *phone_obj = kobject_get(TASK, phone_handle,
     51        /*
     52         * The capability is now published, but the phone is not connected yet.
     53         * The user cannot use it to send anything over it, in fact the
     54         * userspace can only unpublish and free the capability at this point.
     55         *
     56         * We now proceed to test the capability is still there. We don't care
     57         * if the user destroyed the old one and recreated a new published one
     58         * of the same type under the same handle.
     59         *
     60         * If the capability is in place we temporarily unpublish it to make
     61         * sure the user cannot fiddle with it while we are connecting.
     62         */
     63
     64        kobject_t *phone_obj = cap_unpublish(TASK, phone_handle,
    5665            KOBJECT_TYPE_PHONE);
    5766        if (!phone_obj) {
     
    6372                return ENOENT;
    6473        }
     74
    6575        /* Hand over phone_obj's reference to ARG5 */
    6676        IPC_SET_ARG5(call->data, (sysarg_t) phone_obj->phone);
     77
     78        /* Remember the handle */
     79        call->priv = phone_handle;
    6780
    6881        return EOK;
     
    7386        cap_handle_t phone_handle = (cap_handle_t) call->priv;
    7487
    75         if (phone_handle < 0) {
     88        if (phone_handle < 0)
    7689                return EOK;
    77         }
    7890
    79         phone_dealloc(phone_handle);
    8091        /* Hand over reference from ARG5 to phone->kobject */
    8192        phone_t *phone = (phone_t *) IPC_GET_ARG5(call->data);
    82         /* Drop phone_obj's reference */
     93        /* Drop phone->kobject's reference */
    8394        kobject_put(phone->kobject);
     95        cap_free(TASK, phone_handle);
     96
    8497        return EOK;
    8598}
     
    90103        phone_t *phone = (phone_t *) IPC_GET_ARG5(*olddata);
    91104
    92         /* If the user accepted call, connect */
     105        /*
     106         * Get an extra reference and pass it in the answer data.
     107         */
     108        kobject_add_ref(phone->kobject);
     109        IPC_SET_ARG5(answer->data, (sysarg_t) phone);
     110
     111        /* If the user accepted the call, connect */
    93112        if (IPC_GET_RETVAL(answer->data) == EOK) {
    94113                /* Hand over reference from phone to the answerbox */
     
    104123{
    105124        cap_handle_t phone_handle = (cap_handle_t) answer->priv;
     125        phone_t *phone = (phone_t *) IPC_GET_ARG5(answer->data);
    106126
    107127        if (IPC_GET_RETVAL(answer->data)) {
    108128                if (phone_handle >= 0) {
    109129                        /*
    110                          * The phone was indeed allocated and now needs
    111                          * to be deallocated.
     130                         * Cleanup the unpublished capability and drop
     131                         * phone->kobject's reference.
    112132                         */
    113                         phone_dealloc(phone_handle);
     133                        kobject_put(phone->kobject);
     134                        cap_free(TASK, phone_handle);
    114135                }
    115136        } else {
     137                /*
     138                 * Publish the capability. Publishing the capability this late
     139                 * is important for ipc_cleanup() where we want to have a
     140                 * capability for each phone that wasn't hung up by the user.
     141                 */
     142                cap_publish(TASK, phone_handle, phone->kobject);
     143
    116144                IPC_SET_ARG5(answer->data, phone_handle);
    117145        }
Note: See TracChangeset for help on using the changeset viewer.