Subversion Repositories HelenOS-historic

Rev

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);