xref: /aosp_15_r20/external/cronet/base/task/deferred_sequenced_task_runner.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_TASK_DEFERRED_SEQUENCED_TASK_RUNNER_H_
6 #define BASE_TASK_DEFERRED_SEQUENCED_TASK_RUNNER_H_
7 
8 #include <vector>
9 
10 #include "base/base_export.h"
11 #include "base/compiler_specific.h"
12 #include "base/functional/callback.h"
13 #include "base/synchronization/lock.h"
14 #include "base/task/sequenced_task_runner.h"
15 #include "base/threading/platform_thread.h"
16 #include "base/time/time.h"
17 
18 namespace base {
19 
20 // A DeferredSequencedTaskRunner is a subclass of SequencedTaskRunner that
21 // queues up all requests until the first call to Start() is issued.
22 // DeferredSequencedTaskRunner may be created in two ways:
23 // . with an explicit SequencedTaskRunner that the events are flushed to
24 // . without a SequencedTaskRunner. In this configuration the
25 //   SequencedTaskRunner is supplied in StartWithTaskRunner().
26 class BASE_EXPORT DeferredSequencedTaskRunner : public SequencedTaskRunner {
27  public:
28   explicit DeferredSequencedTaskRunner(
29       scoped_refptr<SequencedTaskRunner> target_runner);
30 
31   // Use this constructor when you don't have the target SequencedTaskRunner.
32   // When using this call StartWithTaskRunner().
33   DeferredSequencedTaskRunner();
34   DeferredSequencedTaskRunner(const DeferredSequencedTaskRunner&) = delete;
35   DeferredSequencedTaskRunner& operator=(const DeferredSequencedTaskRunner&) =
36       delete;
37 
38   // TaskRunner implementation
39   bool PostDelayedTask(const Location& from_here,
40                        OnceClosure task,
41                        TimeDelta delay) override;
42 
43   // SequencedTaskRunner implementation
44   bool RunsTasksInCurrentSequence() const override;
45   bool PostNonNestableDelayedTask(const Location& from_here,
46                                   OnceClosure task,
47                                   TimeDelta delay) override;
48 
49   // Start the execution - posts all queued tasks to the target executor. The
50   // deferred tasks are posted with their initial delay, meaning that the task
51   // execution delay is actually measured from Start.
52   // Fails when called a second time.
53   void Start();
54 
55   // Same as Start(), but must be used with the no-arg constructor.
56   void StartWithTaskRunner(
57       scoped_refptr<SequencedTaskRunner> target_task_runner);
58 
59   // Returns true if task execution has been started.
60   bool Started() const;
61 
62  private:
63   struct DeferredTask  {
64     DeferredTask();
65     DeferredTask(DeferredTask&& other);
66     ~DeferredTask();
67     DeferredTask& operator=(DeferredTask&& other);
68 
69     Location posted_from;
70     OnceClosure task;
71     // The delay this task was initially posted with.
72     TimeDelta delay;
73     bool is_non_nestable;
74   };
75 
76   ~DeferredSequencedTaskRunner() override;
77 
78   // Both variants of Start() call into this.
79   void StartImpl();
80 
81   // Creates a |Task| object and adds it to |deferred_tasks_queue_|.
82   void QueueDeferredTask(const Location& from_here,
83                          OnceClosure task,
84                          TimeDelta delay,
85                          bool is_non_nestable);
86 
87   mutable Lock lock_;
88 
89   const PlatformThreadId created_thread_id_;
90 
91   // An atomic pointer that allows to call task_runner methods without lock.
92   // It's possible because the pointer starts as null, is set to a non-null
93   // value only once, and is never changed again.
94   // This is used to implement a lock-free RunsTasksInCurrentSequence method.
95   std::atomic<SequencedTaskRunner*> task_runner_atomic_ptr_{nullptr};
96   bool started_ GUARDED_BY(lock_) = false;
97   scoped_refptr<SequencedTaskRunner> target_task_runner_ GUARDED_BY(lock_);
98   std::vector<DeferredTask> deferred_tasks_queue_ GUARDED_BY(lock_);
99 };
100 
101 }  // namespace base
102 
103 #endif  // BASE_TASK_DEFERRED_SEQUENCED_TASK_RUNNER_H_
104