Ignore:
File:
1 edited

Legend:

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

    raadde10 ra35b458  
    3939 *
    4040 * The pattern of usage of the resources is:
    41  * - allocate a capability and phone kernel object (do not publish yet),
    42  *   connect to the answerbox, and finally publish the capability
     41 * - allocate empty phone capability slot, connect | deallocate slot
    4342 * - disconnect connected phone (some messages might be on the fly)
    44  * - find phone capability and send a message using phone
     43 * - find phone in slot and send a message using phone
    4544 * - answer message to phone
    4645 * - hangup phone (the caller has hung up)
     
    5453 *   atomic on all platforms)
    5554 *
     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=EOK,
    76  * the phone call is accepted, otherwise it is refused.
     75 * 'phoneid' of the connecting phone as an ARG5. If it answers with RETVAL=0,
     76 * the phonecall 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=EOK), it can use the phoneid immediately. Possible race condition can
     81 * (RETVAL=0), 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 call sys_ipc_hangup after cleaning up its internal
     97 *   is expected to send an sys_ipc_hangup after cleaning up its internal
    9898 *   structures.
    9999 *
     
    137137#include <mm/slab.h>
    138138
     139static 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
    139152static void phone_destroy(void *arg)
    140153{
     
    144157
    145158static kobject_ops_t phone_kobject_ops = {
     159        .reclaim = phone_reclaim,
    146160        .destroy = phone_destroy
    147161};
     
    150164/** Allocate new phone in the specified task.
    151165 *
    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.
     166 * @param task  Task for which to allocate a new phone.
     167 *
     168 * @param[out] out_handle  New phone capability handle.
    156169 *
    157170 * @return  An error code if a new capability cannot be allocated.
    158171 */
    159 errno_t phone_alloc(task_t *task, bool publish, cap_handle_t *phandle,
    160     kobject_t **kobject)
     172errno_t phone_alloc(task_t *task, cap_handle_t *out_handle)
    161173{
    162174        cap_handle_t handle;
     
    168180                        return ENOMEM;
    169181                }
    170                 kobject_t *kobj = malloc(sizeof(kobject_t), FRAME_ATOMIC);
    171                 if (!kobj) {
     182                kobject_t *kobject = malloc(sizeof(kobject_t), FRAME_ATOMIC);
     183                if (!kobject) {
    172184                        cap_free(TASK, handle);
    173185                        slab_free(phone_cache, phone);
     
    178190                phone->state = IPC_PHONE_CONNECTING;
    179191
    180                 kobject_initialize(kobj, KOBJECT_TYPE_PHONE, phone,
     192                kobject_initialize(kobject, KOBJECT_TYPE_PHONE, phone,
    181193                    &phone_kobject_ops);
    182                 phone->kobject = kobj;
    183 
    184                 if (publish)
    185                         cap_publish(task, handle, kobj);
    186 
    187                 *phandle = handle;
    188                 if (kobject)
    189                         *kobject = kobj;
     194                phone->kobject = kobject;
     195
     196                cap_publish(task, handle, kobject);
     197
     198                *out_handle = handle;
    190199        }
    191200        return rc;
     
    205214                return;
    206215
     216        assert(kobj->phone);
     217        assert(kobj->phone->state == IPC_PHONE_CONNECTING);
     218
    207219        kobject_put(kobj);
    208220        cap_free(TASK, handle);
    209221}
    210222
     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 */
     229bool 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
    211241/** @}
    212242 */
Note: See TracChangeset for help on using the changeset viewer.