Index: webrtc/rtc_base/task_queue_gcd.cc |
diff --git a/webrtc/rtc_base/task_queue_gcd.cc b/webrtc/rtc_base/task_queue_gcd.cc |
index 45c5f09ebfc1f81a1ec18206bcd0c953f98579fb..fd221969407ada3aae9cc5e5768ebeb9f86bb0b0 100644 |
--- a/webrtc/rtc_base/task_queue_gcd.cc |
+++ b/webrtc/rtc_base/task_queue_gcd.cc |
@@ -16,6 +16,8 @@ |
#include <string.h> |
+#include <atomic> |
+ |
#include "webrtc/rtc_base/checks.h" |
#include "webrtc/rtc_base/logging.h" |
#include "webrtc/rtc_base/task_queue_posix.h" |
@@ -53,8 +55,12 @@ struct TaskQueue::QueueContext { |
delete qc; |
} |
+ // By posting this function synchronously, one can wait until the queue |
+ // has been emptied. |
+ static void VoidFunction(void* context) {} // TODO(eladalon): !!! Rename? |
+ |
TaskQueue* const queue; |
- bool is_active; |
+ std::atomic<bool> is_active; |
}; |
struct TaskQueue::TaskContext { |
@@ -134,9 +140,17 @@ TaskQueue::~TaskQueue() { |
// queue have been released, the queue will be deallocated by the system. |
// This is why we check the context before running tasks. |
- // Use dispatch_sync to set the context to null to guarantee that there's not |
- // a race between checking the context and using it from a task. |
- dispatch_sync_f(queue_, context_, &QueueContext::SetNotActive); |
+ // Prevent pending tasks from running. |
+ QueueContext::SetNotActive(context_); |
+ |
+ // Wait until all previous tasks' destructors have been invoked. |
+ dispatch_sync_f(queue_, context_, &QueueContext::VoidFunction); |
+ |
+ // TODO(eladalon): !!! It would be good to also RTC_DCHECK here to make sure |
+ // no additional tasks were posted in the meantime. Posting tasks during |
+ // tear-down would be an error of poster. Additionally, the tasks' destructors |
+ // would not get called. |
+ |
dispatch_release(queue_); |
} |