Atomically to invalidate request
authorRobin Gareus <robin@gareus.org>
Wed, 14 Dec 2016 21:19:33 +0000 (22:19 +0100)
committerRobin Gareus <robin@gareus.org>
Wed, 14 Dec 2016 21:39:18 +0000 (22:39 +0100)
Yet another slightly overkill approach, but it /may/ explain crashes.

libs/pbd/event_loop.cc
libs/pbd/pbd/abstract_ui.cc
libs/pbd/pbd/event_loop.h

index 926c7016d35ffeab44e2f9d8546fcb414cd72b90..0baba2835a4e04ab3cec41b34a61880ddbc854b3 100644 (file)
@@ -91,7 +91,7 @@ EventLoop::invalidate_request (void* data)
                {
                        Glib::Threads::Mutex::Lock lm (ir->event_loop->slot_invalidation_mutex());
                        for (list<BaseRequestObject*>::iterator i = ir->requests.begin(); i != ir->requests.end(); ++i) {
-                               (*i)->valid = false;
+                               (*i)->invalidate ();
                                (*i)->invalidation = 0;
                        }
                }
index 330e6ddc595bfb2df3f9da1465148d6f3db0e2a9..db63c3f96d10d48fd72ce575ca38ea691512379e 100644 (file)
@@ -168,7 +168,7 @@ AbstractUI<RequestObject>::get_request (RequestType rt)
                DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: allocated per-thread request of type %2, caller %3\n", event_loop_name(), rt, pthread_name()));
 
                vec.buf[0]->type = rt;
-               vec.buf[0]->valid = true;
+               vec.buf[0]->validate ();
                return vec.buf[0];
        }
 
@@ -218,7 +218,7 @@ AbstractUI<RequestObject>::handle_ui_requests ()
                        if (vec.len[0] == 0) {
                                break;
                        } else {
-                               if (vec.buf[0]->valid) {
+                               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
                                         * will delete the invalidation record (aka buf[0]), so we cannot use it after calling do_request
@@ -327,7 +327,7 @@ AbstractUI<RequestObject>::handle_ui_requests ()
                        }
                }
 
-               if (!req->valid) {
+               if (!req->valid ()) {
                        DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 handling invalid heap request, type %3, deleting\n", event_loop_name(), pthread_name(), req->type));
                        delete req;
                        continue;
index f7765cb79200db5fc434502dea743e044dd06261..ce2040084c27d0654234c3fb2b012e9aa319759c 100644 (file)
@@ -67,12 +67,16 @@ class LIBPBD_API EventLoop
         static void* invalidate_request (void* data);
 
        struct BaseRequestObject {
-           RequestType             type;
-            bool                    valid;
-            InvalidationRecord*     invalidation;
-           boost::function<void()> the_slot;
+               RequestType             type;
+               gint                    _valid;
+               InvalidationRecord*     invalidation;
+               boost::function<void()> the_slot;
 
-            BaseRequestObject() : valid (true), invalidation (0) {}
+               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; }
        };
 
        virtual void call_slot (InvalidationRecord*, const boost::function<void()>&) = 0;