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..3c1457f9b1acb62ccfff0cb8d90ec50a3d65119b 100644 |
--- a/webrtc/rtc_base/task_queue_gcd.cc |
+++ b/webrtc/rtc_base/task_queue_gcd.cc |
@@ -53,6 +53,10 @@ struct TaskQueue::QueueContext { |
delete qc; |
} |
+ // By posting this function synchronously, one can wait until the queue |
+ // has been emptied. |
+ static void VoidFunction(void* context) {} |
+ |
TaskQueue* const queue; |
bool is_active; |
}; |
@@ -134,9 +138,15 @@ 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); |
+ // Toggle the context to not-active while the task-queue is suspended, to |
+ // avoid a race. |
+ dispatch_suspend(queue_); |
nisse-webrtc
2017/08/30 09:20:35
The interesting question is what dispatch_suspend
eladalon
2017/08/30 09:41:27
My thinking was that it would be helpful in either
eladalon
2017/08/30 10:21:42
Okay, looks like it prevents the next task from la
|
+ QueueContext::SetNotActive(context_); |
+ dispatch_resume(queue_); |
+ |
+ // Wait until all previous tasks' destructors have been invoked. |
+ dispatch_sync_f(queue_, context_, &QueueContext::VoidFunction); |
+ |
eladalon
2017/08/30 09:19:36
Might not hurt to add an RTC_DCHECK here to make s
|
dispatch_release(queue_); |
} |