diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2011-02-04 13:41:05 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2011-02-04 13:41:05 +0000 |
commit | 808ce59488849e0e6f367470323552884f4ef2ea (patch) | |
tree | 405188bc83b6d6acc319249f391b5b69462648b2 /libs | |
parent | 33dc722235c12777bede5e6f795cf17063b30f84 (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.cc | 67 | ||||
-rw-r--r-- | libs/pbd/pbd/abstract_ui.h | 13 |
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; |