Subversion Repositories HelenOS

Rev

Rev 4439 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4439 Rev 4537
Line 334... Line 334...
334
        answer->buffer = NULL;
334
        answer->buffer = NULL;
335
    }
335
    }
336
    return 0;
336
    return 0;
337
}
337
}
338
 
338
 
-
 
339
static void phones_lock(phone_t *p1, phone_t *p2)
-
 
340
{
-
 
341
    if (p1 < p2) {
-
 
342
        mutex_lock(&p1->lock);
-
 
343
        mutex_lock(&p2->lock);
-
 
344
    } else if (p1 > p2) {
-
 
345
        mutex_lock(&p2->lock);
-
 
346
        mutex_lock(&p1->lock);
-
 
347
    } else {
-
 
348
        mutex_lock(&p1->lock);
-
 
349
    }
-
 
350
}
-
 
351
 
-
 
352
static void phones_unlock(phone_t *p1, phone_t *p2)
-
 
353
{
-
 
354
    mutex_unlock(&p1->lock);
-
 
355
    if (p1 != p2)
-
 
356
        mutex_unlock(&p2->lock);
-
 
357
}
-
 
358
 
339
/** Called before the request is sent.
359
/** Called before the request is sent.
340
 *
360
 *
341
 * @param call      Call structure with the request.
361
 * @param call      Call structure with the request.
342
 * @param phone     Phone that the call will be sent through.
362
 * @param phone     Phone that the call will be sent through.
343
 *
363
 *
Line 353... Line 373...
353
    switch (IPC_GET_METHOD(call->data)) {
373
    switch (IPC_GET_METHOD(call->data)) {
354
    case IPC_M_CONNECTION_CLONE: {
374
    case IPC_M_CONNECTION_CLONE: {
355
        phone_t *cloned_phone;
375
        phone_t *cloned_phone;
356
        GET_CHECK_PHONE(cloned_phone, IPC_GET_ARG1(call->data),
376
        GET_CHECK_PHONE(cloned_phone, IPC_GET_ARG1(call->data),
357
            return ENOENT);
377
            return ENOENT);
358
        if (cloned_phone < phone) {
-
 
359
            mutex_lock(&cloned_phone->lock);
378
        phones_lock(cloned_phone, phone);
360
            mutex_lock(&phone->lock);
-
 
361
        } else if (cloned_phone > phone) {
-
 
362
            mutex_lock(&phone->lock);
-
 
363
            mutex_lock(&cloned_phone->lock);
-
 
364
        } else {
-
 
365
            mutex_lock(&phone->lock);
-
 
366
        }
-
 
367
        if ((cloned_phone->state != IPC_PHONE_CONNECTED) ||
379
        if ((cloned_phone->state != IPC_PHONE_CONNECTED) ||
368
            phone->state != IPC_PHONE_CONNECTED) {
380
            phone->state != IPC_PHONE_CONNECTED) {
369
            if (cloned_phone != phone)
-
 
370
                mutex_unlock(&cloned_phone->lock);
381
            phones_unlock(cloned_phone, phone);
371
            mutex_unlock(&phone->lock);
-
 
372
            return EINVAL;
382
            return EINVAL;
373
        }
383
        }
374
        /*
384
        /*
375
         * We can be pretty sure now that both tasks exist and we are
385
         * We can be pretty sure now that both tasks exist and we are
376
         * connected to them. As we continue to hold the phone locks,
386
         * connected to them. As we continue to hold the phone locks,
377
         * we are effectively preventing them from finishing their
387
         * we are effectively preventing them from finishing their
378
         * potential cleanup.
388
         * potential cleanup.
379
         */
389
         */
380
        newphid = phone_alloc(phone->callee->task);
390
        newphid = phone_alloc(phone->callee->task);
381
        if (newphid < 0) {
391
        if (newphid < 0) {
382
            if (cloned_phone != phone)
-
 
383
                mutex_unlock(&cloned_phone->lock);
392
            phones_unlock(cloned_phone, phone);
384
            mutex_unlock(&phone->lock);
-
 
385
            return ELIMIT;
393
            return ELIMIT;
386
        }
394
        }
387
        ipc_phone_connect(&phone->callee->task->phones[newphid],
395
        ipc_phone_connect(&phone->callee->task->phones[newphid],
388
            cloned_phone->callee);
396
            cloned_phone->callee);
389
        if (cloned_phone != phone)
-
 
390
            mutex_unlock(&cloned_phone->lock);
397
        phones_unlock(cloned_phone, phone);
391
        mutex_unlock(&phone->lock);
-
 
392
        /* Set the new phone for the callee. */
398
        /* Set the new phone for the callee. */
393
        IPC_SET_ARG1(call->data, newphid);
399
        IPC_SET_ARG1(call->data, newphid);
394
        break;
400
        break;
395
    }
401
    }
396
    case IPC_M_CONNECT_ME:
402
    case IPC_M_CONNECT_ME: