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