Ignore:
File:
1 edited

Legend:

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

    ra35b458 raadde10  
    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 */
Note: See TracChangeset for help on using the changeset viewer.