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