summaryrefslogtreecommitdiff
path: root/libs/pbd/pbd
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-12-15 18:16:03 +0100
committerRobin Gareus <robin@gareus.org>2016-12-15 18:19:38 +0100
commit6c88f339cacabf89645882214cbf0ecc9d710a20 (patch)
tree850efa76d8b06181a3630d02e679851a4650c4eb /libs/pbd/pbd
parent529b91828db699d9605a424f17b701fa907178c2 (diff)
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.
Diffstat (limited to 'libs/pbd/pbd')
-rw-r--r--libs/pbd/pbd/abstract_ui.cc13
1 files changed, 11 insertions, 2 deletions
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<RequestObject>::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<RequestObject>::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);