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
.
This commit is contained in:
parent
07bcdc7f0a
commit
62b06fa427
|
@ -95,8 +95,9 @@ EventLoop::invalidate_request (void* data)
|
||||||
(*i)->invalidation = 0;
|
(*i)->invalidation = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// should this not always be deleted, regardless if there's an event_loop?
|
// This invalidation record may still be in-use in per-thread-request-ringbuffer.
|
||||||
delete ir;
|
// it cannot be deleted here,
|
||||||
|
ir->event_loop->trash.push_back(ir);
|
||||||
} else {
|
} else {
|
||||||
DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("EventLoop::invalidate_request no event-loop for invalidation %1\n", ir));
|
DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("EventLoop::invalidate_request no event-loop for invalidation %1\n", ir));
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,6 +218,7 @@ AbstractUI<RequestObject>::handle_ui_requests ()
|
||||||
if (vec.len[0] == 0) {
|
if (vec.len[0] == 0) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
bool alive = true;
|
||||||
if (vec.buf[0]->valid ()) {
|
if (vec.buf[0]->valid ()) {
|
||||||
/* We first need to remove the event from the list.
|
/* We first need to remove the event from the list.
|
||||||
* If the event results in object destruction, PBD::EventLoop::invalidate_request
|
* 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));
|
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) {
|
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()));
|
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) {
|
if (vec.buf[0]->invalidation->event_loop && vec.buf[0]->invalidation->event_loop != this) {
|
||||||
vec.buf[0]->invalidation->event_loop->slot_invalidation_mutex().lock ();
|
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()));
|
DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: valid request, unlocking before calling\n", event_loop_name()));
|
||||||
rbml.release ();
|
rbml.release ();
|
||||||
|
|
||||||
DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: valid request, calling ::do_request()\n", event_loop_name()));
|
if (alive) {
|
||||||
do_request (vec.buf[0]);
|
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
|
/* 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.
|
* 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 ());
|
assert (rbml.locked ());
|
||||||
for (i = request_buffers.begin(); i != request_buffers.end(); ) {
|
for (i = request_buffers.begin(); i != request_buffers.end(); ) {
|
||||||
if ((*i).second->dead) {
|
if ((*i).second->dead) {
|
||||||
|
@ -370,6 +374,15 @@ AbstractUI<RequestObject>::handle_ui_requests ()
|
||||||
rbml.acquire();
|
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 ();
|
rbml.release ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,8 @@ public:
|
||||||
static void pre_register (const std::string& emitting_thread_name, uint32_t num_requests);
|
static void pre_register (const std::string& emitting_thread_name, uint32_t num_requests);
|
||||||
static void remove_request_buffer_from_map (void* ptr);
|
static void remove_request_buffer_from_map (void* ptr);
|
||||||
|
|
||||||
|
std::list<InvalidationRecord*> trash;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Glib::Threads::Private<EventLoop> thread_event_loop;
|
static Glib::Threads::Private<EventLoop> thread_event_loop;
|
||||||
std::string _name;
|
std::string _name;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user