Changes in kernel/generic/src/ipc/ipc.c [f97f1e51:cd529c4] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/ipc.c
rf97f1e51 rcd529c4 71 71 { 72 72 memsetb(call, sizeof(*call), 0); 73 call->callerbox = &TASK->answerbox;74 73 call->sender = TASK; 75 74 call->buffer = NULL; … … 120 119 irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock"); 121 120 waitq_initialize(&box->wq); 122 link_initialize(&box->sync_box_link);123 121 list_initialize(&box->connected_phones); 124 122 list_initialize(&box->calls); … … 163 161 } 164 162 165 /** Helper function to facilitate synchronous calls.166 *167 * @param phone Destination kernel phone structure.168 * @param request Call structure with request.169 *170 * @return EOK on success or EINTR if the sleep was interrupted.171 *172 */173 int ipc_call_sync(phone_t *phone, call_t *request)174 {175 answerbox_t *sync_box = slab_alloc(ipc_answerbox_slab, 0);176 ipc_answerbox_init(sync_box, TASK);177 178 /*179 * Put the answerbox on the TASK's list of synchronous answerboxes so180 * that it can be cleaned up if the call is interrupted.181 */182 irq_spinlock_lock(&TASK->lock, true);183 list_append(&sync_box->sync_box_link, &TASK->sync_boxes);184 irq_spinlock_unlock(&TASK->lock, true);185 186 /* We will receive data in a special box. */187 request->callerbox = sync_box;188 189 ipc_call(phone, request);190 if (!ipc_wait_for_call(sync_box, SYNCH_NO_TIMEOUT,191 SYNCH_FLAGS_INTERRUPTIBLE)) {192 /* The answerbox and the call will be freed by ipc_cleanup(). */193 return EINTR;194 }195 196 /*197 * The answer arrived without interruption so we can remove the198 * answerbox from the TASK's list of synchronous answerboxes.199 */200 irq_spinlock_lock(&TASK->lock, true);201 list_remove(&sync_box->sync_box_link);202 irq_spinlock_unlock(&TASK->lock, true);203 204 slab_free(ipc_answerbox_slab, sync_box);205 return EOK;206 }207 208 163 /** Answer a message which was not dispatched and is not listed in any queue. 209 164 * … … 214 169 static void _ipc_answer_free_call(call_t *call, bool selflocked) 215 170 { 216 answerbox_t *callerbox = call->callerbox;171 answerbox_t *callerbox = &call->sender->answerbox; 217 172 bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox)); 218 173 … … 606 561 ipc_cleanup_call_list(&TASK->answerbox.calls); 607 562 irq_spinlock_unlock(&TASK->answerbox.lock, true); 608 609 /* Wait for all answers to interrupted synchronous calls to arrive */610 ipl_t ipl = interrupts_disable();611 while (!list_empty(&TASK->sync_boxes)) {612 answerbox_t *box = list_get_instance(613 list_first(&TASK->sync_boxes), answerbox_t, sync_box_link);614 615 list_remove(&box->sync_box_link);616 call_t *call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,617 SYNCH_FLAGS_NONE);618 ipc_call_free(call);619 slab_free(ipc_answerbox_slab, box);620 }621 interrupts_restore(ipl);622 563 623 564 /* Wait for all answers to asynchronous calls to arrive */
Note:
See TracChangeset
for help on using the changeset viewer.