Back out changeset c509d8f8f423 (bug 627985, bug 614480) because of reftest suite shutdown timeout on Linux64 opt builds
authorEhsan Akhgari <ehsan@mozilla.com>
Mon, 11 Apr 2011 02:07:25 -0400
changeset 67825 db98c4f4634761d23f2b481f57e912b4b36615ce
parent 67824 704e425c1a6bad2b206fa5c06998902050b5d363
child 67826 f79edc2f8714d33d5855509df40f1f67266f29d5
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs627985, 614480
milestone2.2a1pre
backs outc509d8f8f423778ab4e30aad0fd67638d115cb4c
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Back out changeset c509d8f8f423 (bug 627985, bug 614480) because of reftest suite shutdown timeout on Linux64 opt builds
xpcom/reflect/xptinfo/src/xptiInterfaceInfo.cpp
xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
xpcom/reflect/xptinfo/src/xptiTypelibGuts.cpp
xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp
xpcom/reflect/xptinfo/src/xptiprivate.h
--- a/xpcom/reflect/xptinfo/src/xptiInterfaceInfo.cpp
+++ b/xpcom/reflect/xptinfo/src/xptiInterfaceInfo.cpp
@@ -614,20 +614,17 @@ xptiInterfaceEntry::HasAncestor(const ns
     return NS_OK;
 }
 
 /***************************************************/
 
 nsresult 
 xptiInterfaceEntry::GetInterfaceInfo(xptiInterfaceInfo** info)
 {
-#ifdef DEBUG
-    xptiInterfaceInfoManager::GetSingleton()->GetWorkingSet()->mTableLock.
-        AssertCurrentThreadOwns();
-#endif
+    MonitorAutoEnter lock(xptiInterfaceInfoManager::GetInfoMonitor());
     LOG_INFO_MONITOR_ENTRY;
 
     if(!mInfo)
     {
         mInfo = new xptiInterfaceInfo(this);
         if(!mInfo)
         {
             *info = nsnull;    
@@ -644,29 +641,16 @@ xptiInterfaceEntry::LockedInvalidateInte
 {
     if(mInfo)
     {
         mInfo->Invalidate(); 
         mInfo = nsnull;
     }
 }
 
-PRBool
-xptiInterfaceInfo::BuildParent()
-{
-    mozilla::MutexAutoLock lock(xptiInterfaceInfoManager::GetSingleton()->
-                                    GetWorkingSet()->mTableLock);
-    NS_ASSERTION(mEntry && 
-                 mEntry->IsFullyResolved() && 
-                 !mParent &&
-                 mEntry->Parent(),
-                "bad BuildParent call");
-    return NS_SUCCEEDED(mEntry->Parent()->GetInterfaceInfo(&mParent));
-}
-
 /***************************************************************************/
 
 NS_IMPL_QUERY_INTERFACE1(xptiInterfaceInfo, nsIInterfaceInfo)
 
 xptiInterfaceInfo::xptiInterfaceInfo(xptiInterfaceEntry* entry)
     : mEntry(entry), mParent(nsnull)
 {
     LOG_INFO_CREATE(this);
@@ -690,45 +674,37 @@ xptiInterfaceInfo::AddRef(void)
 nsrefcnt
 xptiInterfaceInfo::Release(void)
 {
     xptiInterfaceEntry* entry = mEntry;
     nsrefcnt cnt = NS_AtomicDecrementRefcnt(mRefCnt);
     NS_LOG_RELEASE(this, cnt, "xptiInterfaceInfo");
     if(!cnt)
     {
-        // Need to exit the lock before calling |delete this|, since
-        // that release mParent, which can re-enter this function.
-        {
-            mozilla::MutexAutoLock lock(xptiInterfaceInfoManager::
-                                            GetSingleton()->GetWorkingSet()->
-                                            mTableLock);
-            LOG_INFO_MONITOR_ENTRY;
+        MonitorAutoEnter lock(xptiInterfaceInfoManager::GetInfoMonitor());
+        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
+        // would want to bail immediately. If 'this' is already dead then the
+        // entry will no longer have a pointer to 'this'. So, we can protect 
+        // ourselves from danger without more aggressive locking.
+        if(entry && !entry->InterfaceInfoEquals(this))
+            return 0;
 
-            // 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 would want to bail immediately. If
-            // 'this' is already dead then the entry will no longer have
-            // a pointer to 'this'. So, we can protect ourselves from
-            // danger without more aggressive locking.
-            if(entry && !entry->InterfaceInfoEquals(this))
-                return 0;
-
-            // If GetInterfaceInfo added a reference before we acquired
-            // the monitor then we want to bail out of here without
-            // destorying the object.
-            if(mRefCnt)
-                return 1;
-
-            if(mEntry)
-            {
-                mEntry->LockedInterfaceInfoDeathNotification();
-                mEntry = nsnull;
-            }
+        // If GetInterfaceInfo added a reference before we acquired the monitor
+        // then we want to bail out of here without destorying the object.
+        if(mRefCnt)
+            return 1;
+        
+        if(mEntry)
+        {
+            mEntry->LockedInterfaceInfoDeathNotification();
+            mEntry = nsnull;
         }
 
         delete this;
         return 0;    
     }
     return cnt;
 }
 
--- a/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
+++ b/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
@@ -75,16 +75,18 @@ void
 xptiInterfaceInfoManager::FreeInterfaceInfoManager()
 {
     NS_IF_RELEASE(gInterfaceInfoManager);
 }
 
 xptiInterfaceInfoManager::xptiInterfaceInfoManager()
     :   mWorkingSet(),
         mResolveLock("xptiInterfaceInfoManager.mResolveLock"),
+        mAutoRegLock("xptiInterfaceInfoManager.mAutoRegLock"), // FIXME: unused!
+        mInfoMonitor("xptiInterfaceInfoManager.mInfoMonitor"),
         mAdditionalManagersLock(
             "xptiInterfaceInfoManager.mAdditionalManagersLock")
 {
 }
 
 xptiInterfaceInfoManager::~xptiInterfaceInfoManager()
 {
     // We only do this on shutdown of the service.
@@ -228,17 +230,16 @@ xptiInterfaceInfoManager::RegisterXPTHea
 {
     if (aHeader->major_version >= XPT_MAJOR_INCOMPATIBLE_VERSION) {
         NS_ASSERTION(!aHeader->num_interfaces,"bad libxpt");
         LOG_AUTOREG(("      file is version %d.%d  Type file of version %d.0 or higher can not be read.\n", (int)header->major_version, (int)header->minor_version, (int)XPT_MAJOR_INCOMPATIBLE_VERSION));
     }
 
     xptiTypelibGuts* typelib = xptiTypelibGuts::Create(aHeader);
 
-    MutexAutoLock lock(mWorkingSet.mTableLock);
     for(PRUint16 k = 0; k < aHeader->num_interfaces; k++)
         VerifyAndAddEntryIfNew(aHeader->interface_directory + k, k, typelib);
 }
 
 void
 xptiInterfaceInfoManager::RegisterInputStream(nsIInputStream* aStream)
 {
     XPTHeader* header = ReadXPTFileFromInputStream(aStream);
@@ -249,17 +250,16 @@ xptiInterfaceInfoManager::RegisterInputS
 void
 xptiInterfaceInfoManager::VerifyAndAddEntryIfNew(XPTInterfaceDirectoryEntry* iface,
                                                  PRUint16 idx,
                                                  xptiTypelibGuts* typelib)
 {
     if (!iface->interface_descriptor)
         return;
     
-    mWorkingSet.mTableLock.AssertCurrentThreadOwns();
     xptiInterfaceEntry* entry = mWorkingSet.mIIDTable.Get(iface->iid);
     if (entry) {
         // XXX validate this info to find possible inconsistencies
         LOG_AUTOREG(("      ignoring repeated interface: %s\n", iface->name));
         return;
     }
     
     // Build a new xptiInterfaceEntry object and hook it up. 
@@ -301,65 +301,61 @@ EntryToInfo(xptiInterfaceEntry* entry, n
     // Transfer the AddRef done by GetInterfaceInfo.
     *_retval = static_cast<nsIInterfaceInfo*>(info);
     return NS_OK;    
 }
 
 xptiInterfaceEntry*
 xptiInterfaceInfoManager::GetInterfaceEntryForIID(const nsIID *iid)
 {
-    MutexAutoLock lock(mWorkingSet.mTableLock);
     return mWorkingSet.mIIDTable.Get(*iid);
 }
 
 /* nsIInterfaceInfo getInfoForIID (in nsIIDPtr iid); */
 NS_IMETHODIMP xptiInterfaceInfoManager::GetInfoForIID(const nsIID * iid, nsIInterfaceInfo **_retval)
 {
     NS_ASSERTION(iid, "bad param");
     NS_ASSERTION(_retval, "bad param");
 
-    MutexAutoLock lock(mWorkingSet.mTableLock);
-    xptiInterfaceEntry* entry = mWorkingSet.mIIDTable.Get(*iid);
+    xptiInterfaceEntry* entry = GetInterfaceEntryForIID(iid);
     return EntryToInfo(entry, _retval);
 }
 
 /* nsIInterfaceInfo getInfoForName (in string name); */
 NS_IMETHODIMP xptiInterfaceInfoManager::GetInfoForName(const char *name, nsIInterfaceInfo **_retval)
 {
     NS_ASSERTION(name, "bad param");
     NS_ASSERTION(_retval, "bad param");
 
-    MutexAutoLock lock(mWorkingSet.mTableLock);
     xptiInterfaceEntry* entry = mWorkingSet.mNameTable.Get(name);
     return EntryToInfo(entry, _retval);
 }
 
 /* nsIIDPtr getIIDForName (in string name); */
 NS_IMETHODIMP xptiInterfaceInfoManager::GetIIDForName(const char *name, nsIID * *_retval)
 {
     NS_ASSERTION(name, "bad param");
     NS_ASSERTION(_retval, "bad param");
 
-    MutexAutoLock lock(mWorkingSet.mTableLock);
+
     xptiInterfaceEntry* entry = mWorkingSet.mNameTable.Get(name);
     if (!entry) {
         *_retval = nsnull;
         return NS_ERROR_FAILURE;    
     }
 
     return entry->GetIID(_retval);
 }
 
 /* string getNameForIID (in nsIIDPtr iid); */
 NS_IMETHODIMP xptiInterfaceInfoManager::GetNameForIID(const nsIID * iid, char **_retval)
 {
     NS_ASSERTION(iid, "bad param");
     NS_ASSERTION(_retval, "bad param");
 
-    MutexAutoLock lock(mWorkingSet.mTableLock);
     xptiInterfaceEntry* entry = mWorkingSet.mIIDTable.Get(*iid);
     if (!entry) {
         *_retval = nsnull;
         return NS_ERROR_FAILURE;    
     }
 
     return entry->GetName(_retval);
 }
@@ -383,17 +379,16 @@ NS_IMETHODIMP xptiInterfaceInfoManager::
     // the table using an nsISupportsArray and builds an enumerator for that.
     // We can afford this transient cost.
 
     nsCOMPtr<nsISupportsArray> array;
     NS_NewISupportsArray(getter_AddRefs(array));
     if (!array)
         return NS_ERROR_UNEXPECTED;
 
-    MutexAutoLock lock(mWorkingSet.mTableLock);
     mWorkingSet.mNameTable.EnumerateRead(xpti_ArrayAppender, array);
 
     return array->Enumerate(_retval);
 }
 
 struct ArrayAndPrefix
 {
     nsISupportsArray* array;
@@ -419,17 +414,16 @@ xpti_ArrayPrefixAppender(const char* key
 /* nsIEnumerator enumerateInterfacesWhoseNamesStartWith (in string prefix); */
 NS_IMETHODIMP xptiInterfaceInfoManager::EnumerateInterfacesWhoseNamesStartWith(const char *prefix, nsIEnumerator **_retval)
 {
     nsCOMPtr<nsISupportsArray> array;
     NS_NewISupportsArray(getter_AddRefs(array));
     if (!array)
         return NS_ERROR_UNEXPECTED;
 
-    MutexAutoLock lock(mWorkingSet.mTableLock);
     ArrayAndPrefix args = {array, prefix, PL_strlen(prefix)};
     mWorkingSet.mNameTable.EnumerateRead(xpti_ArrayPrefixAppender, &args);
 
     return array->Enumerate(_retval);
 }
 
 /* void autoRegisterInterfaces (); */
 NS_IMETHODIMP xptiInterfaceInfoManager::AutoRegisterInterfaces()
--- a/xpcom/reflect/xptinfo/src/xptiTypelibGuts.cpp
+++ b/xpcom/reflect/xptinfo/src/xptiTypelibGuts.cpp
@@ -36,18 +36,16 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* Implementation of xptiTypelibGuts. */
 
 #include "xptiprivate.h"
 
-using namespace mozilla;
-
 // static 
 xptiTypelibGuts* 
 xptiTypelibGuts::Create(XPTHeader* aHeader)
 {
     NS_ASSERTION(aHeader, "bad param");
     void* place = XPT_MALLOC(gXPTIStructArena,
                              sizeof(xptiTypelibGuts) + 
                              (sizeof(xptiInterfaceEntry*) *
@@ -70,21 +68,18 @@ xptiTypelibGuts::GetEntryAt(PRUint16 i)
     if (r)
         return r;
 
     XPTInterfaceDirectoryEntry* iface = mHeader->interface_directory + i;
 
     xptiWorkingSet* set =
         xptiInterfaceInfoManager::GetSingleton()->GetWorkingSet();
 
-    {
-        MutexAutoLock lock(set->mTableLock);
-        if (iface->iid.Equals(zeroIID))
-            r = set->mNameTable.Get(iface->name);
-        else
-            r = set->mIIDTable.Get(iface->iid);
-    }
+    if (iface->iid.Equals(zeroIID))
+        r = set->mNameTable.Get(iface->name);
+    else
+        r = set->mIIDTable.Get(iface->iid);
 
     if (r)
         SetEntryAt(i, r);
 
     return r;
 }
--- a/xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp
+++ b/xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp
@@ -43,17 +43,16 @@
 #include "nsString.h"
 
 using namespace mozilla;
 
 #define XPTI_STRUCT_ARENA_BLOCK_SIZE    (1024 * 1)
 #define XPTI_HASHTABLE_SIZE             2048
 
 xptiWorkingSet::xptiWorkingSet()
-    : mTableLock("xptiWorkingSet::mTableLock")
 {
     MOZ_COUNT_CTOR(xptiWorkingSet);
 
     mIIDTable.Init(XPTI_HASHTABLE_SIZE);
     mNameTable.Init(XPTI_HASHTABLE_SIZE);
 
     gXPTIStructArena = XPT_NewArena(XPTI_STRUCT_ARENA_BLOCK_SIZE, sizeof(double),
                                     "xptiWorkingSet structs");
@@ -64,17 +63,17 @@ xpti_Invalidator(const char* keyname, xp
 {
     entry->LockedInvalidateInterfaceInfo();
     return PL_DHASH_NEXT;
 }
 
 void 
 xptiWorkingSet::InvalidateInterfaceInfos()
 {
-    MutexAutoLock lock(mTableLock);
+    MonitorAutoEnter lock(xptiInterfaceInfoManager::GetInfoMonitor());
     mNameTable.EnumerateRead(xpti_Invalidator, NULL);
 }        
 
 xptiWorkingSet::~xptiWorkingSet()
 {
     MOZ_COUNT_DTOR(xptiWorkingSet);
 
     // Only destroy the arena if we're doing leak stats. Why waste shutdown
--- a/xpcom/reflect/xptinfo/src/xptiprivate.h
+++ b/xpcom/reflect/xptinfo/src/xptiprivate.h
@@ -175,21 +175,16 @@ public:
     PRBool   DirectoryAtMatchesPersistentDescriptor(PRUint32 i, const char* desc);
 
 private:
     PRUint32        mFileCount;
     PRUint32        mMaxFileCount;
 
 public:
     // XXX make these private with accessors
-    // mTableLock 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::Mutex mTableLock;
     nsDataHashtable<nsIDHashKey, xptiInterfaceEntry*> mIIDTable;
     nsDataHashtable<nsDepCharHashKey, xptiInterfaceEntry*> mNameTable;
 };
 
 /***************************************************************************/
 
 // This class exists to help xptiInterfaceInfo store a 4-state (2 bit) value 
 // and a set of bitflags in one 8bit value. See below.
@@ -406,17 +401,25 @@ private:
         return mParent || !mEntry->Parent() || BuildParent();
     }
     
     PRBool EnsureResolved()
     {
         return mEntry && mEntry->EnsureResolved();
     }
 
-    PRBool BuildParent();
+    PRBool BuildParent()
+    {
+        NS_ASSERTION(mEntry && 
+                     mEntry->IsFullyResolved() && 
+                     !mParent &&
+                     mEntry->Parent(),
+                    "bad BuildParent call");
+        return NS_SUCCEEDED(mEntry->Parent()->GetInterfaceInfo(&mParent));
+    }
 
     xptiInterfaceInfo();  // not implemented
 
 private:
     xptiInterfaceEntry* mEntry;
     xptiInterfaceInfo*  mParent;
 };
 
@@ -443,16 +446,28 @@ public:
     xptiWorkingSet*  GetWorkingSet() {return &mWorkingSet;}
 
     static Mutex& GetResolveLock(xptiInterfaceInfoManager* self = nsnull) 
     {
         self = self ? self : GetSingleton();
         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:
     xptiInterfaceInfoManager();
     ~xptiInterfaceInfoManager();
 
     void RegisterXPTHeader(XPTHeader* aHeader);
                           
@@ -462,13 +477,15 @@ private:
     // idx is the index of this interface in the XPTHeader
     void VerifyAndAddEntryIfNew(XPTInterfaceDirectoryEntry* iface,
                                 PRUint16 idx,
                                 xptiTypelibGuts* typelib);
 
 private:
     xptiWorkingSet               mWorkingSet;
     Mutex                        mResolveLock;
+    Mutex                        mAutoRegLock;
+    Monitor                      mInfoMonitor;
     Mutex                        mAdditionalManagersLock;
     nsCOMArray<nsISupports>      mAdditionalManagers;
 };
 
 #endif /* xptiprivate_h___ */