From 95b219344421f9312f5de496b8bbe3cba7bb5c9d Mon Sep 17 00:00:00 2001 From: Jason Bray Date: Fri, 15 May 2020 01:52:32 -0700 Subject: [PATCH 1/4] Fix most remaining task cancellation race conditions --- lib/include/public/ITaskDispatcher.hpp | 2 +- lib/offline/OfflineStorageHandler.cpp | 4 +-- lib/pal/TaskDispatcher.hpp | 32 +++++++++++------ lib/pal/TaskDispatcher_CAPI.cpp | 2 +- lib/pal/TaskDispatcher_CAPI.hpp | 2 +- lib/pal/WorkerThread.cpp | 50 +++++++++++++++++--------- lib/system/TelemetrySystem.cpp | 2 ++ lib/tpm/TransmissionPolicyManager.cpp | 1 + lib/tpm/TransmissionPolicyManager.hpp | 20 +++++------ 9 files changed, 72 insertions(+), 43 deletions(-) diff --git a/lib/include/public/ITaskDispatcher.hpp b/lib/include/public/ITaskDispatcher.hpp index 60ef2f02c..2946e26a8 100644 --- a/lib/include/public/ITaskDispatcher.hpp +++ b/lib/include/public/ITaskDispatcher.hpp @@ -118,7 +118,7 @@ namespace ARIASDK_NS_BEGIN /// Task to be cancelled /// Amount of time to wait for if the task is currently executing /// True if successfully cancelled, else false - virtual bool Cancel(Task* task, uint64_t waitTime = 0) = 0; + virtual bool Cancel(Task* task, bool wait_for_cancel = false) = 0; }; /// @endcond diff --git a/lib/offline/OfflineStorageHandler.cpp b/lib/offline/OfflineStorageHandler.cpp index 61d88d557..7547e7dcd 100644 --- a/lib/offline/OfflineStorageHandler.cpp +++ b/lib/offline/OfflineStorageHandler.cpp @@ -61,7 +61,7 @@ namespace ARIASDK_NS_BEGIN { if (!m_flushPending) return; } - LOG_INFO("Waiting for pending Flush (%p) to complete...", m_flushHandle.m_task.load()); + LOG_INFO("Waiting for pending Flush (%p) to complete...", m_flushHandle.m_task); m_flushComplete.wait(); } @@ -259,7 +259,7 @@ namespace ARIASDK_NS_BEGIN { m_flushPending = true; m_flushComplete.Reset(); m_flushHandle = PAL::scheduleTask(&m_taskDispatcher, 0, this, &OfflineStorageHandler::Flush); - LOG_INFO("Requested Flush (%p)", m_flushHandle.m_task.load()); + LOG_INFO("Requested Flush (%p)", m_flushHandle.m_task); } m_flushLock.unlock(); } diff --git a/lib/pal/TaskDispatcher.hpp b/lib/pal/TaskDispatcher.hpp index 6b418b8b8..d528a4b42 100644 --- a/lib/pal/TaskDispatcher.hpp +++ b/lib/pal/TaskDispatcher.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include "ITaskDispatcher.hpp" #include "Version.hpp" @@ -59,33 +60,42 @@ namespace PAL_NS_BEGIN { class DeferredCallbackHandle { public: - std::atomic m_task; + std::mutex m_mutex; + MAT::Task* m_task; MAT::ITaskDispatcher* m_taskDispatcher; DeferredCallbackHandle(MAT::Task* task, MAT::ITaskDispatcher* taskDispatcher) : m_task(task), m_taskDispatcher(taskDispatcher) { }; DeferredCallbackHandle() : m_task(nullptr), m_taskDispatcher(nullptr) {}; - DeferredCallbackHandle(const DeferredCallbackHandle& h) : - m_task(h.m_task.load()), - m_taskDispatcher(h.m_taskDispatcher) { }; + DeferredCallbackHandle(DeferredCallbackHandle&& h) + { + *this = std::move(h); + }; - DeferredCallbackHandle& operator=(DeferredCallbackHandle other) + DeferredCallbackHandle& operator=(DeferredCallbackHandle&& other) { - m_task = other.m_task.load(); + std::lock_guard lock(m_mutex); + std::lock_guard lock2(other.m_mutex); + m_task = other.m_task; + other.m_task = nullptr; m_taskDispatcher = other.m_taskDispatcher; + return *this; } - bool Cancel(uint64_t waitTime = 0) + bool Cancel(bool wait_for_cancel = false) { - MAT::Task* m_current_task = m_task.exchange(nullptr); - if (m_current_task) + std::lock_guard lock(m_mutex); + if (m_task) { - bool result = (m_taskDispatcher != nullptr) && (m_taskDispatcher->Cancel(m_current_task, waitTime)); + bool result = (m_taskDispatcher != nullptr) && (m_taskDispatcher->Cancel(m_task, wait_for_cancel)); return result; } - return false; + else { + // Canceled nothing successfully + return true; + } } }; diff --git a/lib/pal/TaskDispatcher_CAPI.cpp b/lib/pal/TaskDispatcher_CAPI.cpp index 8aa8bdea7..09ff8fa72 100644 --- a/lib/pal/TaskDispatcher_CAPI.cpp +++ b/lib/pal/TaskDispatcher_CAPI.cpp @@ -126,7 +126,7 @@ namespace PAL_NS_BEGIN { } // TODO: currently shutdown wait on task cancellation is not implemented for C API Task Dispatcher - bool TaskDispatcher_CAPI::Cancel(Task* task, uint64_t) + bool TaskDispatcher_CAPI::Cancel(Task* task, bool) { std::string taskId; diff --git a/lib/pal/TaskDispatcher_CAPI.hpp b/lib/pal/TaskDispatcher_CAPI.hpp index 66d22ddf7..c0bed50d5 100644 --- a/lib/pal/TaskDispatcher_CAPI.hpp +++ b/lib/pal/TaskDispatcher_CAPI.hpp @@ -12,7 +12,7 @@ namespace PAL_NS_BEGIN { TaskDispatcher_CAPI(task_dispatcher_queue_fn_t queueFn, task_dispatcher_cancel_fn_t cancelFn, task_dispatcher_join_fn_t joinFn); void Join() override; void Queue(MAT::Task* task) override; - bool Cancel(MAT::Task* task, uint64_t waitTime = 0) override; + bool Cancel(MAT::Task* task, bool wait_for_cancel = false) override; private: task_dispatcher_queue_fn_t m_queueFn; diff --git a/lib/pal/WorkerThread.cpp b/lib/pal/WorkerThread.cpp index 093b7aead..e069f63e5 100644 --- a/lib/pal/WorkerThread.cpp +++ b/lib/pal/WorkerThread.cpp @@ -7,9 +7,12 @@ /* Maximum scheduler interval for SDK is 1 hour required for clamping in case of monotonic clock drift */ #define MAX_FUTURE_DELTA_MS (60 * 60 * 1000) -// Polling interval for task cancellation can be customized at compile-time -#ifndef TASK_CANCEL_WAIT_MS -#define TASK_CANCEL_WAIT_MS 50 +// This macro allows to specify max upload task cancellation wait time at compile-time, +// addressing the case when a task that we are trying to cancel is currently running. +// Default value: 500ms - sufficient for upload scheduler/batcher task to finish. +// Alternate value: UINT64_MAX - for infinite wait until the task is completed. +#ifndef TASK_CANCEL_TIME_MS +#define TASK_CANCEL_TIME_MS 500 #endif namespace PAL_NS_BEGIN { @@ -31,6 +34,7 @@ namespace PAL_NS_BEGIN { // TODO: [MG] - investigate all the cases why we need recursive here std::recursive_mutex m_lock; + std::timed_mutex m_execution_mutex; std::list m_queue; std::list m_timerQueue; @@ -100,7 +104,7 @@ namespace PAL_NS_BEGIN { // // - acquire the m_lock to prevent a new task from getting scheduled. // This may block the scheduling of a new task in queue for up to - // TASK_CANCEL_WAIT_MS=50 ms in case if the task being canceled + // TASK_CANCEL_TIME_MS in case if the task being canceled // is the one being executed right now. // // - if currently executing task is the one we are trying to cancel, @@ -121,7 +125,7 @@ namespace PAL_NS_BEGIN { // - TASK_COMPLETED - task found and ran to completion // - TASK_RUNNING - task is still running (insufficient waitTime) // - bool Cancel(MAT::Task* item, uint64_t waitTime) override + bool Cancel(MAT::Task* item, bool wait_for_cancel) override { LOCKGUARD(m_lock); if (item == nullptr) @@ -134,12 +138,19 @@ namespace PAL_NS_BEGIN { /* Can't recursively wait on completion of our own thread */ if (m_hThread.get_id() != std::this_thread::get_id()) { - while ((waitTime > TASK_CANCEL_WAIT_MS) && (m_itemInProgress == item)) + if (wait_for_cancel && m_execution_mutex.try_lock_for(std::chrono::milliseconds(TASK_CANCEL_TIME_MS))) { - PAL::sleep(TASK_CANCEL_WAIT_MS); - waitTime -= TASK_CANCEL_WAIT_MS; + m_itemInProgress = nullptr; + m_execution_mutex.unlock(); } } + else + { + // The SDK may attempt to cancel itself from within its own task. + // Return true and assume that the current task will finish, and therefore be cancelled. + return true; + } + /* Either waited long enough or the task is still executing. Return: * true - if item in progress is different than item (other task) * false - if item in progress is still the same (didn't wait long enough) @@ -153,7 +164,6 @@ namespace PAL_NS_BEGIN { // Still in the queue m_timerQueue.erase(it); delete item; - return true; } } #if 0 @@ -167,7 +177,7 @@ namespace PAL_NS_BEGIN { Sleep(10); } #endif - return false; + return true; } protected: @@ -229,13 +239,21 @@ namespace PAL_NS_BEGIN { break; } - LOG_TRACE("%10llu Execute item=%p type=%s\n", wakeupCount, item.get(), item.get()->TypeName.c_str() ); - (*item)(); - self->m_itemInProgress = nullptr; + { + std::lock_guard lock(self->m_execution_mutex); - if (item.get()) { - item->Type = MAT::Task::Done; - item.reset(); + // Item wasn't cancelled before it could be executed + if (self->m_itemInProgress != nullptr) { + LOG_TRACE("%10llu Execute item=%p type=%s\n", wakeupCount, item.get(), item.get()->TypeName.c_str() ); + PAL::sleep(200); + (*item)(); + self->m_itemInProgress = nullptr; + } + + if (item.get()) { + item->Type = MAT::Task::Done; + item.reset(); + } } } } diff --git a/lib/system/TelemetrySystem.cpp b/lib/system/TelemetrySystem.cpp index f5a5a3afd..cc9c5fd45 100644 --- a/lib/system/TelemetrySystem.cpp +++ b/lib/system/TelemetrySystem.cpp @@ -81,6 +81,8 @@ namespace ARIASDK_NS_BEGIN { // cancel all pending and force-finish all uploads stopTimes[1] = GetUptimeMs(); + // TODO: should this still pause, since the TPM now has abort logic in addition to pause logic? + // it doesn't seem particularly useful onPause(); hcm.cancelAllRequests(); tpm.finishAllUploads(); diff --git a/lib/tpm/TransmissionPolicyManager.cpp b/lib/tpm/TransmissionPolicyManager.cpp index c483f7b3f..6fb26247b 100644 --- a/lib/tpm/TransmissionPolicyManager.cpp +++ b/lib/tpm/TransmissionPolicyManager.cpp @@ -255,6 +255,7 @@ namespace ARIASDK_NS_BEGIN { // Called from finishAllUploads void TransmissionPolicyManager::handleFinishAllUploads() { + // TODO: This pause appears to server no practical purpose? pauseAllUploads(); allUploadsFinished(); // calls stats.onStop >> this->flushTaskDispatcher; } diff --git a/lib/tpm/TransmissionPolicyManager.hpp b/lib/tpm/TransmissionPolicyManager.hpp index 3b081a074..a3555d835 100644 --- a/lib/tpm/TransmissionPolicyManager.hpp +++ b/lib/tpm/TransmissionPolicyManager.hpp @@ -18,14 +18,6 @@ #include #include -// This macro allows to specify max upload task cancellation wait time at compile-time, -// addressing the case when a task that we are trying to cancel is currently running. -// Default value: 500ms - sufficient for upload scheduler/batcher task to finish. -// Alternate value: UINT64_MAX - for infinite wait until the task is completed. -#ifndef UPLOAD_TASK_CANCEL_TIME_MS -#define UPLOAD_TASK_CANCEL_TIME_MS 500 -#endif - namespace ARIASDK_NS_BEGIN { class TransmissionPolicyManager @@ -126,9 +118,15 @@ namespace ARIASDK_NS_BEGIN { /// bool cancelUploadTask() { - uint64_t cancelWaitTimeMs = (m_scheduledUploadAborted) ? UPLOAD_TASK_CANCEL_TIME_MS : 0; - bool result = m_scheduledUpload.Cancel(cancelWaitTimeMs); - m_isUploadScheduled.exchange(false); + bool result = m_scheduledUpload.Cancel(/*wait_for_cancel*/ m_scheduledUploadAborted); + + // TODO: There is a potential for upload tasks to not be canceled, especially if they aren't waited for. + // We either need a stronger guarantee here (could impact SDK performance), or a mechanism to + // ensure those tasks are canceled when the log manager is destroyed. + if (result) + { + m_isUploadScheduled.exchange(false); + } return result; } From 0a34ac9723efb02dde2ccf6cbe687d2faf3b67db Mon Sep 17 00:00:00 2001 From: Jason Bray Date: Mon, 18 May 2020 01:09:35 -0700 Subject: [PATCH 2/4] Remove extra wait used for testing --- lib/pal/WorkerThread.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/pal/WorkerThread.cpp b/lib/pal/WorkerThread.cpp index e069f63e5..14a569786 100644 --- a/lib/pal/WorkerThread.cpp +++ b/lib/pal/WorkerThread.cpp @@ -245,7 +245,6 @@ namespace PAL_NS_BEGIN { // Item wasn't cancelled before it could be executed if (self->m_itemInProgress != nullptr) { LOG_TRACE("%10llu Execute item=%p type=%s\n", wakeupCount, item.get(), item.get()->TypeName.c_str() ); - PAL::sleep(200); (*item)(); self->m_itemInProgress = nullptr; } From 53706d1836c1dafd14940e8779e19aab28b5b7b9 Mon Sep 17 00:00:00 2001 From: Jason Bray Date: Mon, 18 May 2020 14:20:13 -0700 Subject: [PATCH 3/4] Re-expose wait time in API, link issues, and small clarity changes --- lib/include/public/ITaskDispatcher.hpp | 2 +- lib/pal/TaskDispatcher.hpp | 12 ++++++------ lib/pal/TaskDispatcher_CAPI.cpp | 2 +- lib/pal/TaskDispatcher_CAPI.hpp | 2 +- lib/pal/WorkerThread.cpp | 16 ++++------------ lib/system/TelemetrySystem.cpp | 4 ++-- lib/tpm/TransmissionPolicyManager.hpp | 13 +++++++++++-- 7 files changed, 26 insertions(+), 25 deletions(-) diff --git a/lib/include/public/ITaskDispatcher.hpp b/lib/include/public/ITaskDispatcher.hpp index 2946e26a8..60ef2f02c 100644 --- a/lib/include/public/ITaskDispatcher.hpp +++ b/lib/include/public/ITaskDispatcher.hpp @@ -118,7 +118,7 @@ namespace ARIASDK_NS_BEGIN /// Task to be cancelled /// Amount of time to wait for if the task is currently executing /// True if successfully cancelled, else false - virtual bool Cancel(Task* task, bool wait_for_cancel = false) = 0; + virtual bool Cancel(Task* task, uint64_t waitTime = 0) = 0; }; /// @endcond diff --git a/lib/pal/TaskDispatcher.hpp b/lib/pal/TaskDispatcher.hpp index d528a4b42..28d80539c 100644 --- a/lib/pal/TaskDispatcher.hpp +++ b/lib/pal/TaskDispatcher.hpp @@ -61,13 +61,13 @@ namespace PAL_NS_BEGIN { { public: std::mutex m_mutex; - MAT::Task* m_task; - MAT::ITaskDispatcher* m_taskDispatcher; + MAT::Task* m_task = nullptr; + MAT::ITaskDispatcher* m_taskDispatcher = nullptr; DeferredCallbackHandle(MAT::Task* task, MAT::ITaskDispatcher* taskDispatcher) : m_task(task), m_taskDispatcher(taskDispatcher) { }; - DeferredCallbackHandle() : m_task(nullptr), m_taskDispatcher(nullptr) {}; + DeferredCallbackHandle() {}; DeferredCallbackHandle(DeferredCallbackHandle&& h) { *this = std::move(h); @@ -76,7 +76,7 @@ namespace PAL_NS_BEGIN { DeferredCallbackHandle& operator=(DeferredCallbackHandle&& other) { std::lock_guard lock(m_mutex); - std::lock_guard lock2(other.m_mutex); + std::lock_guard otherLock(other.m_mutex); m_task = other.m_task; other.m_task = nullptr; m_taskDispatcher = other.m_taskDispatcher; @@ -84,12 +84,12 @@ namespace PAL_NS_BEGIN { return *this; } - bool Cancel(bool wait_for_cancel = false) + bool Cancel(uint64_t waitTime = 0) { std::lock_guard lock(m_mutex); if (m_task) { - bool result = (m_taskDispatcher != nullptr) && (m_taskDispatcher->Cancel(m_task, wait_for_cancel)); + bool result = (m_taskDispatcher != nullptr) && (m_taskDispatcher->Cancel(m_task, waitTime)); return result; } else { diff --git a/lib/pal/TaskDispatcher_CAPI.cpp b/lib/pal/TaskDispatcher_CAPI.cpp index 09ff8fa72..8aa8bdea7 100644 --- a/lib/pal/TaskDispatcher_CAPI.cpp +++ b/lib/pal/TaskDispatcher_CAPI.cpp @@ -126,7 +126,7 @@ namespace PAL_NS_BEGIN { } // TODO: currently shutdown wait on task cancellation is not implemented for C API Task Dispatcher - bool TaskDispatcher_CAPI::Cancel(Task* task, bool) + bool TaskDispatcher_CAPI::Cancel(Task* task, uint64_t) { std::string taskId; diff --git a/lib/pal/TaskDispatcher_CAPI.hpp b/lib/pal/TaskDispatcher_CAPI.hpp index c0bed50d5..66d22ddf7 100644 --- a/lib/pal/TaskDispatcher_CAPI.hpp +++ b/lib/pal/TaskDispatcher_CAPI.hpp @@ -12,7 +12,7 @@ namespace PAL_NS_BEGIN { TaskDispatcher_CAPI(task_dispatcher_queue_fn_t queueFn, task_dispatcher_cancel_fn_t cancelFn, task_dispatcher_join_fn_t joinFn); void Join() override; void Queue(MAT::Task* task) override; - bool Cancel(MAT::Task* task, bool wait_for_cancel = false) override; + bool Cancel(MAT::Task* task, uint64_t waitTime = 0) override; private: task_dispatcher_queue_fn_t m_queueFn; diff --git a/lib/pal/WorkerThread.cpp b/lib/pal/WorkerThread.cpp index 14a569786..2f3d4db31 100644 --- a/lib/pal/WorkerThread.cpp +++ b/lib/pal/WorkerThread.cpp @@ -7,14 +7,6 @@ /* Maximum scheduler interval for SDK is 1 hour required for clamping in case of monotonic clock drift */ #define MAX_FUTURE_DELTA_MS (60 * 60 * 1000) -// This macro allows to specify max upload task cancellation wait time at compile-time, -// addressing the case when a task that we are trying to cancel is currently running. -// Default value: 500ms - sufficient for upload scheduler/batcher task to finish. -// Alternate value: UINT64_MAX - for infinite wait until the task is completed. -#ifndef TASK_CANCEL_TIME_MS -#define TASK_CANCEL_TIME_MS 500 -#endif - namespace PAL_NS_BEGIN { class WorkerThreadShutdownItem : public Task @@ -125,7 +117,7 @@ namespace PAL_NS_BEGIN { // - TASK_COMPLETED - task found and ran to completion // - TASK_RUNNING - task is still running (insufficient waitTime) // - bool Cancel(MAT::Task* item, bool wait_for_cancel) override + bool Cancel(MAT::Task* item, uint64_t waitTime) override { LOCKGUARD(m_lock); if (item == nullptr) @@ -138,7 +130,7 @@ namespace PAL_NS_BEGIN { /* Can't recursively wait on completion of our own thread */ if (m_hThread.get_id() != std::this_thread::get_id()) { - if (wait_for_cancel && m_execution_mutex.try_lock_for(std::chrono::milliseconds(TASK_CANCEL_TIME_MS))) + if (waitTime > 0 && m_execution_mutex.try_lock_for(std::chrono::milliseconds(waitTime))) { m_itemInProgress = nullptr; m_execution_mutex.unlock(); @@ -249,9 +241,9 @@ namespace PAL_NS_BEGIN { self->m_itemInProgress = nullptr; } - if (item.get()) { + if (item) { item->Type = MAT::Task::Done; - item.reset(); + item = nullptr; } } } diff --git a/lib/system/TelemetrySystem.cpp b/lib/system/TelemetrySystem.cpp index cc9c5fd45..1def01a3e 100644 --- a/lib/system/TelemetrySystem.cpp +++ b/lib/system/TelemetrySystem.cpp @@ -81,8 +81,8 @@ namespace ARIASDK_NS_BEGIN { // cancel all pending and force-finish all uploads stopTimes[1] = GetUptimeMs(); - // TODO: should this still pause, since the TPM now has abort logic in addition to pause logic? - // it doesn't seem particularly useful + // TODO: Should this still pause, since the TPM now has abort logic in addition to pause logic? + // hcm.cancelAllRequests is also part of pause, so the logic is definitely redundant. Issue 387 onPause(); hcm.cancelAllRequests(); tpm.finishAllUploads(); diff --git a/lib/tpm/TransmissionPolicyManager.hpp b/lib/tpm/TransmissionPolicyManager.hpp index 9ea937138..d75274672 100644 --- a/lib/tpm/TransmissionPolicyManager.hpp +++ b/lib/tpm/TransmissionPolicyManager.hpp @@ -20,6 +20,14 @@ #include #include +// This macro allows to specify max upload task cancellation wait time at compile-time, +// addressing the case when a task that we are trying to cancel is currently running. +// Default value: 500ms - sufficient for upload scheduler/batcher task to finish. +// Alternate value: UINT64_MAX - for infinite wait until the task is completed. +#ifndef UPLOAD_TASK_CANCEL_TIME_MS +#define UPLOAD_TASK_CANCEL_TIME_MS 500 +#endif + namespace ARIASDK_NS_BEGIN { class TransmissionPolicyManager @@ -120,11 +128,12 @@ namespace ARIASDK_NS_BEGIN { /// bool cancelUploadTask() { - bool result = m_scheduledUpload.Cancel(/*wait_for_cancel*/ m_scheduledUploadAborted); + uint64_t cancelWaitTimeMs = (m_scheduledUploadAborted) ? UPLOAD_TASK_CANCEL_TIME_MS : 0; + bool result = m_scheduledUpload.Cancel(cancelWaitTimeMs); // TODO: There is a potential for upload tasks to not be canceled, especially if they aren't waited for. // We either need a stronger guarantee here (could impact SDK performance), or a mechanism to - // ensure those tasks are canceled when the log manager is destroyed. + // ensure those tasks are canceled when the log manager is destroyed. Issue 388 if (result) { m_isUploadScheduled.exchange(false); From e0b12b7683204c71f6d69c22400ec99a0a18718b Mon Sep 17 00:00:00 2001 From: Jason Bray Date: Mon, 18 May 2020 14:27:24 -0700 Subject: [PATCH 4/4] Clean up comments --- lib/pal/WorkerThread.cpp | 2 +- lib/tpm/TransmissionPolicyManager.cpp | 2 +- lib/tpm/TransmissionPolicyManager.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pal/WorkerThread.cpp b/lib/pal/WorkerThread.cpp index 2f3d4db31..435e61693 100644 --- a/lib/pal/WorkerThread.cpp +++ b/lib/pal/WorkerThread.cpp @@ -96,7 +96,7 @@ namespace PAL_NS_BEGIN { // // - acquire the m_lock to prevent a new task from getting scheduled. // This may block the scheduling of a new task in queue for up to - // TASK_CANCEL_TIME_MS in case if the task being canceled + // waitTime in case if the task being canceled // is the one being executed right now. // // - if currently executing task is the one we are trying to cancel, diff --git a/lib/tpm/TransmissionPolicyManager.cpp b/lib/tpm/TransmissionPolicyManager.cpp index 3e2771089..726dfb8b1 100644 --- a/lib/tpm/TransmissionPolicyManager.cpp +++ b/lib/tpm/TransmissionPolicyManager.cpp @@ -255,7 +255,7 @@ namespace ARIASDK_NS_BEGIN { // Called from finishAllUploads void TransmissionPolicyManager::handleFinishAllUploads() { - // TODO: This pause appears to server no practical purpose? + // TODO: This pause appears to server no practical purpose? Issue 387 pauseAllUploads(); allUploadsFinished(); // calls stats.onStop >> this->flushTaskDispatcher; } diff --git a/lib/tpm/TransmissionPolicyManager.hpp b/lib/tpm/TransmissionPolicyManager.hpp index d75274672..b5d36b5f4 100644 --- a/lib/tpm/TransmissionPolicyManager.hpp +++ b/lib/tpm/TransmissionPolicyManager.hpp @@ -25,7 +25,7 @@ // Default value: 500ms - sufficient for upload scheduler/batcher task to finish. // Alternate value: UINT64_MAX - for infinite wait until the task is completed. #ifndef UPLOAD_TASK_CANCEL_TIME_MS -#define UPLOAD_TASK_CANCEL_TIME_MS 500 +#define UPLOAD_TASK_CANCEL_TIME_MS 500 #endif namespace ARIASDK_NS_BEGIN {