@@ -226,6 +226,7 @@ static void tcache_destroy(void *_cache)
{
struct thread_cache *cache = _cache;
+ mutex_lock(&cache->mutex);
/*
* tcache_gc almost does what we want. It tries hard to only
* free part of the cache, but call it often enough and it
@@ -234,6 +235,15 @@ static void tcache_destroy(void *_cache)
*/
while (cache->tc_count)
tcache_gc(cache);
+ /*
+ * public_free will call tcache_free, which could free the
+ * cache into... the cache. Result would be a memory leak.
+ * But since we hold the cache-mutex, it cannot and has to
+ * free the memory back to the arena.
+ * A bit of a hack, but creates smaller code than having a
+ * second copy of uncached_free. And this is by no means a
+ * performance-critical path.
+ */
public_fREe(cache);
}