Skip to content

Commit

Permalink
Fix endless wait in RenameThreadPool (#2675)
Browse files Browse the repository at this point in the history
  • Loading branch information
UdjinM6 committed Feb 1, 2019
1 parent 1400df2 commit 2a330f1
Showing 1 changed file with 24 additions and 5 deletions.
29 changes: 24 additions & 5 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -907,18 +907,37 @@ void RenameThreadPool(ctpl::thread_pool& tp, const char* baseName)
auto cond = std::make_shared<std::condition_variable>();
auto mutex = std::make_shared<std::mutex>();
std::atomic<int> doneCnt(0);
for (size_t i = 0; i < tp.size(); i++) {
tp.push([baseName, i, cond, mutex, &doneCnt](int threadId) {
std::map<int, std::future<void> > futures;

for (int i = 0; i < tp.size(); i++) {
futures[i] = tp.push([baseName, i, cond, mutex, &doneCnt](int threadId) {
RenameThread(strprintf("%s-%d", baseName, i).c_str());
doneCnt++;
std::unique_lock<std::mutex> l(*mutex);
doneCnt++;
cond->wait(l);
});
}
while (doneCnt != tp.size()) {

do {
// Always sleep to let all threads acquire locks
MilliSleep(10);
}
// `doneCnt` should be at least `futures.size()` if tp size was increased (for whatever reason),
// or at least `tp.size()` if tp size was decreased and queue was cleared
// (which can happen on `stop()` if we were not fast enough to get all jobs to their threads).
} while (doneCnt < futures.size() && doneCnt < tp.size());

cond->notify_all();

// Make sure no one is left behind, just in case
for (auto& pair : futures) {
auto& f = pair.second;
if (f.valid() && f.wait_for(std::chrono::milliseconds(2000)) == std::future_status::timeout) {
LogPrintf("%s: %s-%d timed out\n", __func__, baseName, pair.first);
// Notify everyone again
cond->notify_all();
break;
}
}
}

void SetupEnvironment()
Expand Down

0 comments on commit 2a330f1

Please sign in to comment.