NOT YET PART OF SEAMONKEY BUILD. added locking

This commit is contained in:
jband%netscape.com 2000-04-18 21:33:46 +00:00
Родитель e1cdbeacdf
Коммит e6a64cb2a6
3 изменённых файлов: 120 добавлений и 72 удалений

Просмотреть файл

@ -82,8 +82,16 @@ xptiInterfaceInfo::~xptiInterfaceInfo()
delete mInterface;
}
PRBool
xptiInterfaceInfo::Resolve(xptiWorkingSet* aWorkingSet)
xptiInterfaceInfo::Resolve(xptiWorkingSet* aWorkingSet /* = nsnull */)
{
nsAutoLock lock(xptiInterfaceInfoManager::GetResolveLock());
return ResolveLocked(aWorkingSet);
}
PRBool
xptiInterfaceInfo::ResolveLocked(xptiWorkingSet* aWorkingSet /* = nsnull */)
{
int resolvedState = GetResolveState();
@ -93,7 +101,7 @@ xptiInterfaceInfo::Resolve(xptiWorkingSet* aWorkingSet)
return PR_FALSE;
xptiInterfaceInfoManager* mgr =
xptiInterfaceInfoManager::GetInterfaceInfoManager();
xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef();
if(!mgr)
return PR_FALSE;
@ -109,17 +117,16 @@ xptiInterfaceInfo::Resolve(xptiWorkingSet* aWorkingSet)
// Make a copy of mTypelib because the underlying memory will change!
xptiTypelib typelib = mTypelib;
// We expect our PartiallyResolve() to get called before this returns.
// We expect our PartiallyResolveLocked() to get called before
// this returns.
if(!mgr->LoadFile(typelib, aWorkingSet))
{
NS_RELEASE(mgr);
SetResolvedState(RESOLVE_FAILED);
return PR_FALSE;
}
// The state was changed by LoadFile to PARTIALLY_RESOLVED, so this
// ...falls through...
}
NS_IF_RELEASE(mgr);
NS_ASSERTION(GetResolveState() == PARTIALLY_RESOLVED, "bad state!");
@ -134,7 +141,7 @@ xptiInterfaceInfo::Resolve(xptiWorkingSet* aWorkingSet)
aWorkingSet->GetTypelibGuts(mInterface->mTypelib)->
GetInfoAtNoAddRef(parent_index - 1);
if(!parent || !parent->EnsureResolved())
if(!parent || !parent->EnsureResolvedLocked())
{
xptiTypelib aTypelib = mInterface->mTypelib;
delete mInterface;
@ -160,8 +167,9 @@ xptiInterfaceInfo::Resolve(xptiWorkingSet* aWorkingSet)
return PR_TRUE;
}
// This *only* gets called by xptiInterfaceInfoManager::LoadFile (while locked).
PRBool
xptiInterfaceInfo::PartiallyResolve(XPTInterfaceDescriptor* aDescriptor,
xptiInterfaceInfo::PartiallyResolveLocked(XPTInterfaceDescriptor* aDescriptor,
xptiWorkingSet* aWorkingSet)
{
NS_ASSERTION(GetResolveState() == NOT_RESOLVED, "bad state");
@ -213,16 +221,9 @@ xptiInterfaceInfo::IsScriptable(PRBool* result)
{
NS_ASSERTION(result, "bad bad caller!");
/*
if(!EnsureResolved())
{
EnsureResolved();
return NS_ERROR_UNEXPECTED;
}
*/
// It is not necessary to Resolve because this info is read from manifest.
NS_ASSERTION(ScriptableFlagIsValid(), "scriptable flag out of sync!");
*result = GetScriptableFlag();
return NS_OK;
}

Просмотреть файл

@ -30,17 +30,19 @@ static xptiInterfaceInfoManager* gInterfaceInfoManager = nsnull;
// static
xptiInterfaceInfoManager*
xptiInterfaceInfoManager::GetInterfaceInfoManager()
xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef()
{
if(!gInterfaceInfoManager)
{
gInterfaceInfoManager = new xptiInterfaceInfoManager();
if(gInterfaceInfoManager)
NS_ADDREF(gInterfaceInfoManager);
if(!gInterfaceInfoManager->mWorkingSet.IsValid())
if(!gInterfaceInfoManager->IsValid())
{
NS_RELEASE(gInterfaceInfoManager);
}
else
{
PRBool mustAutoReg =
!xptiManifest::Read(gInterfaceInfoManager,
&gInterfaceInfoManager->mWorkingSet);
@ -57,8 +59,7 @@ xptiInterfaceInfoManager::GetInterfaceInfoManager()
if(mustAutoReg)
gInterfaceInfoManager->AutoRegisterInterfaces();
}
if(gInterfaceInfoManager)
NS_ADDREF(gInterfaceInfoManager);
}
return gInterfaceInfoManager;
}
@ -71,9 +72,20 @@ xptiInterfaceInfoManager::FreeInterfaceInfoManager()
NS_IF_RELEASE(gInterfaceInfoManager);
}
PRBool
xptiInterfaceInfoManager::IsValid()
{
return mWorkingSet.IsValid() &&
mResolveLock &&
mAutoRegLock;
}
xptiInterfaceInfoManager::xptiInterfaceInfoManager()
: mWorkingSet(),
mOpenLogFile(nsnull)
mOpenLogFile(nsnull),
mResolveLock(PR_NewLock()),
mAutoRegLock(PR_NewLock())
{
NS_INIT_ISUPPORTS();
@ -361,7 +373,7 @@ xptiInterfaceInfoManager::LoadFile(const xptiTypelib& aTypelibRecord,
XPTInterfaceDescriptor* descriptor = iface->interface_descriptor;
if(descriptor && aTypelibRecord.Equals(info->GetTypelibRecord()))
info->PartiallyResolve(descriptor, aWorkingSet);
info->PartiallyResolveLocked(descriptor, aWorkingSet);
}
return PR_TRUE;
}
@ -1059,14 +1071,18 @@ PRBool
xptiInterfaceInfoManager::MergeWorkingSets(xptiWorkingSet* aDestWorkingSet,
xptiWorkingSet* aSrcWorkingSet)
{
// Combine file lists.
PRUint32 i;
// Combine file lists.
PRUint32 originalFileCount = aDestWorkingSet->GetFileCount();
PRUint32 additionalFileCount = aSrcWorkingSet->GetFileCount();
// Create a new array big enough to hold both lists and copy existing files
if(additionalFileCount)
{
if(!aDestWorkingSet->ExtendFileArray(originalFileCount +
additionalFileCount))
return PR_FALSE;
@ -1080,6 +1096,7 @@ xptiInterfaceInfoManager::MergeWorkingSets(xptiWorkingSet* aDestWorkingSet,
additionalFileCount * sizeof(PRUint32));
if(!aDestWorkingSet->mFileMergeOffsetMap)
return PR_FALSE;
}
for(i = 0; i < additionalFileCount; ++i)
{
@ -1117,6 +1134,8 @@ xptiInterfaceInfoManager::MergeWorkingSets(xptiWorkingSet* aDestWorkingSet,
// Create a new array big enough to hold both lists and copy existing ZipItems
if(additionalZipItemCount)
{
if(!aDestWorkingSet->ExtendZipItemArray(originalZipItemCount +
additionalZipItemCount))
return PR_FALSE;
@ -1130,7 +1149,7 @@ xptiInterfaceInfoManager::MergeWorkingSets(xptiWorkingSet* aDestWorkingSet,
additionalZipItemCount * sizeof(PRUint32));
if(!aDestWorkingSet->mZipItemMergeOffsetMap)
return PR_FALSE;
}
for(i = 0; i < additionalZipItemCount; ++i)
{
@ -1439,6 +1458,8 @@ NS_IMETHODIMP xptiInterfaceInfoManager::AutoRegisterInterfaces()
AutoRegMode mode;
PRBool ok;
nsAutoLock lock(xptiInterfaceInfoManager::GetAutoRegLock());
if(!workingSet.IsValid())
return NS_ERROR_UNEXPECTED;
@ -1515,7 +1536,10 @@ NS_IMETHODIMP xptiInterfaceInfoManager::AutoRegisterInterfaces()
XPTI_PUBLIC_API(nsIInterfaceInfoManager*)
XPTI_GetInterfaceInfoManager()
{
return xptiInterfaceInfoManager::GetInterfaceInfoManager();
nsIInterfaceInfoManager* iim =
xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef();
NS_IF_ADDREF(iim);
return iim;
}
XPTI_PUBLIC_API(void)

Просмотреть файл

@ -50,6 +50,8 @@
#include "nsIInputStream.h"
#include "nsIPref.h"
#include "nsAutoLock.h"
#include "plstr.h"
#include "prprf.h"
#include "prio.h"
@ -444,7 +446,7 @@ public:
virtual ~xptiInterfaceInfo();
// We use mName[-1] (cast as a xptiInfoFlags) to hold the two bit state
// below and alos the bit flags that follow. If the states ever grow beyond
// below and also the bit flags that follow. If the states ever grow beyond
// 2 bits then these flags need to be adjusted along with STATE_MASK in
// xptiInfoFlags.
@ -482,7 +484,7 @@ public:
const nsID* GetTheIID() const {return &mIID;}
const char* GetTheName() const {return mName;}
PRBool PartiallyResolve(XPTInterfaceDescriptor* aDescriptor,
PRBool PartiallyResolveLocked(XPTInterfaceDescriptor* aDescriptor,
xptiWorkingSet* aWorkingSet);
void Invalidate()
@ -506,10 +508,17 @@ private:
{NS_ASSERTION(IsValid(),"bad state");
GetFlags().SetState(uint8(state));}
PRBool Resolve(xptiWorkingSet* aWorkingSet = nsnull);
PRBool EnsureResolved(xptiWorkingSet* aWorkingSet = nsnull)
{return IsFullyResolved() ? PR_TRUE : Resolve(aWorkingSet);}
PRBool Resolve(xptiWorkingSet* aWorkingSet = nsnull);
// We only call these "*Locked" varients after locking. This is done to
// allow reentrace as files are loaded and various interfaces resolved
// without having to worry about the locked state.
PRBool EnsureResolvedLocked(xptiWorkingSet* aWorkingSet = nsnull)
{return IsFullyResolved() ? PR_TRUE : ResolveLocked(aWorkingSet);}
PRBool ResolveLocked(xptiWorkingSet* aWorkingSet = nsnull);
PRBool ScriptableFlagIsValid() const
{int s = (int) GetResolveState();
@ -644,7 +653,7 @@ class xptiInterfaceInfoManager
public:
virtual ~xptiInterfaceInfoManager();
static xptiInterfaceInfoManager* GetInterfaceInfoManager();
static xptiInterfaceInfoManager* GetInterfaceInfoManagerNoAddRef();
static void FreeInterfaceInfoManager();
xptiWorkingSet* GetWorkingSet() {return &mWorkingSet;}
@ -657,6 +666,16 @@ public:
PRBool GetComponentsDir(nsILocalFile** aDir);
static PRLock* GetResolveLock(xptiInterfaceInfoManager* self = nsnull)
{if(!self && !(self = GetInterfaceInfoManagerNoAddRef()))
return nsnull;
return self->mResolveLock;}
static PRLock* GetAutoRegLock(xptiInterfaceInfoManager* self = nsnull)
{if(!self && !(self = GetInterfaceInfoManagerNoAddRef()))
return nsnull;
return self->mAutoRegLock;}
static void WriteToLog(const char *fmt, ...);
private:
@ -668,6 +687,8 @@ private:
FULL_VALIDATION_REQUIRED
};
PRBool IsValid();
PRBool BuildFileList(nsISupportsArray** aFileList);
nsILocalFile** BuildOrderedFileArray(nsISupportsArray* aFileList,
@ -703,6 +724,8 @@ private:
nsCOMPtr<nsILocalFile> mStatsLogFile;
nsCOMPtr<nsILocalFile> mAutoRegLogFile;
PRFileDesc* mOpenLogFile;
PRLock* mResolveLock;
PRLock* mAutoRegLock;
};
#endif /* xptiprivate_h___ */