diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2016-01-16 09:33:15 -0500 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2016-01-16 09:33:31 -0500 |
commit | 9d65e6084c6cf81032613645c85a99529f0de38d (patch) | |
tree | cfad369a333db561514dcc7d4edcd1f72ddd5a33 /libs/pbd/pbd/abstract_ui.cc | |
parent | d61cf819974f47a30dd473291fa65bc939ca38be (diff) |
clean up functors used in cross-thread call_slot() messages, in case they contain shared_ptr<T>, which could result in a dangling reference
Diffstat (limited to 'libs/pbd/pbd/abstract_ui.cc')
-rw-r--r-- | libs/pbd/pbd/abstract_ui.cc | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/libs/pbd/pbd/abstract_ui.cc b/libs/pbd/pbd/abstract_ui.cc index 65f321222e..40b4ea8d93 100644 --- a/libs/pbd/pbd/abstract_ui.cc +++ b/libs/pbd/pbd/abstract_ui.cc @@ -224,6 +224,19 @@ AbstractUI<RequestObject>::handle_ui_requests () request_buffer_map_lock.unlock (); DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: valid request, calling ::do_request()\n", event_loop_name())); do_request (vec.buf[0]); + + /* 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. + * + * Note that this method (::handle_ui_requests()) is by definition called from the event loop thread, so + * caller_is_self() is true, which means that the execution of the functor has definitely happened after + * do_request() returns and we no longer need the functor for any reason. + */ + + if (vec.buf[0]->type == CallSlot) { + vec.buf[0]->the_slot = 0; + } + request_buffer_map_lock.lock (); if (vec.buf[0]->invalidation) { DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: removing invalidation record for that request\n", event_loop_name())); |