summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2011-02-04 13:41:05 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2011-02-04 13:41:05 +0000
commit808ce59488849e0e6f367470323552884f4ef2ea (patch)
tree405188bc83b6d6acc319249f391b5b69462648b2 /libs
parent33dc722235c12777bede5e6f795cf17063b30f84 (diff)
better (?) fix for handling cleanup of per-thread UI request buffers : the thread mark the buffer as dead, and the UI gets to cleanup when appropriate
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@8700 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/pbd/pbd/abstract_ui.cc67
-rw-r--r--libs/pbd/pbd/abstract_ui.h13
2 files changed, 52 insertions, 28 deletions
diff --git a/libs/pbd/pbd/abstract_ui.cc b/libs/pbd/pbd/abstract_ui.cc
index f8fd947685..ed81f738d6 100644
--- a/libs/pbd/pbd/abstract_ui.cc
+++ b/libs/pbd/pbd/abstract_ui.cc
@@ -13,7 +13,12 @@ template<typename RequestBuffer> void
cleanup_request_buffer (void* ptr)
{
RequestBuffer* rb = (RequestBuffer*) ptr;
- delete rb;
+
+ {
+ cerr << "Thread dies with a per-thread buffer for ui " << rb->ui.name() << endl;
+ Glib::Mutex::Lock lm (rb->ui.request_buffer_map_lock);
+ rb->dead = true;
+ }
}
template <typename RequestObject>
@@ -52,7 +57,7 @@ AbstractUI<RequestObject>::register_thread_with_request_count (pthread_t thread_
return;
}
- RequestBuffer* b = new RequestBuffer (num_requests);
+ RequestBuffer* b = new RequestBuffer (num_requests, *this);
{
Glib::Mutex::Lock lm (request_buffer_map_lock);
@@ -115,33 +120,43 @@ AbstractUI<RequestObject>::handle_ui_requests ()
request_buffer_map_lock.lock ();
- for (i = request_buffers.begin(); i != request_buffers.end(); ++i) {
+ for (i = request_buffers.begin(); i != request_buffers.end(); ) {
RequestBufferVector vec;
- while (true) {
-
- /* we must process requests 1 by 1 because
- the request may run a recursive main
- event loop that will itself call
- handle_ui_requests. when we return
- from the request handler, we cannot
- expect that the state of queued requests
- is even remotely consistent with
- the condition before we called it.
- */
-
- i->second->get_read_vector (&vec);
-
- if (vec.len[0] == 0) {
- break;
- } else {
- request_buffer_map_lock.unlock ();
- do_request (vec.buf[0]);
- request_buffer_map_lock.lock ();
- i->second->increment_read_ptr (1);
- }
- }
+ if ((*i).second->dead) {
+ cerr << "Seen a dead request buffer - cleaning it up ..\n";
+ delete (*i).second;
+ RequestBufferMapIterator tmp = i;
+ ++tmp;
+ request_buffers.erase (i);
+ i = tmp;
+ } else {
+ while (true) {
+
+ /* we must process requests 1 by 1 because
+ the request may run a recursive main
+ event loop that will itself call
+ handle_ui_requests. when we return
+ from the request handler, we cannot
+ expect that the state of queued requests
+ is even remotely consistent with
+ the condition before we called it.
+ */
+
+ i->second->get_read_vector (&vec);
+
+ if (vec.len[0] == 0) {
+ break;
+ } else {
+ request_buffer_map_lock.unlock ();
+ do_request (vec.buf[0]);
+ request_buffer_map_lock.lock ();
+ i->second->increment_read_ptr (1);
+ }
+ }
+ ++i;
+ }
}
request_buffer_map_lock.unlock ();
diff --git a/libs/pbd/pbd/abstract_ui.h b/libs/pbd/pbd/abstract_ui.h
index 7718d944ea..f20d0a35f3 100644
--- a/libs/pbd/pbd/abstract_ui.h
+++ b/libs/pbd/pbd/abstract_ui.h
@@ -58,12 +58,21 @@ class AbstractUI : public BaseUI
void register_thread_with_request_count (pthread_t, std::string, uint32_t num_requests);
void unregister_thread (pthread_t);
+ Glib::Mutex request_buffer_map_lock;
+
protected:
- typedef RingBufferNPT<RequestObject> RequestBuffer;
+ struct RequestBuffer : public RingBufferNPT<RequestObject> {
+ bool dead;
+ AbstractUI<RequestObject>& ui;
+ RequestBuffer (uint32_t size, AbstractUI<RequestObject>& uir)
+ : RingBufferNPT<RequestObject> (size)
+ , dead (false)
+ , ui (uir) {}
+ };
+
typedef typename RequestBuffer::rw_vector RequestBufferVector;
typedef typename std::map<pthread_t,RequestBuffer*>::iterator RequestBufferMapIterator;
- Glib::Mutex request_buffer_map_lock;
typedef std::map<pthread_t,RequestBuffer*> RequestBufferMap;
RequestBufferMap request_buffers;
pthread_key_t thread_request_buffer_key;