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-20 13:48:06 -0800
commit50914e7a429acddb981bc3344f51a793280704e6 (patch)
tree45c4aa68631e29596f23d5cdc918eca6cc8cee0f
parent17c627b5e4b763f08af05f28597acc4a7b28ae78 (diff)
downloadceph-50914e7a429acddb981bc3344f51a793280704e6.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>
-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 32d8be79c45..51a340ffcb1 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);
}