X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Fpool.cc;h=7b24625727dc1d05dff0c2554a8c6398925f544a;hb=2ec45cfd1b09343b874726f1b3f38ac6a1ed49e3;hp=abb8695c23016b56ce26aa781d844f5f5f9ecf1f;hpb=84e92060fd0593adcd47c39b358048715ece9c7a;p=ardour.git diff --git a/libs/pbd/pool.cc b/libs/pbd/pool.cc index abb8695c23..7b24625727 100644 --- a/libs/pbd/pool.cc +++ b/libs/pbd/pool.cc @@ -19,13 +19,14 @@ */ #include -#include #include #include #include #include "pbd/pool.h" #include "pbd/error.h" +#include "pbd/debug.h" +#include "pbd/compose.h" using namespace std; using namespace PBD; @@ -86,37 +87,27 @@ Pool::release (void *ptr) MultiAllocSingleReleasePool::MultiAllocSingleReleasePool (string n, unsigned long isize, unsigned long nitems) : Pool (n, isize, nitems) - , m_lock(0) { } MultiAllocSingleReleasePool::~MultiAllocSingleReleasePool () { - delete m_lock; } SingleAllocMultiReleasePool::SingleAllocMultiReleasePool (string n, unsigned long isize, unsigned long nitems) : Pool (n, isize, nitems) - , m_lock(0) { } SingleAllocMultiReleasePool::~SingleAllocMultiReleasePool () { - delete m_lock; } void* MultiAllocSingleReleasePool::alloc () { void *ptr; - if(!m_lock) { - m_lock = new Glib::Mutex(); - // umm, I'm not sure that this doesn't also allocate memory. - if(!m_lock) error << "cannot create Glib::Mutex in pool.cc" << endmsg; - } - - Glib::Mutex::Lock guard(*m_lock); + Glib::Threads::Mutex::Lock guard (m_lock); ptr = Pool::alloc (); return ptr; } @@ -136,12 +127,7 @@ SingleAllocMultiReleasePool::alloc () void SingleAllocMultiReleasePool::release (void* ptr) { - if(!m_lock) { - m_lock = new Glib::Mutex(); - // umm, I'm not sure that this doesn't also allocate memory. - if(!m_lock) error << "cannot create Glib::Mutex in pool.cc" << endmsg; - } - Glib::Mutex::Lock guard(*m_lock); + Glib::Threads::Mutex::Lock guard (m_lock); Pool::release (ptr); } @@ -157,19 +143,24 @@ free_per_thread_pool (void* ptr) CrossThreadPool* cp = static_cast (ptr); assert (cp); - cp->parent()->add_to_trash (cp); + if (cp->empty()) { + /* This CrossThreadPool is already empty, and the thread is finishing so nothing + * more can be added to it. We can just delete the pool. + */ + delete cp; + } else { + /* This CrossThreadPool is not empty, meaning that there's some Events in it + * which another thread may yet read, so we can't delete the pool just yet. + * Put it in the trash and hope someone deals with it at some stage. + */ + cp->parent()->add_to_trash (cp); + } } PerThreadPool::PerThreadPool () - : _trash (0) + : _key (free_per_thread_pool) + , _trash (0) { - { - /* for some reason this appears necessary to get glib's thread private stuff to work */ - GPrivate* key; - key = g_private_new (NULL); - } - - _key = g_private_new (free_per_thread_pool); } /** Create a new CrossThreadPool and set the current thread's private _key to point to it. @@ -180,8 +171,7 @@ PerThreadPool::PerThreadPool () void PerThreadPool::create_per_thread_pool (string n, unsigned long isize, unsigned long nitems) { - CrossThreadPool* p = new CrossThreadPool (n, isize, nitems, this); - g_private_set (_key, p); + _key.set (new CrossThreadPool (n, isize, nitems, this)); } /** @return CrossThreadPool for the current thread, which must previously have been created by @@ -190,7 +180,7 @@ PerThreadPool::create_per_thread_pool (string n, unsigned long isize, unsigned l CrossThreadPool* PerThreadPool::per_thread_pool () { - CrossThreadPool* p = static_cast (g_private_get (_key)); + CrossThreadPool* p = _key.get(); if (!p) { fatal << "programming error: no per-thread pool \"" << _name << "\" for thread " << pthread_self() << endmsg; /*NOTREACHED*/ @@ -201,7 +191,7 @@ PerThreadPool::per_thread_pool () void PerThreadPool::set_trash (RingBuffer* t) { - Glib::Mutex::Lock lm (_trash_mutex); + Glib::Threads::Mutex::Lock lm (_trash_mutex); _trash = t; } @@ -209,7 +199,7 @@ PerThreadPool::set_trash (RingBuffer* t) void PerThreadPool::add_to_trash (CrossThreadPool* p) { - Glib::Mutex::Lock lm (_trash_mutex); + Glib::Threads::Mutex::Lock lm (_trash_mutex); if (!_trash) { warning << "Pool " << p->name() << " has no trash collector; a memory leak has therefore occurred" << endmsg; @@ -235,7 +225,10 @@ void* CrossThreadPool::alloc () { void* ptr; + + DEBUG_TRACE (DEBUG::Pool, string_compose ("%1 %2 has %3 pending free entries waiting\n", pthread_self(), name(), pending.read_space())); while (pending.read (&ptr, 1) == 1) { + DEBUG_TRACE (DEBUG::Pool, string_compose ("%1 %2 pushes back a pending free list entry before allocating\n", pthread_self(), name())); free_list.write (&ptr, 1); } return Pool::alloc ();