summaryrefslogtreecommitdiff
path: root/libs/pbd
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-12-14 22:38:37 +0100
committerRobin Gareus <robin@gareus.org>2016-12-14 22:39:25 +0100
commit62b06fa427b4f432f82510f51e4b6920280b17a8 (patch)
treed3e5bd9e92a4b0492c6307a8c317fc6dd20580bb /libs/pbd
parent07bcdc7f0a5b2702eff92716ab42228c6977ce94 (diff)
Add a trash pool for invalidation requests.
While EventLoop::invalidate_request() does invalidate request in the request-list. It does *not* invalidate requests in the per-thread-request-ringbuffer(s). The invalidation record cannot be deleted in EventLoop::invalidate_request see 6b5891a78f.
Diffstat (limited to 'libs/pbd')
-rw-r--r--libs/pbd/event_loop.cc5
-rw-r--r--libs/pbd/pbd/abstract_ui.cc21
-rw-r--r--libs/pbd/pbd/event_loop.h2
3 files changed, 22 insertions, 6 deletions
diff --git a/libs/pbd/event_loop.cc b/libs/pbd/event_loop.cc
index 0baba2835a..aae0c21a08 100644
--- a/libs/pbd/event_loop.cc
+++ b/libs/pbd/event_loop.cc
@@ -95,8 +95,9 @@ EventLoop::invalidate_request (void* data)
(*i)->invalidation = 0;
}
}
- // should this not always be deleted, regardless if there's an event_loop?
- delete ir;
+ // This invalidation record may still be in-use in per-thread-request-ringbuffer.
+ // it cannot be deleted here,
+ ir->event_loop->trash.push_back(ir);
} else {
DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("EventLoop::invalidate_request no event-loop for invalidation %1\n", ir));
}
diff --git a/libs/pbd/pbd/abstract_ui.cc b/libs/pbd/pbd/abstract_ui.cc
index db63c3f96d..db7ce38a64 100644
--- a/libs/pbd/pbd/abstract_ui.cc
+++ b/libs/pbd/pbd/abstract_ui.cc
@@ -218,6 +218,7 @@ AbstractUI<RequestObject>::handle_ui_requests ()
if (vec.len[0] == 0) {
break;
} else {
+ bool alive = true;
if (vec.buf[0]->valid ()) {
/* We first need to remove the event from the list.
* If the event results in object destruction, PBD::EventLoop::invalidate_request
@@ -225,6 +226,7 @@ AbstractUI<RequestObject>::handle_ui_requests ()
*/
DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: remove request %2 from its invalidation list %3\n", event_loop_name(), vec.buf[0], vec.buf[0]->invalidation));
if (vec.buf[0]->invalidation) {
+ alive = std::find (trash.begin(), trash.end(), vec.buf[0]->invalidation) == trash.end();
DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: removing invalidation record for that request\n", event_loop_name()));
if (vec.buf[0]->invalidation->event_loop && vec.buf[0]->invalidation->event_loop != this) {
vec.buf[0]->invalidation->event_loop->slot_invalidation_mutex().lock ();
@@ -240,8 +242,12 @@ AbstractUI<RequestObject>::handle_ui_requests ()
DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: valid request, unlocking before calling\n", event_loop_name()));
rbml.release ();
- DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: valid request, calling ::do_request()\n", event_loop_name()));
- do_request (vec.buf[0]);
+ if (alive) {
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: valid request, calling ::do_request()\n", event_loop_name()));
+ do_request (vec.buf[0]);
+ } else {
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: skipping invalidated request\n", event_loop_name()));
+ }
/* if the request was CallSlot, then we need to ensure that we reset the functor in the request, in case it
* held a shared_ptr<>. Failure to do so can lead to dangling references to objects passed to PBD::Signals.
@@ -264,8 +270,6 @@ AbstractUI<RequestObject>::handle_ui_requests ()
}
}
- /* clean up any dead request buffers (their thread has exited) */
-
assert (rbml.locked ());
for (i = request_buffers.begin(); i != request_buffers.end(); ) {
if ((*i).second->dead) {
@@ -370,6 +374,15 @@ AbstractUI<RequestObject>::handle_ui_requests ()
rbml.acquire();
}
+ /* clean up any dead invalidation records (object was deleted) */
+ trash.sort();
+ trash.unique();
+ for (std::list<InvalidationRecord*>::const_iterator r = trash.begin(); r != trash.end(); ++r) {
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1 drop invalidation trash %2\n", event_loop_name(), *r));
+ delete *r;
+ }
+ trash.clear ();
+
rbml.release ();
}
diff --git a/libs/pbd/pbd/event_loop.h b/libs/pbd/pbd/event_loop.h
index 6fd92c49c8..e84832ebcb 100644
--- a/libs/pbd/pbd/event_loop.h
+++ b/libs/pbd/pbd/event_loop.h
@@ -99,6 +99,8 @@ public:
static void pre_register (const std::string& emitting_thread_name, uint32_t num_requests);
static void remove_request_buffer_from_map (void* ptr);
+ std::list<InvalidationRecord*> trash;
+
private:
static Glib::Threads::Private<EventLoop> thread_event_loop;
std::string _name;