finisher_lock.Lock();
while (!finisher_queue.empty() || finisher_running) {
ldout(cct, 10) << "wait_for_empty waiting" << dendl;
+ finisher_empty_wait = true;
finisher_empty_cond.Wait(finisher_lock);
}
ldout(cct, 10) << "wait_for_empty empty" << dendl;
+ finisher_empty_wait = false;
finisher_lock.Unlock();
}
finisher_running = false;
}
ldout(cct, 10) << "finisher_thread empty" << dendl;
- finisher_empty_cond.Signal();
+ if (unlikely(finisher_empty_wait))
+ finisher_empty_cond.Signal();
if (finisher_stop)
break;
Cond finisher_empty_cond; ///< Signaled when the finisher has nothing more to process.
bool finisher_stop; ///< Set when the finisher should stop.
bool finisher_running; ///< True when the finisher is currently executing contexts.
+ bool finisher_empty_wait; ///< True mean someone wait finisher empty.
/// Queue for contexts for which complete(0) will be called.
/// NULLs in this queue indicate that an item from finisher_queue_rval
/// should be completed in that place instead.
/// Anonymous finishers do not log their queue length.
explicit Finisher(CephContext *cct_) :
cct(cct_), finisher_lock("Finisher::finisher_lock"),
- finisher_stop(false), finisher_running(false),
+ finisher_stop(false), finisher_running(false), finisher_empty_wait(false),
thread_name("fn_anonymous"), logger(0),
finisher_thread(this) {}
/// Construct a named Finisher that logs its queue length.
Finisher(CephContext *cct_, string name, string tn) :
cct(cct_), finisher_lock("Finisher::" + name),
- finisher_stop(false), finisher_running(false),
+ finisher_stop(false), finisher_running(false), finisher_empty_wait(false),
thread_name(tn), logger(0),
finisher_thread(this) {
PerfCountersBuilder b(cct, string("finisher-") + name,