--- a/kernel/eka/drivers/resourceman/rescontrol_export.cpp Thu Aug 19 11:14:22 2010 +0300
+++ b/kernel/eka/drivers/resourceman/rescontrol_export.cpp Tue Aug 31 16:34:26 2010 +0300
@@ -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());