Bug 658995 part 2 - Use static destructors instead of atexit(). r=bsmedberg
authorMike Hommey <mh+mozilla@glandium.org>
Wed, 15 Jun 2011 07:32:03 +0200
changeset 71201 f4ddad2c0eb7d079abeba227758176ba4992f59e
parent 71200 eef5d644e17e778357ab31306136dc88fc52413c
child 71202 8ae2a073b044817811fb8766929ef16074577445
push id101
push usermh@glandium.org
push dateFri, 17 Jun 2011 01:05:08 +0000
treeherdermozilla-inbound@cc18551d5cc3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs658995
milestone7.0a1
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
Bug 658995 part 2 - Use static destructors instead of atexit(). r=bsmedberg
netwerk/base/src/nsStandardURL.cpp
profile/dirserviceprovider/src/nsProfileLock.cpp
profile/dirserviceprovider/src/nsProfileLock.h
tools/trace-malloc/lib/nsTraceMalloc.c
tools/trace-malloc/lib/nsTypeInfo.cpp
--- a/netwerk/base/src/nsStandardURL.cpp
+++ b/netwerk/base/src/nsStandardURL.cpp
@@ -320,17 +320,22 @@ nsStandardURL::~nsStandardURL()
 
     CRTFREEIF(mHostA);
 #ifdef DEBUG_DUMP_URLS_AT_SHUTDOWN
     PR_REMOVE_LINK(&mDebugCList);
 #endif
 }
 
 #ifdef DEBUG_DUMP_URLS_AT_SHUTDOWN
-static void DumpLeakedURLs()
+struct DumpLeakedURLs {
+    DumpLeakedURLs() {}
+    ~DumpLeakedURLs();
+};
+
+DumpLeakedURLs::~DumpLeakedURLs()
 {
     if (!PR_CLIST_IS_EMPTY(&gAllURLs)) {
         printf("Leaked URLs:\n");
         for (PRCList *l = PR_LIST_HEAD(&gAllURLs); l != &gAllURLs; l = PR_NEXT_LINK(l)) {
             nsStandardURL *url = reinterpret_cast<nsStandardURL*>(reinterpret_cast<char*>(l) - offsetof(nsStandardURL, mDebugCList));
             url->PrintSpec();
         }
     }
@@ -358,18 +363,22 @@ nsStandardURL::InitGlobalObjects()
 
 void
 nsStandardURL::ShutdownGlobalObjects()
 {
     NS_IF_RELEASE(gIDN);
     NS_IF_RELEASE(gCharsetMgr);
 
 #ifdef DEBUG_DUMP_URLS_AT_SHUTDOWN
-    if (gInitialized)
-        atexit(DumpLeakedURLs);
+    if (gInitialized) {
+        // This instanciates a dummy class, and will trigger the class
+        // destructor when libxul is unloaded. This is equivalent to atexit(),
+        // but gracefully handles dlclose().
+        static DumpLeakedURLs d;
+    }
 #endif
 }
 
 //----------------------------------------------------------------------------
 // nsStandardURL <private>
 //----------------------------------------------------------------------------
 
 void
--- a/profile/dirserviceprovider/src/nsProfileLock.cpp
+++ b/profile/dirserviceprovider/src/nsProfileLock.cpp
@@ -385,17 +385,20 @@ nsresult nsProfileLock::LockWithSymlink(
         mHaveLock = PR_TRUE;
         mPidLockFileName = strdup(fileName);
         if (mPidLockFileName)
         {
             PR_APPEND_LINK(this, &mPidLockList);
             if (!setupPidLockCleanup++)
             {
                 // Clean up on normal termination.
-                atexit(RemovePidLockFilesExiting);
+                // This instanciates a dummy class, and will trigger the class
+                // destructor when libxul is unloaded. This is equivalent to atexit(),
+                // but gracefully handles dlclose().
+                static RemovePidLockFilesExiting r;
 
                 // Clean up on abnormal termination, using POSIX sigaction.
                 // Don't arm a handler if the signal is being ignored, e.g.,
                 // because mozilla is run via nohup.
                 if (!sDisableSignalHandling) {
                     struct sigaction act, oldact;
 #ifdef SA_SIGINFO
                     act.sa_sigaction = FatalSignalHandler;
--- a/profile/dirserviceprovider/src/nsProfileLock.h
+++ b/profile/dirserviceprovider/src/nsProfileLock.h
@@ -94,24 +94,22 @@ private:
     PRPackedBool            mHaveLock;
 
 #if defined (XP_WIN)
     HANDLE                  mLockFileHandle;
 #elif defined (XP_OS2)
     LHANDLE                 mLockFileHandle;
 #elif defined (XP_UNIX)
 
-    static void             RemovePidLockFilesExiting()
-    {
-      // We can't implement this function with a default parameter on
-      // RemovePidLockFiles(aFatalSignal) since we register
-      //    atexit(RemovePidLockFilesExiting).
-
-      RemovePidLockFiles(PR_FALSE);
-    }
+    struct RemovePidLockFilesExiting {
+        RemovePidLockFilesExiting() {}
+        ~RemovePidLockFilesExiting() {
+            RemovePidLockFiles(PR_FALSE);
+        }
+    };
 
     static void             RemovePidLockFiles(PRBool aFatalSignal);
     static void             FatalSignalHandler(int signo
 #ifdef SA_SIGINFO
                                                , siginfo_t *info, void *context
 #endif
                                                );
     static PRCList          mPidLockList;
--- a/tools/trace-malloc/lib/nsTraceMalloc.c
+++ b/tools/trace-malloc/lib/nsTraceMalloc.c
@@ -1360,17 +1360,17 @@ NS_TraceMallocStartup(int logfd)
         /* Log everything in logfp (aka default_logfile)'s buffer to logfd. */
         logfp->fd = logfd;
         logfile_list = &default_logfile;
         logfp->prevp = &logfile_list;
         logfile_tail = &logfp->next;
         log_header(logfd);
     }
 
-    atexit(NS_TraceMallocShutdown);
+    RegisterTraceMallocShutdown();
 
     tmlock = PR_NewLock();
     (void) tm_get_thread(); /* ensure index initialization while it's easy */
 
     if (tracing_enabled)
         StartupHooker();
 }
 
--- a/tools/trace-malloc/lib/nsTypeInfo.cpp
+++ b/tools/trace-malloc/lib/nsTypeInfo.cpp
@@ -49,16 +49,32 @@
   by Patrick C. Beard.
  */
 
 #include <typeinfo>
 #include <ctype.h>
 
 extern "C" const char* nsGetTypeName(void* ptr);
 
+extern "C" void NS_TraceMallocShutdown();
+
+struct TraceMallocShutdown {
+    TraceMallocShutdown() {}
+    ~TraceMallocShutdown() {
+        NS_TraceMallocShutdown();
+    }
+};
+
+extern "C" void RegisterTraceMallocShutdown() {
+    // This instanciates the dummy class above, and will trigger the class
+    // destructor when libxul is unloaded. This is equivalent to atexit(),
+    // but gracefully handles dlclose().
+    static TraceMallocShutdown t;
+}
+
 class IUnknown {
 public:
     virtual long QueryInterface() = 0;
     virtual long AddRef() = 0;
     virtual long Release() = 0;
 };
 
 #if defined(MACOS)