• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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