diff --git a/src/audacious/main.cc b/src/audacious/main.cc index ff2cc66403..2f436ef71a 100644 --- a/src/audacious/main.cc +++ b/src/audacious/main.cc @@ -49,6 +49,7 @@ static struct { int qt; } options; +static bool initted = false; static Index filenames; static const struct { @@ -304,6 +305,17 @@ static void do_commands () static void main_cleanup () { + 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 (); @@ -360,6 +372,7 @@ int main (int argc, char * * argv) signals_init_two (); #endif + initted = true; aud_init (); do_commands (); @@ -383,6 +396,7 @@ int main (int argc, char * * argv) #endif aud_cleanup (); + initted = false; return EXIT_SUCCESS; } diff --git a/src/libaudcore/multihash.h b/src/libaudcore/multihash.h index 186e1958eb..4ddd37f23d 100644 --- a/src/libaudcore/multihash.h +++ b/src/libaudcore/multihash.h @@ -54,8 +54,11 @@ class HashBase 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 @@ class MultiHash 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. is * called if no matching node is found, and may return a new node to add to @@ -187,7 +195,10 @@ class SimpleHash : private HashBase } void clear () - { HashBase::iterate (remove_cb, nullptr); } + { + HashBase::iterate (remove_cb, nullptr); + HashBase::clear (); + } private: struct Node : public HashBase::Node