diff options
author | Sage Weil <sage@inktank.com> | 2012-12-20 13:48:06 -0800 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2012-12-26 14:27:42 -0800 |
commit | fdae0552a0b8b1a634775609b473aff9221904f3 (patch) | |
tree | e642599a2fcd9a66256efb44f0e6d5c089e7606e | |
parent | bdcf6647dec05617d3da46ad00459498ede94f1d (diff) | |
download | ceph-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.cc | 2 |
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); } |