From 6c88f339cacabf89645882214cbf0ecc9d710a20 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 15 Dec 2016 18:16:03 +0100 Subject: some further invalidation details: Prevent double unref during when the EventLoop terminates: deleting the ringbuffer deletes all requests, some of which may contain stale invalidation remove the buffer_map_lock, now that signals ref-count the IR. --- libs/pbd/pbd/abstract_ui.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'libs/pbd/pbd') diff --git a/libs/pbd/pbd/abstract_ui.cc b/libs/pbd/pbd/abstract_ui.cc index 586b50aed5..76ad5d0da4 100644 --- a/libs/pbd/pbd/abstract_ui.cc +++ b/libs/pbd/pbd/abstract_ui.cc @@ -267,6 +267,7 @@ AbstractUI::handle_ui_requests () if (vec.buf[0]->invalidation) { vec.buf[0]->invalidation->unref (); } + vec.buf[0]->invalidation = NULL; i->second->increment_read_ptr (1); } } @@ -418,15 +419,23 @@ AbstractUI::call_slot (InvalidationRecord* invalidation, const bo return; } + /* object destruction may race with realtime signal emission. + * + * There may be a concurrent event-loop in progress of deleting + * the slot-object. That's perfectly fine. But we need to mark + * the invalidation record itself as being used by the request. + * + * The IR needs to be kept around until the last signal using + * it is disconnected and then it can be deleted in the event-loop + * (GUI thread). + */ if (invalidation) { - Glib::Threads::Mutex::Lock lm (request_buffer_map_lock); // -- remove this once signal connect/disconnect uses ir->un/ref() if (!invalidation->valid()) { DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 ignoring call-slot using functor @ %3, dead invalidation %4\n", event_loop_name(), pthread_name(), &f, invalidation)); return; } invalidation->ref (); assert (invalidation->event_loop == this); - invalidation->event_loop = this; // XXX is this needed, PBD::signal::connect sets it } RequestObject *req = get_request (BaseUI::CallSlot); -- cgit v1.2.3