From 25e735239c971a71c2feab65f19793c4edb60db9 Mon Sep 17 00:00:00 2001 From: Tomas Gunnarsson Date: Mon, 19 Apr 2021 10:14:10 +0200 Subject: [PATCH] Add support for setting the initial state to the pending task flag. This is useful in cases where a class needs to use a flag for controlling operations on a task queue but initialization needs to complete before tasks are allowed to run. Example CL that needs this (for MediaChannel): https://webrtc-review.googlesource.com/c/src/+/215405 Bug: webrtc:11993 Change-Id: Icd7dd16ee7447647266d6de000a4db3fd0447618 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/215583 Commit-Queue: Tommi Reviewed-by: Niels Moller Cr-Commit-Position: refs/heads/master@{#33773} --- .../task_utils/pending_task_safety_flag.cc | 13 ++++++++++-- .../task_utils/pending_task_safety_flag.h | 7 ++++++- .../pending_task_safety_flag_unittest.cc | 21 ++++++++++++++++++- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/rtc_base/task_utils/pending_task_safety_flag.cc b/rtc_base/task_utils/pending_task_safety_flag.cc index 595457dc0e..b83d714916 100644 --- a/rtc_base/task_utils/pending_task_safety_flag.cc +++ b/rtc_base/task_utils/pending_task_safety_flag.cc @@ -16,12 +16,21 @@ namespace webrtc { // static rtc::scoped_refptr PendingTaskSafetyFlag::Create() { - return new rtc::RefCountedObject(); + return new rtc::RefCountedObject(true); } rtc::scoped_refptr PendingTaskSafetyFlag::CreateDetached() { - auto safety_flag = Create(); + rtc::scoped_refptr safety_flag( + new rtc::RefCountedObject(true)); + safety_flag->main_sequence_.Detach(); + return safety_flag; +} + +rtc::scoped_refptr +PendingTaskSafetyFlag::CreateDetachedInactive() { + rtc::scoped_refptr safety_flag( + new rtc::RefCountedObject(false)); safety_flag->main_sequence_.Detach(); return safety_flag; } diff --git a/rtc_base/task_utils/pending_task_safety_flag.h b/rtc_base/task_utils/pending_task_safety_flag.h index abfce26ad8..4864b5de3b 100644 --- a/rtc_base/task_utils/pending_task_safety_flag.h +++ b/rtc_base/task_utils/pending_task_safety_flag.h @@ -58,10 +58,15 @@ namespace webrtc { class PendingTaskSafetyFlag : public rtc::RefCountInterface { public: static rtc::scoped_refptr Create(); + // Creates a flag, but with its SequenceChecker initially detached. Hence, it // may be created on a different thread than the flag will be used on. static rtc::scoped_refptr CreateDetached(); + // Same as `CreateDetached()` except the initial state of the returned flag + // will be `!alive()`. + static rtc::scoped_refptr CreateDetachedInactive(); + ~PendingTaskSafetyFlag() = default; void SetNotAlive(); @@ -84,7 +89,7 @@ class PendingTaskSafetyFlag : public rtc::RefCountInterface { bool alive() const; protected: - PendingTaskSafetyFlag() = default; + explicit PendingTaskSafetyFlag(bool alive) : alive_(alive) {} private: bool alive_ = true; diff --git a/rtc_base/task_utils/pending_task_safety_flag_unittest.cc b/rtc_base/task_utils/pending_task_safety_flag_unittest.cc index 6df2fe2ffb..07bbea296e 100644 --- a/rtc_base/task_utils/pending_task_safety_flag_unittest.cc +++ b/rtc_base/task_utils/pending_task_safety_flag_unittest.cc @@ -156,8 +156,27 @@ TEST(PendingTaskSafetyFlagTest, PendingTaskDropped) { blocker.Set(); // Run an empty task on tq1 to flush all the queued tasks. - tq1.SendTask([]() {}, RTC_FROM_HERE); + tq1.WaitForPreviouslyPostedTasks(); ASSERT_FALSE(owner); EXPECT_FALSE(stuff_done); } + +TEST(PendingTaskSafetyFlagTest, PendingTaskNotAliveInitialized) { + TaskQueueForTest tq("PendingTaskNotAliveInitialized"); + + // Create a new flag that initially not `alive`. + auto flag = PendingTaskSafetyFlag::CreateDetachedInactive(); + tq.SendTask([&flag]() { EXPECT_FALSE(flag->alive()); }, RTC_FROM_HERE); + + bool task_1_ran = false; + bool task_2_ran = false; + tq.PostTask(ToQueuedTask(flag, [&task_1_ran]() { task_1_ran = true; })); + tq.PostTask([&flag]() { flag->SetAlive(); }); + tq.PostTask(ToQueuedTask(flag, [&task_2_ran]() { task_2_ran = true; })); + + tq.WaitForPreviouslyPostedTasks(); + EXPECT_FALSE(task_1_ran); + EXPECT_TRUE(task_2_ran); +} + } // namespace webrtc