Rev 1342 | Rev 1502 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1342 | Rev 1364 | ||
|---|---|---|---|
| Line 31... | Line 31... | ||
| 31 | * First the answerbox, then the phone |
31 | * First the answerbox, then the phone |
| 32 | */ |
32 | */ |
| 33 | 33 | ||
| 34 | #include <synch/spinlock.h> |
34 | #include <synch/spinlock.h> |
| 35 | #include <synch/waitq.h> |
35 | #include <synch/waitq.h> |
| - | 36 | #include <synch/synch.h> |
|
| 36 | #include <ipc/ipc.h> |
37 | #include <ipc/ipc.h> |
| 37 | #include <errno.h> |
38 | #include <errno.h> |
| 38 | #include <mm/slab.h> |
39 | #include <mm/slab.h> |
| 39 | #include <arch.h> |
40 | #include <arch.h> |
| 40 | #include <proc/task.h> |
41 | #include <proc/task.h> |
| Line 139... | Line 140... | ||
| 139 | 140 | ||
| 140 | /* We will receive data on special box */ |
141 | /* We will receive data on special box */ |
| 141 | request->callerbox = &sync_box; |
142 | request->callerbox = &sync_box; |
| 142 | 143 | ||
| 143 | ipc_call(phone, request); |
144 | ipc_call(phone, request); |
| 144 | ipc_wait_for_call(&sync_box, 0); |
145 | ipc_wait_for_call(&sync_box, SYNCH_NO_TIMEOUT, SYNCH_BLOCKING); |
| 145 | } |
146 | } |
| 146 | 147 | ||
| 147 | /** Answer message that was not dispatched and is not entered in |
148 | /** Answer message that was not dispatched and is not entered in |
| 148 | * any queue |
149 | * any queue |
| 149 | */ |
150 | */ |
| Line 299... | Line 300... | ||
| 299 | } |
300 | } |
| 300 | 301 | ||
| 301 | 302 | ||
| 302 | /** Wait for phone call |
303 | /** Wait for phone call |
| 303 | * |
304 | * |
| - | 305 | * @param box Answerbox expecting the call. |
|
| - | 306 | * @param usec Timeout in microseconds. See documentation for waitq_sleep_timeout() for |
|
| - | 307 | * decription of its special meaning. |
|
| - | 308 | * @param nonblocking Blocking vs. non-blocking operation mode switch. See documentation |
|
| - | 309 | * for waitq_sleep_timeout() for description of its special meaning. |
|
| 304 | * @return Recived message address |
310 | * @return Recived message address |
| 305 | * - to distinguish between call and answer, look at call->flags |
311 | * - to distinguish between call and answer, look at call->flags |
| 306 | */ |
312 | */ |
| 307 | call_t * ipc_wait_for_call(answerbox_t *box, int flags) |
313 | call_t * ipc_wait_for_call(answerbox_t *box, __u32 usec, int nonblocking) |
| 308 | { |
314 | { |
| 309 | call_t *request; |
315 | call_t *request; |
| 310 | ipl_t ipl; |
316 | ipl_t ipl; |
| - | 317 | int rc; |
|
| 311 | 318 | ||
| 312 | restart: |
319 | restart: |
| 313 | if (flags & IPC_WAIT_NONBLOCKING) { |
- | |
| 314 | if (waitq_sleep_timeout(&box->wq,0,1) == ESYNCH_WOULD_BLOCK) |
320 | rc = waitq_sleep_timeout(&box->wq, usec, nonblocking); |
| - | 321 | if (SYNCH_FAILED(rc)) |
|
| 315 | return NULL; |
322 | return NULL; |
| 316 | } else |
- | |
| 317 | waitq_sleep(&box->wq); |
- | |
| 318 | 323 | ||
| 319 | spinlock_lock(&box->lock); |
324 | spinlock_lock(&box->lock); |
| 320 | if (!list_empty(&box->irq_notifs)) { |
325 | if (!list_empty(&box->irq_notifs)) { |
| 321 | ipl = interrupts_disable(); |
326 | ipl = interrupts_disable(); |
| 322 | spinlock_lock(&box->irq_lock); |
327 | spinlock_lock(&box->irq_lock); |
| Line 405... | Line 410... | ||
| 405 | ipc_cleanup_call_list(&task->answerbox.calls); |
410 | ipc_cleanup_call_list(&task->answerbox.calls); |
| 406 | spinlock_unlock(&task->answerbox.lock); |
411 | spinlock_unlock(&task->answerbox.lock); |
| 407 | 412 | ||
| 408 | /* Wait for all async answers to arrive */ |
413 | /* Wait for all async answers to arrive */ |
| 409 | while (atomic_get(&task->active_calls)) { |
414 | while (atomic_get(&task->active_calls)) { |
| 410 | call = ipc_wait_for_call(&task->answerbox, 0); |
415 | call = ipc_wait_for_call(&task->answerbox, SYNCH_NO_TIMEOUT, SYNCH_BLOCKING); |
| 411 | ASSERT((call->flags & IPC_CALL_ANSWERED) || (call->flags & IPC_CALL_NOTIF)); |
416 | ASSERT((call->flags & IPC_CALL_ANSWERED) || (call->flags & IPC_CALL_NOTIF)); |
| 412 | ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC)); |
417 | ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC)); |
| 413 | 418 | ||
| 414 | atomic_dec(&task->active_calls); |
419 | atomic_dec(&task->active_calls); |
| 415 | ipc_call_free(call); |
420 | ipc_call_free(call); |