Changeset fbcfd458 in mainline for generic/src/ipc/ipc.c
- Timestamp:
- 2006-03-18T23:02:08Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b4b45210
- Parents:
- ba81cab
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/src/ipc/ipc.c
rba81cab rfbcfd458 124 124 } 125 125 126 /** Disconnect phone from answerbox127 *128 * It is allowed to call disconnect on already disconnected phone\129 */130 void ipc_phone_destroy(phone_t *phone)131 {132 answerbox_t *box = phone->callee;133 134 ASSERT(box);135 136 spinlock_lock(&phone->lock);137 spinlock_lock(&box->lock);138 139 if (phone->callee) {140 list_remove(&phone->list);141 phone->callee = NULL;142 }143 144 spinlock_unlock(&box->lock);145 spinlock_unlock(&phone->lock);146 }147 148 126 /** Helper function to facilitate synchronous calls */ 149 127 void ipc_call_sync(phone_t *phone, call_t *request) … … 191 169 } 192 170 171 /* Unsafe unchecking ipc_call */ 172 static void _ipc_call(phone_t *phone, answerbox_t *box, call_t *call) 173 { 174 atomic_inc(&phone->active_calls); 175 call->data.phone = phone; 176 177 spinlock_lock(&box->lock); 178 list_append(&call->list, &box->calls); 179 spinlock_unlock(&box->lock); 180 waitq_wakeup(&box->wq, 0); 181 } 182 193 183 /** Send a asynchronous request using phone to answerbox 194 184 * … … 201 191 202 192 spinlock_lock(&phone->lock); 193 203 194 box = phone->callee; 204 195 if (!box) { 205 196 /* Trying to send over disconnected phone */ 197 spinlock_unlock(&phone->lock); 198 199 call->data.phone = phone; 206 200 IPC_SET_RETVAL(call->data, ENOENT); 207 201 _ipc_answer_free_call(call); 208 202 return; 209 203 } 210 211 spinlock_lock(&box->lock); 212 list_append(&call->list, &box->calls); 213 spinlock_unlock(&box->lock); 214 waitq_wakeup(&box->wq, 0); 204 _ipc_call(phone, box, call); 215 205 216 206 spinlock_unlock(&phone->lock); 207 } 208 209 /** Disconnect phone from answerbox 210 * 211 * It is allowed to call disconnect on already disconnected phone 212 * 213 * @return 0 - phone disconnected, -1 - the phone was already disconnected 214 */ 215 int ipc_phone_hangup(phone_t *phone) 216 { 217 answerbox_t *box; 218 call_t *call; 219 220 spinlock_lock(&phone->lock); 221 box = phone->callee; 222 if (!box) { 223 spinlock_unlock(&phone->lock); 224 return -1; 225 } 226 227 spinlock_lock(&box->lock); 228 list_remove(&phone->list); 229 phone->callee = NULL; 230 spinlock_unlock(&box->lock); 231 232 call = ipc_call_alloc(); 233 IPC_SET_METHOD(call->data, IPC_M_PHONE_HUNGUP); 234 call->flags |= IPC_CALL_DISCARD_ANSWER; 235 _ipc_call(phone, box, call); 236 237 phone->busy = 0; 238 239 spinlock_unlock(&phone->lock); 240 241 return 0; 217 242 } 218 243 … … 226 251 { 227 252 spinlock_lock(&oldbox->lock); 253 atomic_dec(&call->data.phone->active_calls); 228 254 list_remove(&call->list); 229 255 spinlock_unlock(&oldbox->lock); … … 242 268 call_t *request; 243 269 244 spinlock_lock(&box->lock); 245 while (1) { 246 if (!list_empty(&box->answers)) { 247 /* Handle asynchronous answers */ 248 request = list_get_instance(box->answers.next, call_t, list); 249 list_remove(&request->list); 250 } else if (!list_empty(&box->calls)) { 251 /* Handle requests */ 252 request = list_get_instance(box->calls.next, call_t, list); 253 list_remove(&request->list); 254 /* Append request to dispatch queue */ 255 list_append(&request->list, &box->dispatched_calls); 256 request->flags |= IPC_CALL_DISPATCHED; 257 } else { 258 if (!(flags & IPC_WAIT_NONBLOCKING)) { 259 /* Wait for event to appear */ 260 spinlock_unlock(&box->lock); 261 waitq_sleep(&box->wq); 262 spinlock_lock(&box->lock); 263 continue; 264 } 265 request = NULL; 266 } 267 break; 270 restart: 271 if (flags & IPC_WAIT_NONBLOCKING) { 272 if (waitq_sleep_timeout(&box->wq,0,1) == ESYNCH_WOULD_BLOCK) 273 return NULL; 274 } else 275 waitq_sleep(&box->wq); 276 277 spinlock_lock(&box->lock); 278 if (!list_empty(&box->answers)) { 279 /* Handle asynchronous answers */ 280 request = list_get_instance(box->answers.next, call_t, list); 281 list_remove(&request->list); 282 printf("%d %P\n", IPC_GET_METHOD(request->data), 283 request->data.phone); 284 atomic_dec(&request->data.phone->active_calls); 285 } else if (!list_empty(&box->calls)) { 286 /* Handle requests */ 287 request = list_get_instance(box->calls.next, call_t, list); 288 list_remove(&request->list); 289 /* Append request to dispatch queue */ 290 list_append(&request->list, &box->dispatched_calls); 291 request->flags |= IPC_CALL_DISPATCHED; 292 } else { 293 printf("WARNING: Spurious IPC wakeup.\n"); 294 spinlock_unlock(&box->lock); 295 goto restart; 268 296 } 269 297 spinlock_unlock(&box->lock);
Note:
See TracChangeset
for help on using the changeset viewer.