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_BASE_MESSAGE_LOOP_H_ 6 #define LIBBRILLO_BRILLO_MESSAGE_LOOPS_BASE_MESSAGE_LOOP_H_ 7 8 // BaseMessageLoop is a brillo::MessageLoop implementation based on 9 // base::MessageLoopForIO. This allows to mix new code using 10 // brillo::MessageLoop and legacy code using base::MessageLoopForIO in the 11 // same thread and share a single main loop. This disadvantage of using this 12 // class is a less efficient implementation of CancelTask() for delayed tasks 13 // since base::MessageLoopForIO doesn't provide a way to remove the event. 14 15 #include <map> 16 #include <memory> 17 #include <string> 18 19 #include <base/files/file_descriptor_watcher_posix.h> 20 #include <base/location.h> 21 #include <base/memory/weak_ptr.h> 22 #include <base/message_loop/message_loop.h> 23 #include <base/message_loop/message_pump_for_io.h> 24 #include <base/time/time.h> 25 #include <gtest/gtest_prod.h> 26 27 #include <brillo/brillo_export.h> 28 #include <brillo/message_loops/message_loop.h> 29 30 namespace brillo { 31 32 class BRILLO_EXPORT BaseMessageLoop : public MessageLoop { 33 public: 34 // Construct a base::MessageLoopForIO message loop instance and use it as 35 // the default message loop for this thread. 36 BaseMessageLoop(); 37 38 // Construct a brillo::BaseMessageLoop using the passed base::MessageLoopForIO 39 // instance. 40 explicit BaseMessageLoop(base::MessageLoopForIO* base_loop); 41 ~BaseMessageLoop() override; 42 43 // MessageLoop overrides. 44 TaskId PostDelayedTask(const base::Location& from_here, 45 base::OnceClosure task, 46 base::TimeDelta delay) override; 47 using MessageLoop::PostDelayedTask; 48 bool CancelTask(TaskId task_id) override; 49 bool RunOnce(bool may_block) override; 50 void Run() override; 51 void BreakLoop() override; 52 53 // Returns a callback that will quit the current message loop. If the message 54 // loop is not running, an empty (null) callback is returned. 55 base::RepeatingClosure QuitClosure() const; 56 57 private: 58 FRIEND_TEST(BaseMessageLoopTest, ParseBinderMinor); 59 60 static const int kInvalidMinor; 61 static const int kUninitializedMinor; 62 63 // Parses the contents of the file /proc/misc passed in |file_contents| and 64 // returns the minor device number reported for binder. On error or if not 65 // found, returns kInvalidMinor. 66 static int ParseBinderMinor(const std::string& file_contents); 67 68 // Called by base::MessageLoopForIO when is time to call the callback 69 // scheduled with Post*Task() of id |task_id|, even if it was canceled. 70 void OnRanPostedTask(MessageLoop::TaskId task_id); 71 72 // Return a new unused task_id. 73 TaskId NextTaskId(); 74 75 // Returns binder minor device number. 76 unsigned int GetBinderMinor(); 77 78 struct DelayedTask { 79 base::Location location; 80 81 MessageLoop::TaskId task_id; 82 base::OnceClosure closure; 83 }; 84 85 // The base::MessageLoopForIO instance owned by this class, if any. This 86 // is declared first in this class so it is destroyed last. 87 std::unique_ptr<base::MessageLoopForIO> owned_base_loop_; 88 89 // Tasks blocked on a timeout. 90 std::map<MessageLoop::TaskId, DelayedTask> delayed_tasks_; 91 92 // Flag to mark that we should run the message loop only one iteration. 93 bool run_once_{false}; 94 95 // The last used TaskId. While base::MessageLoopForIO doesn't allow to cancel 96 // delayed tasks, we handle that functionality by not running the callback 97 // if it fires at a later point. 98 MessageLoop::TaskId last_id_{kTaskIdNull}; 99 100 // The pointer to the libchrome base::MessageLoopForIO we are wrapping with 101 // this interface. If the instance was created from this object, this will 102 // point to that instance. 103 base::MessageLoopForIO* base_loop_; 104 105 // FileDescriptorWatcher for |base_loop_|. This is used in AlarmTimer. 106 std::unique_ptr<base::FileDescriptorWatcher> watcher_; 107 108 // The RunLoop instance used to run the main loop from Run(). 109 base::RunLoop* base_run_loop_{nullptr}; 110 111 // The binder minor device number. Binder is a "misc" char device with a 112 // dynamically allocated minor number. When uninitialized, this value will 113 // be negative, otherwise, it will hold the minor part of the binder device 114 // number. This is populated by GetBinderMinor(). 115 int binder_minor_{kUninitializedMinor}; 116 117 // We use a WeakPtrFactory to schedule tasks with the base::MessageLoopForIO 118 // since we can't cancel the callbacks we have scheduled there once this 119 // instance is destroyed. 120 base::WeakPtrFactory<BaseMessageLoop> weak_ptr_factory_{this}; 121 DISALLOW_COPY_AND_ASSIGN(BaseMessageLoop); 122 }; 123 124 } // namespace brillo 125 126 #endif // LIBBRILLO_BRILLO_MESSAGE_LOOPS_BASE_MESSAGE_LOOP_H_ 127