Blob Blame History Raw
diff -Nur audacious-3.6.2-orig/src/audacious/main.cc audacious-3.6.2/src/audacious/main.cc
--- audacious-3.6.2-orig/src/audacious/main.cc	2015-05-31 00:27:01.000000000 +0200
+++ audacious-3.6.2/src/audacious/main.cc	2015-11-22 12:24:15.858308588 +0100
@@ -49,6 +49,7 @@
     int qt;
 } options;
 
+static bool initted = false;
 static Index<PlaylistAddItem> filenames;
 
 static const struct {
@@ -300,6 +301,16 @@
 
 static void main_cleanup (void)
 {
+    if (initted)
+    {
+        /* Somebody was naughty and called exit() instead of aud_quit().
+         * aud_cleanup() has not been called yet, so there's no point in running
+         * leak checks.  Note that it's not safe to call aud_cleanup() from the
+         * exit handler, since we don't know what context we're in (we could be
+         * deep inside the call tree of some plugin, for example). */
+        AUDWARN ("exit() called unexpectedly; skipping normal cleanup.\n");
+        return;
+    }
     filenames.clear ();
     aud_cleanup_paths ();
     aud_leak_check ();
@@ -356,6 +367,7 @@
     signals_init_two ();
 #endif
 
+    initted = true;
     aud_init ();
 
     do_commands ();
@@ -379,6 +391,7 @@
 #endif
 
     aud_cleanup ();
+    initted = false;
 
     return EXIT_SUCCESS;
 }
diff -Nur audacious-3.6.2-orig/src/libaudcore/multihash.h audacious-3.6.2/src/libaudcore/multihash.h
--- audacious-3.6.2-orig/src/libaudcore/multihash.h	2015-05-31 00:27:01.000000000 +0200
+++ audacious-3.6.2/src/libaudcore/multihash.h	2015-11-22 12:22:45.550171540 +0100
@@ -54,9 +54,12 @@
         size (0),
         used (0) {}
 
-    ~HashBase ()
-        { delete[] buckets; }
-
+    void clear ()  // use as destructor
+    {
+        delete[] buckets;
+        * this = HashBase ();
+    }
+ 
     int n_items () const
         { return used; }
 
@@ -112,6 +115,11 @@
         locks (),
         channels () {}
 
+    /* There is no destructor.  In some instances, such as the string pool, it
+     * is never safe to destroy the hash table, since it can be referenced from
+     * the destructors of other static objects.  It is left to the operating
+     * system to reclaim the memory used by the hash table upon process exit. */
+
     /* All-purpose lookup function.  The caller passes in the data to be looked
      * up along with its hash value.  The two callbacks are optional.  <add> is
      * called if no matching node is found, and may return a new node to add to
@@ -187,8 +195,11 @@
     }
 
     void clear ()
-        { HashBase::iterate (remove_cb, nullptr); }
-
+    {
+        HashBase::iterate (remove_cb, nullptr);
+        HashBase::clear ();
+    }
+    
 private:
     struct Node : public HashBase::Node
     {