kernel/eka/kernel/sipc.cpp
changeset 45 329ab0095843
parent 43 96e5fb8b040d
equal deleted inserted replaced
44:36bfc973b146 45:329ab0095843
   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 	}