equal
deleted
inserted
replaced
544 // Need a reference on the session, though, in case it goes away. |
544 // Need a reference on the session, though, in case it goes away. |
545 aSession->TotalAccessInc(); |
545 aSession->TotalAccessInc(); |
546 NKern::ThreadEnterCS(); |
546 NKern::ThreadEnterCS(); |
547 NKern::UnlockSystem(); |
547 NKern::UnlockSystem(); |
548 TInt r = KErrNone; |
548 TInt r = KErrNone; |
|
549 TBool anyPins = EFalse; |
|
550 TPinArray pinArray = { { 0, 0, 0, 0 } }; // local, copy to heap later if used |
549 |
551 |
550 for (TInt i = 0; descFlags != 0; ++i, argPinFlags >>= 1, descFlags >>= TIpcArgs::KBitsPerType) |
552 for (TInt i = 0; descFlags != 0; ++i, argPinFlags >>= 1, descFlags >>= TIpcArgs::KBitsPerType) |
551 { |
553 { |
552 __NK_ASSERT_DEBUG(i < KMaxMessageArguments); // Should stop after max args processed. |
554 __NK_ASSERT_DEBUG(i < KMaxMessageArguments); // Should stop after max args processed. |
553 |
555 |
559 // Pin the max length for modifiable descriptors, but only |
561 // Pin the max length for modifiable descriptors, but only |
560 // the current length for non-modifiable descriptors. |
562 // the current length for non-modifiable descriptors. |
561 TUint pinLength = desInfo.IsWriteable() ? desInfo.MaxLength() : desInfo.Length(); |
563 TUint pinLength = desInfo.IsWriteable() ? desInfo.MaxLength() : desInfo.Length(); |
562 if (pinLength) |
564 if (pinLength) |
563 { |
565 { |
564 if (!iPinArray) |
|
565 { |
|
566 iPinArray = new TPinArray; |
|
567 if (!iPinArray) |
|
568 { |
|
569 r = KErrNoMemory; |
|
570 break; |
|
571 } |
|
572 } |
|
573 |
|
574 // This will only create and pin if the descriptor data is paged. |
566 // This will only create and pin if the descriptor data is paged. |
575 // An out-of-memory error here means we fail the whole operation. |
567 // An out-of-memory error here means we fail the whole operation. |
576 r = Kern::CreateAndPinVirtualMemory(iPinArray->iPinPtrs[i], desInfo.DataPtr(), pinLength); |
568 r = Kern::CreateAndPinVirtualMemory(pinArray.iPinPtrs[i], desInfo.DataPtr(), pinLength); |
|
569 if (pinArray.iPinPtrs[i]) |
|
570 anyPins = ETrue; |
577 if (r == KErrNoMemory) |
571 if (r == KErrNoMemory) |
578 break; |
572 break; |
579 if (r != KErrNone) |
573 if (r != KErrNone) |
580 { |
574 { |
581 // For any other error, clear the parameter type and mark the |
575 // For any other error, clear the parameter type and mark the |
587 } |
581 } |
588 } |
582 } |
589 } |
583 } |
590 } |
584 } |
591 |
585 |
|
586 if (anyPins && r != KErrNoMemory) |
|
587 { |
|
588 iPinArray = new TPinArray (pinArray); |
|
589 if (!iPinArray) |
|
590 r = KErrNoMemory; |
|
591 } |
|
592 |
592 if (r == KErrNoMemory) |
593 if (r == KErrNoMemory) |
593 { |
594 { |
594 // Failed to pin everything so clean up any pin objects created. |
595 // Failed to pin everything so clean up any pin objects created. |
595 // This will also unpin any pinned memory. |
596 // This will also unpin any pinned memory. |
596 if (iPinArray) |
597 UnpinMessageArguments(&pinArray); |
597 { |
|
598 UnpinMessageArguments(iPinArray); |
|
599 delete iPinArray; |
|
600 iPinArray = NULL; |
|
601 } |
|
602 } |
598 } |
603 |
599 |
604 NKern::LockSystem(); |
600 NKern::LockSystem(); |
605 |
601 |
606 // Remove the access on the session. |
602 // Remove the access on the session. |
607 if (aSession->TotalAccessDec() == DObject::EObjectDeleted) |
603 if (aSession->TotalAccessDec() == DObject::EObjectDeleted) |
608 {// This was the last access on the session and it has been deleted so |
604 { |
609 // don't access any of its members. |
605 // This was the last access on the session and it has been deleted |
|
606 // so don't access any of its members. |
610 r = KErrDisconnected; |
607 r = KErrDisconnected; |
611 } |
608 } |
612 NKern::ThreadLeaveCS(); |
609 NKern::ThreadLeaveCS(); |
613 return r; |
610 return r; |
614 } |
611 } |