kernel/eka/drivers/resourceman/rescontrol_export.cpp
changeset 244 a77889bee936
parent 0 a41df078684a
child 257 3e88ff8f41d5
--- a/kernel/eka/drivers/resourceman/rescontrol_export.cpp	Fri Aug 06 16:34:38 2010 +0100
+++ b/kernel/eka/drivers/resourceman/rescontrol_export.cpp	Thu Aug 12 11:55:14 2010 +0100
@@ -12,7 +12,7 @@
 //
 // Description:
 // e32\drivers\resourceman\rescontrol_export.cpp
-// 
+//
 //
 
 #include <drivers/resourcecontrol.h>
@@ -55,7 +55,7 @@
 	if(!pRC)
 		return KErrNotFound;
 	pRC->Lock();
-    CHECK_CONTEXT(thread)
+    CHECK_CONTEXT(thread);
 	//Accept the postboot level only if issued before controller is fully initialised.
 	if(pRC->iInitialised == EResConStartupCompleted)
 		{
@@ -66,15 +66,15 @@
 #ifndef PRM_ENABLE_EXTENDED_VERSION
     // coverity[deref_ptr]
     // aResId is checked to be more than the array entries before dereferencing pRC->iStaticResourceArray
-	if((!aResId) || (aResId > pRC->iStaticResourceArrayEntries) || (!pRC->iStaticResourceArray[aResId-1]))
+	if((!aResId) || (aResId > (TUint)pRC->iStaticResourceArray.Count()) || (!pRC->iStaticResourceArray[aResId-1]))
 		{
 		pRC->UnLock();
 		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
 		return KErrNotFound;
 		}
 #else
-	if(!aResId || ((aResId & KIdMaskResourceWithDependencies) && ((aResId & ID_INDEX_BIT_MASK) > pRC->iStaticResDependencyCount)) 
-				|| (!(aResId & KIdMaskResourceWithDependencies) && ((aResId > pRC->iStaticResourceArrayEntries)
+	if(!aResId || ((aResId & KIdMaskResourceWithDependencies) && ((aResId & ID_INDEX_BIT_MASK) > (TUint)pRC->iStaticResDependencyArray.Count())) 
+				|| (!(aResId & KIdMaskResourceWithDependencies) && ((aResId > (TUint)pRC->iStaticResourceArray.Count())
 				|| (!pRC->iStaticResourceArray[aResId-1]))))
 		{
 		pRC->UnLock();
@@ -90,7 +90,7 @@
 		}
 	else
 #endif
-    if(pRC->iStaticResourceArray) 
+    if((TUint)pRC->iStaticResourceArray.Count() > aResId - 1)
 		{
 		DStaticPowerResource* pR=pRC->iStaticResourceArray[--aResId];
 		pR->iPostBootLevel=aLevel;
@@ -107,7 +107,9 @@
 	Kernel extensions or variants can call this API to register the static resources before resource controller
 	is fully initialised.
 	@Param aClientId             ID of the client that is requesting resource registration
-	@Param aStaticResourceArray  Static resources to register with RC. 
+	@Param aStaticResourceArray  Static resources to register with RC.
+	                             Note, that in the special case, when aResCount equals to one, this parameter is treated as a pointer to the
+	                             DStaticPowerResource (DStaticPowerResource*). Otherwise - is the pointer to array of such pointers (DStaticPowerResource*).
 	@Param aResCount             Number of static resources to register with RC. This equals the size of the passed array.
 	@return KErrNone, if operation is success
 	        KErrAccessDenied if clientId could not be found in the current list of registered clients or if this
@@ -127,7 +129,7 @@
 
 	if(!aStaticResourceArray || (aResCount == 0))
 		return KErrArgument;
-    CHECK_CONTEXT(thread)
+	CHECK_CONTEXT(thread);
 	//Accept the registration of static resource only if issued before controller is fully initialised.
 	if(pRC->iInitialised == EResConStartupCompleted)
 		{
@@ -139,10 +141,10 @@
 		return KErrNotSupported;
 		}
 #ifdef PRM_ENABLE_EXTENDED_VERSION
+	// if aResCount equals to 1 aStaticResourceArray contains not an array, but simply a pointer to the resource.
 	if(aResCount == 1)
 		{
-		if((((DStaticPowerResource*)aStaticResourceArray)->iResourceId & KIdMaskResourceWithDependencies) ||
-										(((DStaticPowerResource*)aStaticResourceArray)->iResourceId & KIdMaskDynamic))
+		if(((DStaticPowerResource*)aStaticResourceArray)->iResourceId & (KIdMaskResourceWithDependencies | KIdMaskDynamic))
 			{
 			return KErrNotSupported;
 			}
@@ -151,56 +153,60 @@
 		{
 		for(TUint rescount = 0; rescount < aResCount; rescount++)
 			{
-			if(aStaticResourceArray[rescount] && ((aStaticResourceArray[rescount]->iResourceId & KIdMaskResourceWithDependencies) || 
-				                          (aStaticResourceArray[rescount]->iResourceId & KIdMaskDynamic)))
+			if(aStaticResourceArray[rescount] &&
+			  (aStaticResourceArray[rescount]->iResourceId & (KIdMaskResourceWithDependencies | KIdMaskDynamic)))
 				{
 				return KErrNotSupported;
 				}
 			}
 		}
 #endif
-	SPowerResourceClient* pC = pRC->iClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];								
-	if(!pC)																										
-		{																										
-		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found"));											
-		return KErrAccessDenied;																		
-		}																										
-	if(pC->iClientId != aClientId)				
-		{																										
-		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID instance count does not match"));						
-		return KErrAccessDenied;																		
-		}																										
-	if(pC->iClientId & CLIENT_THREAD_RELATIVE_BIT_MASK)															
-		{																										
-		if(pC->iThreadId != thread.iId)																				
-			{																									
-			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client not called from thread context(Thread Relative)"));	
-			return KErrAccessDenied;																	
-			}																									
+	SPowerResourceClient* pC = pRC->iClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];
+	if(!pC)
+		{
+		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found"));
+		return KErrAccessDenied;
+		}
+	if(pC->iClientId != aClientId)
+		{
+		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID instance count does not match"));
+		return KErrAccessDenied;
 		}
- 
-    TInt r = Kern::SafeReAlloc((TAny*&)pRC->iStaticResourceArray, pRC->iStaticResourceArrayEntries*sizeof(DStaticPowerResource*), 
-		                                         (pRC->iStaticResourceArrayEntries + aResCount)*sizeof(DStaticPowerResource*));
-    if(r != KErrNone)
+	if(pC->iClientId & CLIENT_THREAD_RELATIVE_BIT_MASK)
 		{
-        return r;
+		if(pC->iThreadId != thread.iId)
+			{
+			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client not called from thread context(Thread Relative)"));
+			return KErrAccessDenied;
+			}
 		}
+
+    TInt r = KErrNone;
 	if(aResCount == 1)
 		{
-		pRC->iStaticResourceArray[pRC->iStaticResourceArrayEntries++] = (DStaticPowerResource*)aStaticResourceArray;
-		if((DStaticPowerResource*)aStaticResourceArray)
+		// if aResCount equals to one, threat the pointer as a pointer to resource
+		r = pRC->iStaticResourceArray.Append((DStaticPowerResource*)aStaticResourceArray);
+		// increment count of valid resources
+		if(r == KErrNone && aStaticResourceArray)
 			pRC->iStaticResourceCount++;
 		}
 	else
 		{
 		for(TUint count = 0; count < aResCount; count++)
 			{
-			pRC->iStaticResourceArray[pRC->iStaticResourceArrayEntries++] = aStaticResourceArray[count];
+			r = pRC->iStaticResourceArray.Append(aStaticResourceArray[count]);
+			if(r != KErrNone)
+				{
+				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Could not add new static resources, r = %d", r));
+				break;
+				}
+			// increment count of valid resources
 			if(aStaticResourceArray[count])
 				pRC->iStaticResourceCount++;
 			}
 		}
-    return KErrNone;
+
+	return r;
 	}
 
 /**
@@ -229,6 +235,10 @@
 	This function initialises the controller. 
 	@return KErrNone, if operation is success or one of the system wide errors.
 	*/
+RPointerArray <DStaticPowerResource> *StaticResourceArrayPtr;
+#ifdef PRM_ENABLE_EXTENDED_VERSION
+RPointerArray <DStaticPowerResourceD> *StaticResourceDependencyArrayPtr;
+#endif
 EXPORT_C TInt DPowerResourceController::InitController()
 	{
     __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::InitController()"));
@@ -252,13 +262,31 @@
 	if(!pRC->iMsgQDependency)
 		return KErrNoMemory;
 #endif
-	// Call PSL to create all static resources and populate the iStaticResourceArray with pointers to resources and
-	// update static resource count
-    r=pRC->DoRegisterStaticResources(pRC->iStaticResourceArray, pRC->iStaticResourceArrayEntries);
-    if(r!=KErrNone)
+	// This method can be called in two situations - before the constructor of DPowerResourceController was called 
+	// for the second time (placement new in the extension psl entry macro) e.g. as a result of the call to InitResources() 
+	// from the variant::Init3() method) or after that.
+
+	// In order not to make any assumption on number of constructor invocations, a copy (binary) of the iStaticResourceArray object 
+	// is created below, so that it could be used to later restore the original iStaticResoureceArray object if the constructor
+	// was called after this method. The reason for that is, that in this destructor calls the default RPointerArrayBase()
+	// which resets the array, i.e. it looses the information, but allocated area and pointers still exist in the memory. 
+	// It is then valid to restore the object directly (which will copy all members, including iSize and iEntries pointers). 
+	// This temporary object will be deleted in DPowerResourceController::InitResources() at the last stage of initialization.
+	// (see also comments in DPowerResourceController::DPowerResourceController()) 
+
+	StaticResourceArrayPtr = new RPointerArray <DStaticPowerResource>;
+	if(!StaticResourceArrayPtr)
+		return KErrNoMemory;
+
+	r = pRC->DoRegisterStaticResources(pRC->iStaticResourceArray);
+	if(r != KErrNone)
 		return r;
-	//Get the actual number of static resource registered count
-	for(TInt resCnt = 0; resCnt < pRC->iStaticResourceArrayEntries; resCnt++)
+
+	// make a copy (see above comment)
+	*StaticResourceArrayPtr = pRC->iStaticResourceArray; 
+
+	// Get the actual number of static resource registered count
+	for(TInt resCnt = 0; resCnt < pRC->iStaticResourceArray.Count(); resCnt++)
 		{
 		if(pRC->iStaticResourceArray[resCnt])
 			pRC->iStaticResourceCount++;
@@ -269,7 +297,7 @@
 	DStaticPowerResource* pR = NULL;
 	TPowerResourceInfoBuf01 resInfo;
 	TPowerResourceInfoV01 *pResInfo;
-	for(TInt resCount = 0; resCount < pRC->iStaticResourceArrayEntries; resCount++)
+	for(TInt resCount = 0; resCount < pRC->iStaticResourceArray.Count(); resCount++)
 		{
 		pR = pRC->iStaticResourceArray[resCount];
 		if(!pR)
@@ -281,16 +309,25 @@
 #endif
 
 #ifdef PRM_ENABLE_EXTENDED_VERSION
-	//Call PSL to register static resources with dependency if any exists
-	r = pRC->DoRegisterStaticResourcesDependency(pRC->iStaticResDependencyArray, pRC->iStaticResDependencyCount);
+	StaticResourceDependencyArrayPtr = new RPointerArray <DStaticPowerResourceD>;
+	if(!StaticResourceDependencyArrayPtr)
+		return KErrNoMemory;
+
+	// Call PSL to register static resources with dependency if any exists
+	r = pRC->DoRegisterStaticResourcesDependency(pRC->iStaticResDependencyArray);
+
 	if(r != KErrNone)
 		return r;
-	if(pRC->iStaticResDependencyCount)
+
+	// make a copy (see above comments for StaticResourceArrayPtr)
+	*StaticResourceDependencyArrayPtr = pRC->iStaticResDependencyArray;
+
+	if(pRC->iStaticResDependencyArray.Count())
 		{
 		DStaticPowerResourceD* pRD = NULL;
 		TUint count;
 		//Assign resource index in resource id
-		for(count = 0; count < pRC->iStaticResDependencyCount; count++)
+		for(count = 0; count < (TUint)pRC->iStaticResDependencyArray.Count(); count++)
 			{
 			pRD = pRC->iStaticResDependencyArray[count];
 			if(!pRD)
@@ -298,7 +335,7 @@
 			pRD->iResourceId |= ((count + 1) & ID_INDEX_BIT_MASK);
 			}
 		//Check for dependency closed loops
-		for(count = 0; count < pRC->iStaticResDependencyCount; count++)
+		for(count = 0; count < (TUint)pRC->iStaticResDependencyArray.Count(); count++)
 			{
 			pRD = pRC->iStaticResDependencyArray[count];
 			if(!(pRD->iResourceId & KIdMaskStaticWithDependencies))
@@ -309,7 +346,7 @@
 			pRC->CheckForDependencyLoop(pRD, pRD->iResourceId, pRD->iResourceId);
 			}
 #ifdef PRM_INSTRUMENTATION_MACRO
-		for(count = 0; count < pRC->iStaticResDependencyCount; count++)
+		for(count = 0; count < (TUint)pRC->iStaticResDependencyArray.Count(); count++)
 			{
 			pR = pRC->iStaticResDependencyArray[count];
 			pR->GetInfo((TDes8*)resInfo.Ptr());