ret = pthread_mutex_init(&m_queue_mutex, NULL);
   assert(ret == 0);
 
-  ret = pthread_cond_init(&m_cond, NULL);
+  ret = pthread_cond_init(&m_cond_loggers, NULL);
+  assert(ret == 0);
+
+  ret = pthread_cond_init(&m_cond_flusher, NULL);
   assert(ret == 0);
 
   // kludge for prealloc testing
   pthread_spin_destroy(&m_lock);
   pthread_mutex_destroy(&m_queue_mutex);
   pthread_mutex_destroy(&m_flush_mutex);
-  pthread_cond_destroy(&m_cond);
+  pthread_cond_destroy(&m_cond_loggers);
+  pthread_cond_destroy(&m_cond_flusher);
 }
 
 
 
   // wait for flush to catch up
   while (m_new.m_len > m_max_new)
-    pthread_cond_wait(&m_cond, &m_queue_mutex);
+    pthread_cond_wait(&m_cond_loggers, &m_queue_mutex);
 
   m_new.enqueue(e);
-  pthread_cond_signal(&m_cond);
+  pthread_cond_signal(&m_cond_flusher);
   pthread_mutex_unlock(&m_queue_mutex);
 }
 
   pthread_mutex_lock(&m_queue_mutex);
   EntryQueue t;
   t.swap(m_new);
-  pthread_cond_signal(&m_cond);
+  pthread_cond_broadcast(&m_cond_loggers);
   pthread_mutex_unlock(&m_queue_mutex);
   _flush(&t, &m_recent, false);
 
   assert(is_started());
   pthread_mutex_lock(&m_queue_mutex);
   m_stop = true;
-  pthread_cond_signal(&m_cond);
+  pthread_cond_signal(&m_cond_flusher);
+  pthread_cond_broadcast(&m_cond_loggers);
   pthread_mutex_unlock(&m_queue_mutex);
   join();
 }
       continue;
     }
 
-    pthread_cond_wait(&m_cond, &m_queue_mutex);
+    pthread_cond_wait(&m_cond_flusher, &m_queue_mutex);
   }
   pthread_mutex_unlock(&m_queue_mutex);
   flush();
 
   pthread_spinlock_t m_lock;
   pthread_mutex_t m_queue_mutex;
   pthread_mutex_t m_flush_mutex;
-  pthread_cond_t m_cond;
+  pthread_cond_t m_cond_loggers;
+  pthread_cond_t m_cond_flusher;
 
   EntryQueue m_new;    ///< new entries
   EntryQueue m_recent; ///< recent (less new) entries we've already written at low detail