]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
log: fix flush/signal race
authorSage Weil <sage@inktank.com>
Thu, 20 Dec 2012 21:48:06 +0000 (13:48 -0800)
committerSage Weil <sage@inktank.com>
Wed, 26 Dec 2012 22:27:42 +0000 (14:27 -0800)
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)

src/log/Log.cc

index 7c54534b0b4e5954e45d16b99a18fc3a7c2d0cd6..f3f5e19366e1b093d946513d4b0b735fc0845281 100644 (file)
@@ -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);
 }