Changes in kernel/generic/src/ipc/ipcrsc.c [aadde10:a35b458] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/ipcrsc.c
raadde10 ra35b458 39 39 * 40 40 * 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 43 42 * - disconnect connected phone (some messages might be on the fly) 44 * - find phone capabilityand send a message using phone43 * - find phone in slot and send a message using phone 45 44 * - answer message to phone 46 45 * - hangup phone (the caller has hung up) … … 54 53 * atomic on all platforms) 55 54 * 55 * - To find an empty phone capability slot, the TASK must be locked 56 56 * - To answer a message, the answerbox must be locked 57 57 * - The locking of phone and answerbox is done at the ipc_ level. … … 73 73 * *** Connect_me_to *** 74 74 * 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 75 * 'phoneid' of the connecting phone as an ARG5. If it answers with RETVAL=0, 76 * the phonecall is accepted, otherwise it is refused. 77 77 * 78 78 * *** Connect_to_me *** 79 79 * The caller sends IPC_M_CONNECT_TO_ME. 80 80 * The server receives an automatically opened phoneid. If it accepts 81 * (RETVAL= EOK), it can use the phoneid immediately.Possible race condition can81 * (RETVAL=0), it can use the phoneid immediately. Possible race condition can 82 82 * arise, when the client receives messages from new connection before getting 83 83 * response for connect_to_me message. Userspace should implement handshake … … 95 95 * - The phone is disconnected. EHANGUP response code is sent to the calling 96 96 * task. All new calls through this phone get a EHUNGUP error code, the task 97 * is expected to callsys_ipc_hangup after cleaning up its internal97 * is expected to send an sys_ipc_hangup after cleaning up its internal 98 98 * structures. 99 99 * … … 137 137 #include <mm/slab.h> 138 138 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 139 152 static void phone_destroy(void *arg) 140 153 { … … 144 157 145 158 static kobject_ops_t phone_kobject_ops = { 159 .reclaim = phone_reclaim, 146 160 .destroy = phone_destroy 147 161 }; … … 150 164 /** Allocate new phone in the specified task. 151 165 * 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. 156 169 * 157 170 * @return An error code if a new capability cannot be allocated. 158 171 */ 159 errno_t phone_alloc(task_t *task, bool publish, cap_handle_t *phandle, 160 kobject_t **kobject) 172 errno_t phone_alloc(task_t *task, cap_handle_t *out_handle) 161 173 { 162 174 cap_handle_t handle; … … 168 180 return ENOMEM; 169 181 } 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) { 172 184 cap_free(TASK, handle); 173 185 slab_free(phone_cache, phone); … … 178 190 phone->state = IPC_PHONE_CONNECTING; 179 191 180 kobject_initialize(kobj , KOBJECT_TYPE_PHONE, phone,192 kobject_initialize(kobject, KOBJECT_TYPE_PHONE, phone, 181 193 &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; 190 199 } 191 200 return rc; … … 205 214 return; 206 215 216 assert(kobj->phone); 217 assert(kobj->phone->state == IPC_PHONE_CONNECTING); 218 207 219 kobject_put(kobj); 208 220 cap_free(TASK, handle); 209 221 } 210 222 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 211 241 /** @} 212 242 */
Note:
See TracChangeset
for help on using the changeset viewer.