Changeset 43e2cbc in mainline for kernel/generic/src/ipc/ipc.c
- Timestamp:
- 2016-09-10T13:56:43Z (9 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0b00599
- Parents:
- 838ea8aa
- File:
-
- 1 edited
-
kernel/generic/src/ipc/ipc.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/ipc.c
r838ea8aa r43e2cbc 59 59 #include <ipc/irq.h> 60 60 61 static void ipc_forget_call(call_t *); 62 61 63 /** Open channel that is assigned automatically to new tasks */ 62 64 answerbox_t *ipc_phone_0 = NULL; … … 209 211 return rc; 210 212 } 211 // TODO: forget the call if interrupted 212 (void) ipc_wait_for_call(mybox, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE); 213 214 call_t *answer = ipc_wait_for_call(mybox, SYNCH_NO_TIMEOUT, 215 SYNCH_FLAGS_INTERRUPTIBLE); 216 if (!answer) { 217 218 /* 219 * The sleep was interrupted. 220 * 221 * There are two possibilities now: 222 * 1) the call gets answered before we manage to forget it 223 * 2) we manage to forget the call before it gets answered 224 */ 225 226 spinlock_lock(&request->forget_lock); 227 spinlock_lock(&TASK->active_calls_lock); 228 229 ASSERT(!request->forget); 230 231 bool answered = !request->active; 232 if (!answered) { 233 /* 234 * The call is not yet answered and we won the race to 235 * forget it. 236 */ 237 ipc_forget_call(request); /* releases locks */ 238 rc = EINTR; 239 240 } else { 241 spinlock_unlock(&TASK->active_calls_lock); 242 spinlock_unlock(&request->forget_lock); 243 } 244 245 if (answered) { 246 /* 247 * The other side won the race to answer the call. 248 * It is safe to wait for the answer uninterruptibly 249 * now. 250 */ 251 answer = ipc_wait_for_call(mybox, SYNCH_NO_TIMEOUT, 252 SYNCH_FLAGS_NONE); 253 } 254 } 255 ASSERT(!answer || request == answer); 213 256 214 257 slab_free(ipc_answerbox_slab, mybox); 215 return EOK;258 return rc; 216 259 } 217 260 … … 621 664 } 622 665 666 static void ipc_forget_call(call_t *call) 667 { 668 ASSERT(spinlock_locked(&TASK->active_calls_lock)); 669 ASSERT(spinlock_locked(&call->forget_lock)); 670 671 /* 672 * Forget the call and donate it to the task which holds up the answer. 673 */ 674 675 call->forget = true; 676 call->sender = NULL; 677 list_remove(&call->ta_link); 678 679 /* 680 * The call may be freed by _ipc_answer_free_call() before we are done 681 * with it; to avoid working with a destroyed call_t structure, we 682 * must hold a reference to it. 683 */ 684 ipc_call_hold(call); 685 686 spinlock_unlock(&call->forget_lock); 687 spinlock_unlock(&TASK->active_calls_lock); 688 689 atomic_dec(&call->caller_phone->active_calls); 690 691 SYSIPC_OP(request_forget, call); 692 693 ipc_call_release(call); 694 } 695 623 696 static void ipc_forget_all_active_calls(void) 624 697 { … … 649 722 } 650 723 651 /* 652 * Forget the call and donate it to the task which holds up the answer. 653 */ 654 655 call->forget = true; 656 call->sender = NULL; 657 list_remove(&call->ta_link); 658 659 /* 660 * The call may be freed by _ipc_answer_free_call() before we are done 661 * with it; to avoid working with a destroyed call_t structure, we 662 * must hold a reference to it. 663 */ 664 ipc_call_hold(call); 665 666 spinlock_unlock(&call->forget_lock); 667 spinlock_unlock(&TASK->active_calls_lock); 668 669 atomic_dec(&call->caller_phone->active_calls); 670 671 SYSIPC_OP(request_forget, call); 672 673 ipc_call_release(call); 724 ipc_forget_call(call); 674 725 675 726 goto restart;
Note:
See TracChangeset
for help on using the changeset viewer.
