From 84b2b8738a54d5f2d8fb170562711565b1fa2632 Mon Sep 17 00:00:00 2001 From: casey langen Date: Sat, 31 Oct 2020 11:48:25 -0700 Subject: [PATCH] Restructure RemoteLibrary and LocalLibrary queries that use kWaitIndefinite to avoid deadlock. --- src/musikcore/library/LocalLibrary.cpp | 30 ++++++++++----------- src/musikcore/library/RemoteLibrary.cpp | 35 ++++++++++++++----------- 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/musikcore/library/LocalLibrary.cpp b/src/musikcore/library/LocalLibrary.cpp index da1c0b8c5..fac621aec 100644 --- a/src/musikcore/library/LocalLibrary.cpp +++ b/src/musikcore/library/LocalLibrary.cpp @@ -196,27 +196,27 @@ int LocalLibrary::EnqueueAndWait(QueryPtr query, size_t timeoutMs, Callback call return -1; } - auto context = std::make_shared(); - context->query = localQuery; - context->callback = callback; - - queryQueue.push_back(context); - queueCondition.notify_all(); - if (VERBOSE_LOGGING) { musik::debug::info(TAG, "query '" + localQuery->Name() + "' enqueued"); } - if (timeoutMs > 0) { - while (!this->exit && ( + auto context = std::make_shared(); + context->query = localQuery; + context->callback = callback; + + if (timeoutMs == kWaitIndefinite) { + this->RunQuery(context); + } + else { + queryQueue.push_back(context); + queueCondition.notify_all(); + + if (timeoutMs > 0) { + while (!this->exit && ( context->query->GetStatus() == db::IQuery::Idle || context->query->GetStatus() == db::IQuery::Running) - ) - { - if (timeoutMs == kWaitIndefinite) { - this->queueCondition.wait(lock); - } - else { + ) + { auto result = this->queueCondition.wait_for(lock, timeoutMs * milliseconds(1)); if (result == std::cv_status::timeout) { break; diff --git a/src/musikcore/library/RemoteLibrary.cpp b/src/musikcore/library/RemoteLibrary.cpp index 66a8b23df..318951468 100644 --- a/src/musikcore/library/RemoteLibrary.cpp +++ b/src/musikcore/library/RemoteLibrary.cpp @@ -199,24 +199,29 @@ int RemoteLibrary::EnqueueAndWait(QueryPtr query, size_t timeoutMs, Callback cal context->query = serializableQuery; context->callback = callback; - queryQueue.push_back(context); - queueCondition.notify_all(); + if (timeoutMs == kWaitIndefinite) { + this->RunQuery(context); + } + else { + queryQueue.push_back(context); + queueCondition.notify_all(); - if (timeoutMs > 0) { - while ( - !this->exit && - this->IsQueryInFlight(context->query) && - !isQueryDone(context->query)) - { - if (timeoutMs == kWaitIndefinite) { - this->syncQueryCondition.wait(lock); - break; - } - else { - auto result = this->syncQueryCondition.wait_for(lock, timeoutMs * milliseconds(1)); - if (result == std::cv_status::timeout) { + if (timeoutMs > 0) { + while ( + !this->exit && + this->IsQueryInFlight(context->query) && + !isQueryDone(context->query)) + { + if (timeoutMs == kWaitIndefinite) { + this->syncQueryCondition.wait(lock); break; } + else { + auto result = this->syncQueryCondition.wait_for(lock, timeoutMs * milliseconds(1)); + if (result == std::cv_status::timeout) { + break; + } + } } } }