xref: /aosp_15_r20/external/libbrillo/brillo/message_loops/message_loop.h (revision 1a96fba65179ea7d3f56207137718607415c5953)
1*1a96fba6SXin Li // Copyright 2015 The Chromium OS Authors. All rights reserved.
2*1a96fba6SXin Li // Use of this source code is governed by a BSD-style license that can be
3*1a96fba6SXin Li // found in the LICENSE file.
4*1a96fba6SXin Li 
5*1a96fba6SXin Li #ifndef LIBBRILLO_BRILLO_MESSAGE_LOOPS_MESSAGE_LOOP_H_
6*1a96fba6SXin Li #define LIBBRILLO_BRILLO_MESSAGE_LOOPS_MESSAGE_LOOP_H_
7*1a96fba6SXin Li 
8*1a96fba6SXin Li #include <string>
9*1a96fba6SXin Li #include <utility>
10*1a96fba6SXin Li 
11*1a96fba6SXin Li #include <base/callback.h>
12*1a96fba6SXin Li #include <base/location.h>
13*1a96fba6SXin Li #include <base/time/time.h>
14*1a96fba6SXin Li #include <brillo/brillo_export.h>
15*1a96fba6SXin Li 
16*1a96fba6SXin Li namespace brillo {
17*1a96fba6SXin Li 
18*1a96fba6SXin Li class BRILLO_EXPORT MessageLoop {
19*1a96fba6SXin Li  public:
20*1a96fba6SXin Li   virtual ~MessageLoop();
21*1a96fba6SXin Li 
22*1a96fba6SXin Li   // A unique task identifier used to refer to scheduled callbacks.
23*1a96fba6SXin Li   using TaskId = uint64_t;
24*1a96fba6SXin Li 
25*1a96fba6SXin Li   // The kNullEventId is reserved for an invalid task and will never be used
26*1a96fba6SXin Li   // to refer to a real task.
27*1a96fba6SXin Li   static const TaskId kTaskIdNull;
28*1a96fba6SXin Li 
29*1a96fba6SXin Li   // Return the MessageLoop for the current thread. It is a fatal error to
30*1a96fba6SXin Li   // request the current MessageLoop if SetAsCurrent() was not called on the
31*1a96fba6SXin Li   // current thread. If you really need to, use ThreadHasCurrent() to check if
32*1a96fba6SXin Li   // there is a current thread.
33*1a96fba6SXin Li   static MessageLoop* current();
34*1a96fba6SXin Li 
35*1a96fba6SXin Li   // Return whether there is a MessageLoop in the current thread.
36*1a96fba6SXin Li   static bool ThreadHasCurrent();
37*1a96fba6SXin Li 
38*1a96fba6SXin Li   // Set this message loop as the current thread main loop. Only one message
39*1a96fba6SXin Li   // loop can be set at a time. Use ReleaseFromCurrent() to release it.
40*1a96fba6SXin Li   void SetAsCurrent();
41*1a96fba6SXin Li 
42*1a96fba6SXin Li   // Release this instance from the current thread. This instance must have
43*1a96fba6SXin Li   // been previously set with SetAsCurrent().
44*1a96fba6SXin Li   void ReleaseFromCurrent();
45*1a96fba6SXin Li 
46*1a96fba6SXin Li   // Schedule a Closure |task| to be executed after a |delay|. Returns a task
47*1a96fba6SXin Li   // identifier for the scheduled task that can be used to cancel the task
48*1a96fba6SXin Li   // before it is fired by passing it to CancelTask().
49*1a96fba6SXin Li   // In case of an error scheduling the task, the kTaskIdNull is returned.
50*1a96fba6SXin Li   // Note that once the call is executed or canceled, the TaskId could be reused
51*1a96fba6SXin Li   // at a later point.
52*1a96fba6SXin Li   // This methond can only be called from the same thread running the main loop.
53*1a96fba6SXin Li   virtual TaskId PostDelayedTask(const base::Location& from_here,
54*1a96fba6SXin Li                                  base::OnceClosure task,
55*1a96fba6SXin Li                                  base::TimeDelta delay) = 0;
56*1a96fba6SXin Li   // Variant without the Location for easier usage.
PostDelayedTask(base::OnceClosure task,base::TimeDelta delay)57*1a96fba6SXin Li   TaskId PostDelayedTask(base::OnceClosure task, base::TimeDelta delay) {
58*1a96fba6SXin Li     return PostDelayedTask(base::Location(), std::move(task), delay);
59*1a96fba6SXin Li   }
60*1a96fba6SXin Li 
61*1a96fba6SXin Li   // A convenience method to schedule a call with no delay.
62*1a96fba6SXin Li   // This methond can only be called from the same thread running the main loop.
PostTask(base::OnceClosure task)63*1a96fba6SXin Li   TaskId PostTask(base::OnceClosure task) {
64*1a96fba6SXin Li     return PostDelayedTask(std::move(task), base::TimeDelta());
65*1a96fba6SXin Li   }
PostTask(const base::Location & from_here,base::OnceClosure task)66*1a96fba6SXin Li   TaskId PostTask(const base::Location& from_here, base::OnceClosure task) {
67*1a96fba6SXin Li     return PostDelayedTask(from_here, std::move(task), base::TimeDelta());
68*1a96fba6SXin Li   }
69*1a96fba6SXin Li 
70*1a96fba6SXin Li   // Cancel a scheduled task. Returns whether the task was canceled. For
71*1a96fba6SXin Li   // example, if the callback was already executed (or is being executed) or was
72*1a96fba6SXin Li   // already canceled this method will fail. Note that the TaskId can be reused
73*1a96fba6SXin Li   // after it was executed or cancelled.
74*1a96fba6SXin Li   virtual bool CancelTask(TaskId task_id) = 0;
75*1a96fba6SXin Li 
76*1a96fba6SXin Li   // ---------------------------------------------------------------------------
77*1a96fba6SXin Li   // Methods used to run and stop the message loop.
78*1a96fba6SXin Li 
79*1a96fba6SXin Li   // Run one iteration of the message loop, dispatching up to one task. The
80*1a96fba6SXin Li   // |may_block| tells whether this method is allowed to block waiting for a
81*1a96fba6SXin Li   // task to be ready to run. Returns whether it ran a task. Note that even
82*1a96fba6SXin Li   // if |may_block| is true, this method can return false immediately if there
83*1a96fba6SXin Li   // are no more tasks registered.
84*1a96fba6SXin Li   virtual bool RunOnce(bool may_block) = 0;
85*1a96fba6SXin Li 
86*1a96fba6SXin Li   // Run the main loop until there are no more registered tasks.
87*1a96fba6SXin Li   virtual void Run();
88*1a96fba6SXin Li 
89*1a96fba6SXin Li   // Quit the running main loop immediately. This method will make the current
90*1a96fba6SXin Li   // running Run() method to return right after the current task returns back
91*1a96fba6SXin Li   // to the message loop without processing any other task.
92*1a96fba6SXin Li   virtual void BreakLoop();
93*1a96fba6SXin Li 
94*1a96fba6SXin Li  protected:
95*1a96fba6SXin Li   MessageLoop() = default;
96*1a96fba6SXin Li 
97*1a96fba6SXin Li  private:
98*1a96fba6SXin Li   // Tells whether Run() should quit the message loop in the default
99*1a96fba6SXin Li   // implementation.
100*1a96fba6SXin Li   bool should_exit_ = false;
101*1a96fba6SXin Li 
102*1a96fba6SXin Li   DISALLOW_COPY_AND_ASSIGN(MessageLoop);
103*1a96fba6SXin Li };
104*1a96fba6SXin Li 
105*1a96fba6SXin Li }  // namespace brillo
106*1a96fba6SXin Li 
107*1a96fba6SXin Li #endif  // LIBBRILLO_BRILLO_MESSAGE_LOOPS_MESSAGE_LOOP_H_
108