1 /* 2 * Copyright 2020 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef RTC_BASE_TASK_UTILS_PENDING_TASK_SAFETY_FLAG_H_ 12 #define RTC_BASE_TASK_UTILS_PENDING_TASK_SAFETY_FLAG_H_ 13 14 #include "api/scoped_refptr.h" 15 #include "rtc_base/checks.h" 16 #include "rtc_base/ref_count.h" 17 #include "rtc_base/synchronization/sequence_checker.h" 18 19 namespace webrtc { 20 21 // Use this flag to drop pending tasks that have been posted to the "main" 22 // thread/TQ and end up running after the owning instance has been 23 // deleted. The owning instance signals deletion by calling SetNotAlive() from 24 // its destructor. 25 // 26 // When posting a task, post a copy (capture by-value in a lambda) of the flag 27 // instance and before performing the work, check the |alive()| state. Abort if 28 // alive() returns |false|: 29 // 30 // // Running outside of the main thread. 31 // my_task_queue_->PostTask(ToQueuedTask( 32 // [safety = pending_task_safety_flag_, this]() { 33 // // Now running on the main thread. 34 // if (!safety->alive()) 35 // return; 36 // MyMethod(); 37 // })); 38 // 39 // Or implicitly by letting ToQueuedTask do the checking: 40 // 41 // // Running outside of the main thread. 42 // my_task_queue_->PostTask(ToQueuedTask(pending_task_safety_flag_, 43 // [this]() { MyMethod(); })); 44 // 45 // Note that checking the state only works on the construction/destruction 46 // thread of the ReceiveStatisticsProxy instance. 47 class PendingTaskSafetyFlag : public rtc::RefCountInterface { 48 public: 49 static rtc::scoped_refptr<PendingTaskSafetyFlag> Create(); 50 51 ~PendingTaskSafetyFlag() = default; 52 53 void SetNotAlive(); 54 bool alive() const; 55 56 protected: 57 PendingTaskSafetyFlag() = default; 58 59 private: 60 bool alive_ = true; 61 SequenceChecker main_sequence_; 62 }; 63 64 // Makes using PendingTaskSafetyFlag very simple. Automatic PTSF creation 65 // and signalling of destruction when the ScopedTaskSafety instance goes out 66 // of scope. 67 // Should be used by the class that wants tasks dropped after destruction. 68 // Requirements are that the instance be constructed and destructed on 69 // the same thread as the potentially dropped tasks would be running on. 70 class ScopedTaskSafety { 71 public: 72 ScopedTaskSafety() = default; ~ScopedTaskSafety()73 ~ScopedTaskSafety() { flag_->SetNotAlive(); } 74 75 // Returns a new reference to the safety flag. flag()76 rtc::scoped_refptr<PendingTaskSafetyFlag> flag() const { return flag_; } 77 78 private: 79 rtc::scoped_refptr<PendingTaskSafetyFlag> flag_ = 80 PendingTaskSafetyFlag::Create(); 81 }; 82 83 } // namespace webrtc 84 85 #endif // RTC_BASE_TASK_UTILS_PENDING_TASK_SAFETY_FLAG_H_ 86