Changeset 48bcf49 in mainline for kernel/generic/src/ipc/ipcrsc.c
- Timestamp:
- 2017-09-28T22:08:15Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6636fb19
- Parents:
- dd20cbb
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/ipcrsc.c
rdd20cbb r48bcf49 164 164 } 165 165 166 /** Get phone from the current task by capability handle. 167 * 168 * @param handle Phone capability handle. 169 * @param phone Place to store pointer to phone. 170 * 171 * @return Address of the phone kernel object. 172 * @return NULL if the capability is invalid. 173 * 174 */ 175 phone_t *phone_get(task_t *task, int handle) 176 { 177 phone_t *phone; 178 179 caps_lock(task); 180 cap_t *cap = cap_get(task, handle, CAP_TYPE_PHONE); 181 phone = (phone_t *) cap->kobject; 182 caps_unlock(task); 183 if (!cap) 184 return NULL; 185 186 return phone; 187 } 188 189 phone_t *phone_get_current(int handle) 190 { 191 return phone_get(TASK, handle); 192 } 193 194 static bool phone_can_reclaim(cap_t *cap) 195 { 196 assert(cap->type == CAP_TYPE_PHONE); 197 198 phone_t *phone = (phone_t *) cap->kobject; 199 200 return (phone->state == IPC_PHONE_HUNGUP) && 201 (atomic_get(&phone->active_calls) == 0); 202 } 166 static bool phone_reclaim(kobject_t *kobj) 167 { 168 bool gc = false; 169 170 mutex_lock(&kobj->phone->lock); 171 if (kobj->phone->state == IPC_PHONE_HUNGUP && 172 atomic_get(&kobj->phone->active_calls) == 0) 173 gc = true; 174 mutex_unlock(&kobj->phone->lock); 175 176 return gc; 177 } 178 179 static void phone_destroy(void *arg) 180 { 181 phone_t *phone = (phone_t *) arg; 182 slab_free(phone_slab, phone); 183 } 184 185 static kobject_ops_t phone_kobject_ops = { 186 .reclaim = phone_reclaim, 187 .destroy = phone_destroy 188 }; 189 203 190 204 191 /** Allocate new phone in the specified task. … … 209 196 * @return Negative error code if a new capability cannot be allocated. 210 197 */ 211 int phone_alloc(task_t *task)212 { 213 int handle = cap_alloc(task);198 cap_handle_t phone_alloc(task_t *task) 199 { 200 cap_handle_t handle = cap_alloc(task); 214 201 if (handle >= 0) { 215 202 phone_t *phone = slab_alloc(phone_slab, FRAME_ATOMIC); … … 218 205 return ENOMEM; 219 206 } 220 207 kobject_t *kobject = malloc(sizeof(kobject_t), FRAME_ATOMIC); 208 if (!kobject) { 209 cap_free(TASK, handle); 210 slab_free(phone_slab, phone); 211 return ENOMEM; 212 } 213 221 214 ipc_phone_init(phone, task); 222 215 phone->state = IPC_PHONE_CONNECTING; 216 217 kobject_initialize(kobject, KOBJECT_TYPE_PHONE, phone, 218 &phone_kobject_ops); 219 phone->kobject = kobject; 223 220 224 // FIXME: phase this out eventually 225 mutex_lock(&task->cap_info->lock); 226 cap_t *cap = cap_get(task, handle, CAP_TYPE_ALLOCATED); 227 cap->can_reclaim = phone_can_reclaim; 228 mutex_unlock(&task->cap_info->lock); 229 230 cap_publish(task, handle, CAP_TYPE_PHONE, phone); 221 cap_publish(task, handle, kobject); 231 222 } 232 223 … … 241 232 * 242 233 */ 243 void phone_dealloc(int handle) 244 { 245 cap_t *cap = cap_unpublish(TASK, handle, CAP_TYPE_PHONE); 246 assert(cap); 247 248 phone_t *phone = (phone_t *) cap->kobject; 249 250 assert(phone); 251 assert(phone->state == IPC_PHONE_CONNECTING); 252 253 slab_free(phone_slab, phone); 234 void phone_dealloc(cap_handle_t handle) 235 { 236 kobject_t *kobj = cap_unpublish(TASK, handle, KOBJECT_TYPE_PHONE); 237 if (!kobj) 238 return; 239 240 assert(kobj->phone); 241 assert(kobj->phone->state == IPC_PHONE_CONNECTING); 242 243 kobject_put(kobj); 254 244 cap_free(TASK, handle); 255 245 } … … 260 250 * @param box Answerbox to which to connect the phone. 261 251 * @return True if the phone was connected, false otherwise. 262 * 263 * The procedure _enforces_ that the user first marks the phone busy (e.g. via 264 * phone_alloc) and then connects the phone, otherwise race condition may 265 * appear. 266 * 267 */ 268 bool phone_connect(int handle, answerbox_t *box) 269 { 270 phone_t *phone = phone_get_current(handle); 271 272 assert(phone); 273 assert(phone->state == IPC_PHONE_CONNECTING); 274 275 return ipc_phone_connect(phone, box); 252 */ 253 bool phone_connect(cap_handle_t handle, answerbox_t *box) 254 { 255 kobject_t *phone_obj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE); 256 if (!phone_obj) 257 return false; 258 259 assert(phone_obj->phone->state == IPC_PHONE_CONNECTING); 260 261 /* Hand over phone_obj reference to the answerbox */ 262 return ipc_phone_connect(phone_obj->phone, box); 276 263 } 277 264
Note:
See TracChangeset
for help on using the changeset viewer.