fully clean up request buffers when a thread dies
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 14 Jan 2016 15:53:32 +0000 (10:53 -0500)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 14 Jan 2016 15:53:32 +0000 (10:53 -0500)
libs/pbd/event_loop.cc
libs/pbd/pbd/abstract_ui.cc
libs/pbd/pbd/event_loop.h

index e6f5414d11ff2136327574ebc420947be4d18f19..424636fedaf81c4a08e22dfb0a151e4792cfa7b7 100644 (file)
@@ -219,3 +219,15 @@ EventLoop::pre_register (const string& emitting_thread_name, uint32_t num_reques
        }
 }
 
+void
+EventLoop::remove_request_buffer_from_map (void* ptr)
+{
+       Glib::Threads::RWLock::ReaderLock lm (thread_buffer_requests_lock);
+
+       for (ThreadRequestBufferList::iterator x = thread_buffer_requests.begin(); x != thread_buffer_requests.end(); ++x) {
+               if (x->second.request_buffer == ptr) {
+                       thread_buffer_requests.erase (x);
+                       break;
+               }
+       }
+}
index e186161cf9773ed06f18727660afcbd6e08cc4fa..3fa1f64770211f1e2bcff30703ab50b4746fcdb1 100644 (file)
@@ -54,7 +54,7 @@ cleanup_request_buffer (void* ptr)
         * a request. If the UI has finished processing requests, then
         * we will leak this buffer object.
         */
-
+       DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("thread \"%1\" exits: marking request buffer as dead @ %2\n", pthread_name(), rb));
        rb->dead = true;
 }
 
@@ -246,9 +246,13 @@ AbstractUI<RequestObject>::handle_ui_requests ()
                        DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 deleting dead per-thread request buffer for %3 @ %4\n",
                                                                             event_loop_name(), pthread_name(), i->second));
                        cerr << event_loop_name() << " noticed that a buffer was dead\n";
+                       /* remove it from the EventLoop static map of all request buffers */
+                       EventLoop::remove_request_buffer_from_map ((*i).second);
+                       /* delete it */
                        delete (*i).second;
                        RequestBufferMapIterator tmp = i;
                        ++tmp;
+                       /* remove it from this thread's list of request buffers */
                        request_buffers.erase (i);
                        i = tmp;
                } else {
index f4f57f4c286de32ec133888b4901249fc3f26cbb..b6e07b44de1308fa6dbffd747a0d0b6b6b15ed82 100644 (file)
@@ -93,6 +93,7 @@ class LIBPBD_API EventLoop
 
        static void register_request_buffer_factory (const std::string& target_thread_name, void* (*factory) (uint32_t));
        static void pre_register (const std::string& emitting_thread_name, uint32_t num_requests);
+       static void remove_request_buffer_from_map (void* ptr);
 
   private:
         static Glib::Threads::Private<EventLoop> thread_event_loop;