diff --git a/src/common/Finisher.cc b/src/common/Finisher.cc index 5be9b04bb88..4d30fa665df 100644 --- a/src/common/Finisher.cc +++ b/src/common/Finisher.cc @@ -50,11 +50,10 @@ void *Finisher::finisher_thread_entry() /// Every time we are woken up, we process the queue until it is empty. while (!finisher_queue.empty()) { // To reduce lock contention, we swap out the queue to process. - // This way other threads can submit new contexts to complete while we are working. - vector ls; - list > ls_rval; + // This way other threads can submit new contexts to complete + // while we are working. + vector> ls; ls.swap(finisher_queue); - ls_rval.swap(finisher_queue_rval); finisher_running = true; finisher_lock.Unlock(); ldout(cct, 10) << "finisher_thread doing " << ls << dendl; @@ -65,21 +64,8 @@ void *Finisher::finisher_thread_entry() } // Now actually process the contexts. - for (vector::iterator p = ls.begin(); - p != ls.end(); - ++p) { - if (*p) { - (*p)->complete(0); - } else { - // When an item is NULL in the finisher_queue, it means - // we should instead process an item from finisher_queue_rval, - // which has a parameter for complete() other than zero. - // This preserves the order while saving some storage. - assert(!ls_rval.empty()); - Context *c = ls_rval.front().first; - c->complete(ls_rval.front().second); - ls_rval.pop_front(); - } + for (auto p : ls) { + p.first->complete(p.second); } ldout(cct, 10) << "finisher_thread done with " << ls << dendl; ls.clear(); diff --git a/src/common/Finisher.h b/src/common/Finisher.h index 96a8a78ac5a..af1f8266d38 100644 --- a/src/common/Finisher.h +++ b/src/common/Finisher.h @@ -42,17 +42,12 @@ class Finisher { 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. - vector finisher_queue; + vector> finisher_queue; string thread_name; - /// Queue for contexts for which the complete function will be called - /// with a parameter other than 0. - list > finisher_queue_rval; - /// Performance counter for the finisher's queue length. /// Only active for named finishers. PerfCounters *logger; @@ -72,21 +67,20 @@ class Finisher { if (finisher_queue.empty()) { finisher_cond.Signal(); } - if (r) { - finisher_queue_rval.push_back(pair(c, r)); - finisher_queue.push_back(NULL); - } else - finisher_queue.push_back(c); + finisher_queue.push_back(make_pair(c, r)); if (logger) logger->inc(l_finisher_queue_len); finisher_lock.Unlock(); } - void queue(vector& ls) { + + void queue(list& ls) { finisher_lock.Lock(); if (finisher_queue.empty()) { finisher_cond.Signal(); } - finisher_queue.insert(finisher_queue.end(), ls.begin(), ls.end()); + for (auto i : ls) { + finisher_queue.push_back(make_pair(i, 0)); + } if (logger) logger->inc(l_finisher_queue_len, ls.size()); finisher_lock.Unlock(); @@ -97,18 +91,22 @@ class Finisher { if (finisher_queue.empty()) { finisher_cond.Signal(); } - finisher_queue.insert(finisher_queue.end(), ls.begin(), ls.end()); + for (auto i : ls) { + finisher_queue.push_back(make_pair(i, 0)); + } if (logger) logger->inc(l_finisher_queue_len, ls.size()); finisher_lock.Unlock(); ls.clear(); } - void queue(list& ls) { + void queue(vector& ls) { finisher_lock.Lock(); if (finisher_queue.empty()) { finisher_cond.Signal(); } - finisher_queue.insert(finisher_queue.end(), ls.begin(), ls.end()); + for (auto i : ls) { + finisher_queue.push_back(make_pair(i, 0)); + } if (logger) logger->inc(l_finisher_queue_len, ls.size()); finisher_lock.Unlock();