+
+ /* and now, the generic request buffer. same rules as above apply */
+
+ Glib::Mutex::Lock lm (request_list_lock);
+
+ while (!request_list.empty()) {
+ RequestObject* req = request_list.front ();
+ request_list.pop_front ();
+
+ /* We need to use this lock, because its the one
+ returned by slot_invalidation_mutex() and protects
+ against request invalidation.
+ */
+
+ request_buffer_map_lock.lock ();
+ if (!req->valid) {
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 handling invalid heap request, type %3, deleting\n", name(), pthread_self(), req->type));
+ delete req;
+ request_buffer_map_lock.unlock ();
+ continue;
+ }
+
+ /* we're about to execute this request, so its
+ too late for any invalidation. mark
+ the request as "done" before we start.
+ */
+
+ if (req->invalidation) {
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 remove request from its invalidation list\n", name(), pthread_self()));
+
+ /* after this call, if the object referenced by the
+ * invalidation record is deleted, it will no longer
+ * try to mark the request as invalid.
+ */
+
+ req->invalidation->requests.remove (req);
+ }
+
+ /* at this point, an object involved in a functor could be
+ * deleted before we actually execute the functor. so there is
+ * a race condition that makes the invalidation architecture
+ * somewhat pointless.
+ *
+ * really, we should only allow functors containing shared_ptr
+ * references to objects to enter into the request queue.
+ */
+
+ request_buffer_map_lock.unlock ();
+
+ /* unlock the request lock while we execute the request, so
+ * that we don't needlessly block other threads (note: not RT
+ * threads since they have their own queue) from making requests.
+ */
+
+ lm.release ();
+
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 execute request type %3\n", name(), pthread_self(), req->type));
+
+ /* and lets do it ... this is a virtual call so that each
+ * specific type of UI can have its own set of requests without
+ * some kind of central request type registration logic
+ */
+
+ do_request (req);
+
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 delete heap request type %3\n", name(), pthread_self(), req->type));
+ delete req;
+
+ /* re-acquire the list lock so that we check again */
+
+ lm.acquire();
+ }