diff options
author | Sage Weil <sage@inktank.com> | 2012-12-20 13:48:06 -0800 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2012-12-20 13:48:06 -0800 |
commit | 50914e7a429acddb981bc3344f51a793280704e6 (patch) | |
tree | 45c4aa68631e29596f23d5cdc918eca6cc8cee0f | |
parent | 17c627b5e4b763f08af05f28597acc4a7b28ae78 (diff) | |
download | ceph-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.cc | 2 |
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); } |