summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2012-12-20 13:48:06 -0800
committerSage Weil <sage@inktank.com>2012-12-26 14:27:42 -0800
commitfdae0552a0b8b1a634775609b473aff9221904f3 (patch)
treee642599a2fcd9a66256efb44f0e6d5c089e7606e
parentbdcf6647dec05617d3da46ad00459498ede94f1d (diff)
downloadceph-fdae0552a0b8b1a634775609b473aff9221904f3.tar.gz
log: fix flush/signal race
We need to signal the cond in the same interval where we hold the lock *and* modify the queue. Otherwise, we can have a race like: queue has 1 item, max is 1. A: enter submit_entry, signal cond, wait on condition B: enter submit_entry, signal cond, wait on condition C: flush wakes up, flushes 1 previous item A: retakes lock, enqueues something, exits B: retakes lock, condition fails, waits -> C is never woken up as there are 2 items waiting Signed-off-by: Sage Weil <sage@inktank.com> Reviewed-by: Dan Mick <dan.mick@inktank.com> (cherry picked from commit 50914e7a429acddb981bc3344f51a793280704e6)
-rw-r--r--src/log/Log.cc2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/log/Log.cc b/src/log/Log.cc
index 7c54534b0b4..f3f5e19366e 100644
--- a/src/log/Log.cc
+++ b/src/log/Log.cc
@@ -136,13 +136,13 @@ void Log::set_stderr_level(int log, int crash)
void Log::submit_entry(Entry *e)
{
pthread_mutex_lock(&m_queue_mutex);
- pthread_cond_signal(&m_cond);
// wait for flush to catch up
while (m_new.m_len > m_max_new)
pthread_cond_wait(&m_cond, &m_queue_mutex);
m_new.enqueue(e);
+ pthread_cond_signal(&m_cond);
pthread_mutex_unlock(&m_queue_mutex);
}