mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Protect the xptiWorkingSet's tables with a lock. (Bug 627985, bug 614480); r=dbaron,bsmedberg
This commit is contained in:
parent
cfaae0f225
commit
30255aeb19
@ -619,7 +619,10 @@ xptiInterfaceEntry::HasAncestor(const nsIID * iid, PRBool *_retval)
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetInterfaceInfo(xptiInterfaceInfo** info)
|
||||
{
|
||||
MonitorAutoEnter lock(xptiInterfaceInfoManager::GetInfoMonitor());
|
||||
#ifdef DEBUG
|
||||
xptiInterfaceInfoManager::GetSingleton()->GetWorkingSet()->mTableMonitor.
|
||||
AssertCurrentThreadIn();
|
||||
#endif
|
||||
LOG_INFO_MONITOR_ENTRY;
|
||||
|
||||
if(!mInfo)
|
||||
@ -646,6 +649,19 @@ xptiInterfaceEntry::LockedInvalidateInterfaceInfo()
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
xptiInterfaceInfo::BuildParent()
|
||||
{
|
||||
mozilla::MonitorAutoEnter monitor(xptiInterfaceInfoManager::GetSingleton()->
|
||||
GetWorkingSet()->mTableMonitor);
|
||||
NS_ASSERTION(mEntry &&
|
||||
mEntry->IsFullyResolved() &&
|
||||
!mParent &&
|
||||
mEntry->Parent(),
|
||||
"bad BuildParent call");
|
||||
return NS_SUCCEEDED(mEntry->Parent()->GetInterfaceInfo(&mParent));
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE1(xptiInterfaceInfo, nsIInterfaceInfo)
|
||||
@ -679,9 +695,11 @@ xptiInterfaceInfo::Release(void)
|
||||
NS_LOG_RELEASE(this, cnt, "xptiInterfaceInfo");
|
||||
if(!cnt)
|
||||
{
|
||||
MonitorAutoEnter lock(xptiInterfaceInfoManager::GetInfoMonitor());
|
||||
mozilla::MonitorAutoEnter monitor(xptiInterfaceInfoManager::
|
||||
GetSingleton()->GetWorkingSet()->
|
||||
mTableMonitor);
|
||||
LOG_INFO_MONITOR_ENTRY;
|
||||
|
||||
|
||||
// If GetInterfaceInfo added and *released* a reference before we
|
||||
// acquired the monitor then 'this' might already be dead. In that
|
||||
// case we would not want to try to access any instance data. We
|
||||
@ -695,7 +713,7 @@ xptiInterfaceInfo::Release(void)
|
||||
// then we want to bail out of here without destorying the object.
|
||||
if(mRefCnt)
|
||||
return 1;
|
||||
|
||||
|
||||
if(mEntry)
|
||||
{
|
||||
mEntry->LockedInterfaceInfoDeathNotification();
|
||||
|
@ -80,8 +80,6 @@ xptiInterfaceInfoManager::FreeInterfaceInfoManager()
|
||||
xptiInterfaceInfoManager::xptiInterfaceInfoManager()
|
||||
: mWorkingSet(),
|
||||
mResolveLock("xptiInterfaceInfoManager.mResolveLock"),
|
||||
mAutoRegLock("xptiInterfaceInfoManager.mAutoRegLock"), // FIXME: unused!
|
||||
mInfoMonitor("xptiInterfaceInfoManager.mInfoMonitor"),
|
||||
mAdditionalManagersLock(
|
||||
"xptiInterfaceInfoManager.mAdditionalManagersLock")
|
||||
{
|
||||
@ -235,6 +233,7 @@ xptiInterfaceInfoManager::RegisterXPTHeader(XPTHeader* aHeader)
|
||||
|
||||
xptiTypelibGuts* typelib = xptiTypelibGuts::Create(aHeader);
|
||||
|
||||
MonitorAutoEnter monitor(mWorkingSet.mTableMonitor);
|
||||
for(PRUint16 k = 0; k < aHeader->num_interfaces; k++)
|
||||
VerifyAndAddEntryIfNew(aHeader->interface_directory + k, k, typelib);
|
||||
}
|
||||
@ -255,6 +254,7 @@ xptiInterfaceInfoManager::VerifyAndAddEntryIfNew(XPTInterfaceDirectoryEntry* ifa
|
||||
if (!iface->interface_descriptor)
|
||||
return;
|
||||
|
||||
mWorkingSet.mTableMonitor.AssertCurrentThreadIn();
|
||||
xptiInterfaceEntry* entry = mWorkingSet.mIIDTable.Get(iface->iid);
|
||||
if (entry) {
|
||||
// XXX validate this info to find possible inconsistencies
|
||||
@ -306,6 +306,7 @@ EntryToInfo(xptiInterfaceEntry* entry, nsIInterfaceInfo **_retval)
|
||||
xptiInterfaceEntry*
|
||||
xptiInterfaceInfoManager::GetInterfaceEntryForIID(const nsIID *iid)
|
||||
{
|
||||
MonitorAutoEnter monitor(mWorkingSet.mTableMonitor);
|
||||
return mWorkingSet.mIIDTable.Get(*iid);
|
||||
}
|
||||
|
||||
@ -315,7 +316,8 @@ NS_IMETHODIMP xptiInterfaceInfoManager::GetInfoForIID(const nsIID * iid, nsIInte
|
||||
NS_ASSERTION(iid, "bad param");
|
||||
NS_ASSERTION(_retval, "bad param");
|
||||
|
||||
xptiInterfaceEntry* entry = GetInterfaceEntryForIID(iid);
|
||||
MonitorAutoEnter monitor(mWorkingSet.mTableMonitor);
|
||||
xptiInterfaceEntry* entry = mWorkingSet.mIIDTable.Get(*iid);
|
||||
return EntryToInfo(entry, _retval);
|
||||
}
|
||||
|
||||
@ -325,6 +327,7 @@ NS_IMETHODIMP xptiInterfaceInfoManager::GetInfoForName(const char *name, nsIInte
|
||||
NS_ASSERTION(name, "bad param");
|
||||
NS_ASSERTION(_retval, "bad param");
|
||||
|
||||
MonitorAutoEnter monitor(mWorkingSet.mTableMonitor);
|
||||
xptiInterfaceEntry* entry = mWorkingSet.mNameTable.Get(name);
|
||||
return EntryToInfo(entry, _retval);
|
||||
}
|
||||
@ -335,7 +338,7 @@ NS_IMETHODIMP xptiInterfaceInfoManager::GetIIDForName(const char *name, nsIID *
|
||||
NS_ASSERTION(name, "bad param");
|
||||
NS_ASSERTION(_retval, "bad param");
|
||||
|
||||
|
||||
MonitorAutoEnter monitor(mWorkingSet.mTableMonitor);
|
||||
xptiInterfaceEntry* entry = mWorkingSet.mNameTable.Get(name);
|
||||
if (!entry) {
|
||||
*_retval = nsnull;
|
||||
@ -351,6 +354,7 @@ NS_IMETHODIMP xptiInterfaceInfoManager::GetNameForIID(const nsIID * iid, char **
|
||||
NS_ASSERTION(iid, "bad param");
|
||||
NS_ASSERTION(_retval, "bad param");
|
||||
|
||||
MonitorAutoEnter monitor(mWorkingSet.mTableMonitor);
|
||||
xptiInterfaceEntry* entry = mWorkingSet.mIIDTable.Get(*iid);
|
||||
if (!entry) {
|
||||
*_retval = nsnull;
|
||||
@ -384,6 +388,7 @@ NS_IMETHODIMP xptiInterfaceInfoManager::EnumerateInterfaces(nsIEnumerator **_ret
|
||||
if (!array)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
MonitorAutoEnter monitor(mWorkingSet.mTableMonitor);
|
||||
mWorkingSet.mNameTable.EnumerateRead(xpti_ArrayAppender, array);
|
||||
|
||||
return array->Enumerate(_retval);
|
||||
@ -419,6 +424,7 @@ NS_IMETHODIMP xptiInterfaceInfoManager::EnumerateInterfacesWhoseNamesStartWith(c
|
||||
if (!array)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
MonitorAutoEnter monitor(mWorkingSet.mTableMonitor);
|
||||
ArrayAndPrefix args = {array, prefix, PL_strlen(prefix)};
|
||||
mWorkingSet.mNameTable.EnumerateRead(xpti_ArrayPrefixAppender, &args);
|
||||
|
||||
|
@ -41,6 +41,8 @@
|
||||
|
||||
#include "xptiprivate.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// static
|
||||
xptiTypelibGuts*
|
||||
xptiTypelibGuts::Create(XPTHeader* aHeader)
|
||||
@ -73,10 +75,13 @@ xptiTypelibGuts::GetEntryAt(PRUint16 i)
|
||||
xptiWorkingSet* set =
|
||||
xptiInterfaceInfoManager::GetSingleton()->GetWorkingSet();
|
||||
|
||||
if (iface->iid.Equals(zeroIID))
|
||||
r = set->mNameTable.Get(iface->name);
|
||||
else
|
||||
r = set->mIIDTable.Get(iface->iid);
|
||||
{
|
||||
MonitorAutoEnter monitor(set->mTableMonitor);
|
||||
if (iface->iid.Equals(zeroIID))
|
||||
r = set->mNameTable.Get(iface->name);
|
||||
else
|
||||
r = set->mIIDTable.Get(iface->iid);
|
||||
}
|
||||
|
||||
if (r)
|
||||
SetEntryAt(i, r);
|
||||
|
@ -48,6 +48,7 @@ using namespace mozilla;
|
||||
#define XPTI_HASHTABLE_SIZE 2048
|
||||
|
||||
xptiWorkingSet::xptiWorkingSet()
|
||||
: mTableMonitor("xptiWorkingSet::mTableMonitor")
|
||||
{
|
||||
MOZ_COUNT_CTOR(xptiWorkingSet);
|
||||
|
||||
@ -68,7 +69,7 @@ xpti_Invalidator(const char* keyname, xptiInterfaceEntry* entry, void* arg)
|
||||
void
|
||||
xptiWorkingSet::InvalidateInterfaceInfos()
|
||||
{
|
||||
MonitorAutoEnter lock(xptiInterfaceInfoManager::GetInfoMonitor());
|
||||
MonitorAutoEnter monitor(mTableMonitor);
|
||||
mNameTable.EnumerateRead(xpti_Invalidator, NULL);
|
||||
}
|
||||
|
||||
|
@ -180,6 +180,11 @@ private:
|
||||
|
||||
public:
|
||||
// XXX make these private with accessors
|
||||
// mTableMonitor must be held across:
|
||||
// * any read from or write to mIIDTable or mNameTable
|
||||
// * any writing to the links between an xptiInterfaceEntry
|
||||
// and its xptiInterfaceInfo (mEntry/mInfo)
|
||||
mozilla::Monitor mTableMonitor;
|
||||
nsDataHashtable<nsIDHashKey, xptiInterfaceEntry*> mIIDTable;
|
||||
nsDataHashtable<nsDepCharHashKey, xptiInterfaceEntry*> mNameTable;
|
||||
};
|
||||
@ -406,15 +411,7 @@ private:
|
||||
return mEntry && mEntry->EnsureResolved();
|
||||
}
|
||||
|
||||
PRBool BuildParent()
|
||||
{
|
||||
NS_ASSERTION(mEntry &&
|
||||
mEntry->IsFullyResolved() &&
|
||||
!mParent &&
|
||||
mEntry->Parent(),
|
||||
"bad BuildParent call");
|
||||
return NS_SUCCEEDED(mEntry->Parent()->GetInterfaceInfo(&mParent));
|
||||
}
|
||||
PRBool BuildParent();
|
||||
|
||||
xptiInterfaceInfo(); // not implemented
|
||||
|
||||
@ -451,18 +448,6 @@ public:
|
||||
return self->mResolveLock;
|
||||
}
|
||||
|
||||
static Mutex& GetAutoRegLock(xptiInterfaceInfoManager* self = nsnull)
|
||||
{
|
||||
self = self ? self : GetSingleton();
|
||||
return self->mAutoRegLock;
|
||||
}
|
||||
|
||||
static Monitor& GetInfoMonitor(xptiInterfaceInfoManager* self = nsnull)
|
||||
{
|
||||
self = self ? self : GetSingleton();
|
||||
return self->mInfoMonitor;
|
||||
}
|
||||
|
||||
xptiInterfaceEntry* GetInterfaceEntryForIID(const nsIID *iid);
|
||||
|
||||
private:
|
||||
@ -482,8 +467,6 @@ private:
|
||||
private:
|
||||
xptiWorkingSet mWorkingSet;
|
||||
Mutex mResolveLock;
|
||||
Mutex mAutoRegLock;
|
||||
Monitor mInfoMonitor;
|
||||
Mutex mAdditionalManagersLock;
|
||||
nsCOMArray<nsISupports> mAdditionalManagers;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user