diff options
author | Robin Gareus <robin@gareus.org> | 2016-12-15 06:11:20 +0100 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2016-12-15 06:11:30 +0100 |
commit | a95be76741c29a6ec1eb9684eed1696b3fb405d6 (patch) | |
tree | 60445d9519f26bf6bd5228caaffbbfdae50cb450 /libs/pbd/pbd/event_loop.h | |
parent | 62b06fa427b4f432f82510f51e4b6920280b17a8 (diff) |
rework request invalidation
This kills 2 birds with 1 stone: Removes the necessity of locks
and makes call_slot() realtime safe (req->invalidation->requests list
push_back). On object destruction, the invalidation-record (IR) itself is
invalidated.
Invalidated IRs are pushed onto a trash-pool and deleted in the event-loop
of the invalidated object (GUI thread) once all requests that reference it
have been processed.
One last detail remains: PBD::signal connect should reference the IR
and disconnect unreference it. This will guarantee that signal emission
will not reference the IR while the pool trash is dropped.
Diffstat (limited to 'libs/pbd/pbd/event_loop.h')
-rw-r--r-- | libs/pbd/pbd/event_loop.h | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/libs/pbd/pbd/event_loop.h b/libs/pbd/pbd/event_loop.h index e84832ebcb..09265c13d8 100644 --- a/libs/pbd/pbd/event_loop.h +++ b/libs/pbd/pbd/event_loop.h @@ -58,25 +58,33 @@ public: struct InvalidationRecord { std::list<BaseRequestObject*> requests; PBD::EventLoop* event_loop; + gint _valid; + gint _ref; const char* file; int line; - InvalidationRecord() : event_loop (0) {} + InvalidationRecord() : event_loop (0), _valid (1), _ref (0) {} + void invalidate () { g_atomic_int_set (&_valid, 0); } + bool valid () { return g_atomic_int_get (&_valid) == 1; } + + void ref () { g_atomic_int_inc (&_ref); } + void unref () { g_atomic_int_dec_and_test (&_ref); } + bool in_use () { return g_atomic_int_get (&_ref) > 0; } }; static void* invalidate_request (void* data); struct BaseRequestObject { RequestType type; - gint _valid; InvalidationRecord* invalidation; boost::function<void()> the_slot; - BaseRequestObject() : _valid (0), invalidation (0) {} - - void validate () { g_atomic_int_set (&_valid, 1); } - void invalidate () { g_atomic_int_set (&_valid, 0); } - bool valid () { return g_atomic_int_get (&_valid) == 1; } + BaseRequestObject() : invalidation (0) {} + ~BaseRequestObject() { + if (invalidation) { + invalidation->unref (); + } + } }; virtual void call_slot (InvalidationRecord*, const boost::function<void()>&) = 0; |