aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-11-03 12:10:51 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-11-03 12:10:51 +0000
commit56a6275a62b34a697cf92ebc3bc5a4286c946865 (patch)
tree7f9072dbffa0ce05fac5b887115f6d265383b905
parent6aa4c54709797a52c468059e2e5120126a9b3042 (diff)
downloadpaludis-56a6275a62b34a697cf92ebc3bc5a4286c946865.tar.gz
paludis-56a6275a62b34a697cf92ebc3bc5a4286c946865.tar.xz
Fix qualudis deadlock, attempt two
-rw-r--r--paludis/repositories/e/qa/qa_controller.cc29
1 files changed, 11 insertions, 18 deletions
diff --git a/paludis/repositories/e/qa/qa_controller.cc b/paludis/repositories/e/qa/qa_controller.cc
index a4203c1..385ee0d 100644
--- a/paludis/repositories/e/qa/qa_controller.cc
+++ b/paludis/repositories/e/qa/qa_controller.cc
@@ -45,12 +45,14 @@ namespace
{
QAReporter & base;
Mutex mutex, flush_mutex;
+ ActionQueue message_queue;
std::multimap<const FSEntry, const QAMessage> message_buf;
typedef std::multimap<const FSEntry, const QAMessage>::iterator MessageIterator;
ThreadSafeQAReporter(QAReporter & b) :
- base(b)
+ base(b),
+ message_queue(1, false, false)
{
}
@@ -67,26 +69,17 @@ namespace
void flush(const FSEntry & f)
{
- std::list<QAMessage> to_flush;
+ Lock lock(mutex);
+ std::string root(stringify(f));
+ for (MessageIterator i(message_buf.lower_bound(f)), i_end(message_buf.end()) ; i != i_end ; )
{
- Lock lock(mutex);
- std::string root(stringify(f));
-
- for (MessageIterator i(message_buf.lower_bound(f)), i_end(message_buf.end()) ; i != i_end ; )
- {
- if (0 != stringify(i->first).compare(0, root.length(), root))
- break;
-
- /* don't call base.message whilst we hold the map lock. It'll deadlock. */
- to_flush.push_back(i->second);
- message_buf.erase(i++);
- }
- }
+ if (0 != stringify(i->first).compare(0, root.length(), root))
+ break;
- using namespace tr1::placeholders;
- Lock lock(flush_mutex);
- std::for_each(to_flush.begin(), to_flush.end(), tr1::bind(&QAReporter::message, &base, _1));
+ message_queue.enqueue(tr1::bind(&QAReporter::message, &base, i->second));
+ message_buf.erase(i++);
+ }
}
void message(const QAMessage & msg)