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 <tommi@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33773}
This commit is contained in:
Tomas Gunnarsson 2021-04-19 10:14:10 +02:00 committed by Commit Bot
parent e984aa2e58
commit 25e735239c
3 changed files with 37 additions and 4 deletions

View File

@ -16,12 +16,21 @@ namespace webrtc {
// static // static
rtc::scoped_refptr<PendingTaskSafetyFlag> PendingTaskSafetyFlag::Create() { rtc::scoped_refptr<PendingTaskSafetyFlag> PendingTaskSafetyFlag::Create() {
return new rtc::RefCountedObject<PendingTaskSafetyFlag>(); return new rtc::RefCountedObject<PendingTaskSafetyFlag>(true);
} }
rtc::scoped_refptr<PendingTaskSafetyFlag> rtc::scoped_refptr<PendingTaskSafetyFlag>
PendingTaskSafetyFlag::CreateDetached() { PendingTaskSafetyFlag::CreateDetached() {
auto safety_flag = Create(); rtc::scoped_refptr<PendingTaskSafetyFlag> safety_flag(
new rtc::RefCountedObject<PendingTaskSafetyFlag>(true));
safety_flag->main_sequence_.Detach();
return safety_flag;
}
rtc::scoped_refptr<PendingTaskSafetyFlag>
PendingTaskSafetyFlag::CreateDetachedInactive() {
rtc::scoped_refptr<PendingTaskSafetyFlag> safety_flag(
new rtc::RefCountedObject<PendingTaskSafetyFlag>(false));
safety_flag->main_sequence_.Detach(); safety_flag->main_sequence_.Detach();
return safety_flag; return safety_flag;
} }

View File

@ -58,10 +58,15 @@ namespace webrtc {
class PendingTaskSafetyFlag : public rtc::RefCountInterface { class PendingTaskSafetyFlag : public rtc::RefCountInterface {
public: public:
static rtc::scoped_refptr<PendingTaskSafetyFlag> Create(); static rtc::scoped_refptr<PendingTaskSafetyFlag> Create();
// Creates a flag, but with its SequenceChecker initially detached. Hence, it // 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. // may be created on a different thread than the flag will be used on.
static rtc::scoped_refptr<PendingTaskSafetyFlag> CreateDetached(); static rtc::scoped_refptr<PendingTaskSafetyFlag> CreateDetached();
// Same as `CreateDetached()` except the initial state of the returned flag
// will be `!alive()`.
static rtc::scoped_refptr<PendingTaskSafetyFlag> CreateDetachedInactive();
~PendingTaskSafetyFlag() = default; ~PendingTaskSafetyFlag() = default;
void SetNotAlive(); void SetNotAlive();
@ -84,7 +89,7 @@ class PendingTaskSafetyFlag : public rtc::RefCountInterface {
bool alive() const; bool alive() const;
protected: protected:
PendingTaskSafetyFlag() = default; explicit PendingTaskSafetyFlag(bool alive) : alive_(alive) {}
private: private:
bool alive_ = true; bool alive_ = true;

View File

@ -156,8 +156,27 @@ TEST(PendingTaskSafetyFlagTest, PendingTaskDropped) {
blocker.Set(); blocker.Set();
// Run an empty task on tq1 to flush all the queued tasks. // Run an empty task on tq1 to flush all the queued tasks.
tq1.SendTask([]() {}, RTC_FROM_HERE); tq1.WaitForPreviouslyPostedTasks();
ASSERT_FALSE(owner); ASSERT_FALSE(owner);
EXPECT_FALSE(stuff_done); 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 } // namespace webrtc