From fe85575a12d8c81e8d2d08b7d91238a88c8febe7 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Wed, 11 Mar 2015 00:25:10 +0100 Subject: [PATCH 1/1] =?utf8?q?fix=20=E2=80=9Cno=20per-thread=20pool?= =?utf8?q?=E2=80=9D=20abort?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit For some backends the process thread can change (e.g. switch coreaudio headphone + internal speakers) If there are existing x-thread event calls this can lead to the following situation: 1) SessionEvent::operator new 2) audioengine process thread change 3) SessionEvent::operator delete -> crash, wrong thread SessionEvent::operator delete can safely push the event back to the pool for later cleanup.. --- libs/ardour/session_events.cc | 5 +++-- libs/pbd/pbd/pool.h | 2 +- libs/pbd/pool.cc | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/libs/ardour/session_events.cc b/libs/ardour/session_events.cc index 0208c03cb1..d41b9c5002 100644 --- a/libs/ardour/session_events.cc +++ b/libs/ardour/session_events.cc @@ -86,7 +86,7 @@ SessionEvent::operator new (size_t) void SessionEvent::operator delete (void *ptr, size_t /*size*/) { - Pool* p = pool->per_thread_pool (); + Pool* p = pool->per_thread_pool (false); SessionEvent* ev = static_cast (ptr); DEBUG_TRACE (DEBUG::SessionEvents, string_compose ( @@ -100,9 +100,10 @@ SessionEvent::operator delete (void *ptr, size_t /*size*/) } #endif - if (p == ev->own_pool) { + if (p && p == ev->own_pool) { p->release (ptr); } else { + assert(ev->own_pool); ev->own_pool->push (ev); DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("%1 was wrong thread for this pool, pushed event onto pending list, will be deleted on next alloc from %2 pool size %3 free %4 used %5 pending %6\n", pthread_name(), ev->own_pool->name(), diff --git a/libs/pbd/pbd/pool.h b/libs/pbd/pbd/pool.h index 1c9ac81a3e..cfd782a794 100644 --- a/libs/pbd/pbd/pool.h +++ b/libs/pbd/pbd/pool.h @@ -128,7 +128,7 @@ class LIBPBD_API PerThreadPool const Glib::Threads::Private& key() const { return _key; } void create_per_thread_pool (std::string name, unsigned long item_size, unsigned long nitems); - CrossThreadPool* per_thread_pool (); + CrossThreadPool* per_thread_pool (bool must_exist = true); void set_trash (RingBuffer* t); void add_to_trash (CrossThreadPool *); diff --git a/libs/pbd/pool.cc b/libs/pbd/pool.cc index b3e5c52e1a..020f296f61 100644 --- a/libs/pbd/pool.cc +++ b/libs/pbd/pool.cc @@ -179,10 +179,10 @@ PerThreadPool::create_per_thread_pool (string n, unsigned long isize, unsigned l * calling create_per_thread_pool in the current thread. */ CrossThreadPool* -PerThreadPool::per_thread_pool () +PerThreadPool::per_thread_pool (bool must_exist) { CrossThreadPool* p = _key.get(); - if (!p) { + if (!p && must_exist) { fatal << "programming error: no per-thread pool \"" << _name << "\" for thread " << pthread_name() << endmsg; abort(); /*NOTREACHED*/ } -- 2.30.2