| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 The Chromium 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 BASE_THREAD_H_ | |
| 6 #define BASE_THREAD_H_ | |
| 7 #pragma once | |
| 8 | |
| 9 #include <string> | |
| 10 | |
| 11 #include "base/message_loop.h" | |
| 12 #include "base/message_loop_proxy.h" | |
| 13 #include "base/threading/platform_thread.h" | |
| 14 | |
| 15 namespace base { | |
| 16 | |
| 17 // A simple thread abstraction that establishes a MessageLoop on a new thread. | |
| 18 // The consumer uses the MessageLoop of the thread to cause code to execute on | |
| 19 // the thread. When this object is destroyed the thread is terminated. All | |
| 20 // pending tasks queued on the thread's message loop will run to completion | |
| 21 // before the thread is terminated. | |
| 22 // | |
| 23 // After the thread is stopped, the destruction sequence is: | |
| 24 // | |
| 25 // (1) Thread::CleanUp() | |
| 26 // (2) MessageLoop::~MessageLoop | |
| 27 // (3.b) MessageLoop::DestructionObserver::WillDestroyCurrentMessageLoop | |
| 28 // (4) Thread::CleanUpAfterMessageLoopDestruction() | |
| 29 class Thread : PlatformThread::Delegate { | |
| 30 public: | |
| 31 struct Options { | |
| 32 // Specifies the type of message loop that will be allocated on the thread. | |
| 33 MessageLoop::Type message_loop_type; | |
| 34 | |
| 35 // Specifies the maximum stack size that the thread is allowed to use. | |
| 36 // This does not necessarily correspond to the thread's initial stack size. | |
| 37 // A value of 0 indicates that the default maximum should be used. | |
| 38 size_t stack_size; | |
| 39 | |
| 40 Options() : message_loop_type(MessageLoop::TYPE_DEFAULT), stack_size(0) {} | |
| 41 Options(MessageLoop::Type type, size_t size) | |
| 42 : message_loop_type(type), stack_size(size) {} | |
| 43 }; | |
| 44 | |
| 45 // Constructor. | |
| 46 // name is a display string to identify the thread. | |
| 47 explicit Thread(const char* name); | |
| 48 | |
| 49 // Destroys the thread, stopping it if necessary. | |
| 50 // | |
| 51 // NOTE: If you are subclassing from Thread, and you wish for your CleanUp | |
| 52 // method to be called, then you need to call Stop() from your destructor. | |
| 53 // | |
| 54 virtual ~Thread(); | |
| 55 | |
| 56 // Starts the thread. Returns true if the thread was successfully started; | |
| 57 // otherwise, returns false. Upon successful return, the message_loop() | |
| 58 // getter will return non-null. | |
| 59 // | |
| 60 // Note: This function can't be called on Windows with the loader lock held; | |
| 61 // i.e. during a DllMain, global object construction or destruction, atexit() | |
| 62 // callback. | |
| 63 bool Start(); | |
| 64 | |
| 65 // Starts the thread. Behaves exactly like Start in addition to allow to | |
| 66 // override the default options. | |
| 67 // | |
| 68 // Note: This function can't be called on Windows with the loader lock held; | |
| 69 // i.e. during a DllMain, global object construction or destruction, atexit() | |
| 70 // callback. | |
| 71 bool StartWithOptions(const Options& options); | |
| 72 | |
| 73 // Signals the thread to exit and returns once the thread has exited. After | |
| 74 // this method returns, the Thread object is completely reset and may be used | |
| 75 // as if it were newly constructed (i.e., Start may be called again). | |
| 76 // | |
| 77 // Stop may be called multiple times and is simply ignored if the thread is | |
| 78 // already stopped. | |
| 79 // | |
| 80 // NOTE: This method is optional. It is not strictly necessary to call this | |
| 81 // method as the Thread's destructor will take care of stopping the thread if | |
| 82 // necessary. | |
| 83 // | |
| 84 void Stop(); | |
| 85 | |
| 86 // Signals the thread to exit in the near future. | |
| 87 // | |
| 88 // WARNING: This function is not meant to be commonly used. Use at your own | |
| 89 // risk. Calling this function will cause message_loop() to become invalid in | |
| 90 // the near future. This function was created to workaround a specific | |
| 91 // deadlock on Windows with printer worker thread. In any other case, Stop() | |
| 92 // should be used. | |
| 93 // | |
| 94 // StopSoon should not be called multiple times as it is risky to do so. It | |
| 95 // could cause a timing issue in message_loop() access. Call Stop() to reset | |
| 96 // the thread object once it is known that the thread has quit. | |
| 97 void StopSoon(); | |
| 98 | |
| 99 // Returns the message loop for this thread. Use the MessageLoop's | |
| 100 // PostTask methods to execute code on the thread. This only returns | |
| 101 // non-null after a successful call to Start. After Stop has been called, | |
| 102 // this will return NULL. | |
| 103 // | |
| 104 // NOTE: You must not call this MessageLoop's Quit method directly. Use | |
| 105 // the Thread's Stop method instead. | |
| 106 // | |
| 107 MessageLoop* message_loop() const { return message_loop_; } | |
| 108 | |
| 109 // Returns a MessageLoopProxy for this thread. Use the MessageLoopProxy's | |
| 110 // PostTask methods to execute code on the thread. This only returns | |
| 111 // non-NULL after a successful call to Start. After Stop has been called, | |
| 112 // this will return NULL. Callers can hold on to this even after the thread | |
| 113 // is gone. | |
| 114 // TODO(sanjeevr): Look into merging MessageLoop and MessageLoopProxy. | |
| 115 scoped_refptr<MessageLoopProxy> message_loop_proxy() { | |
| 116 return message_loop_proxy_; | |
| 117 } | |
| 118 | |
| 119 // Set the name of this thread (for display in debugger too). | |
| 120 const std::string &thread_name() { return name_; } | |
| 121 | |
| 122 // The native thread handle. | |
| 123 PlatformThreadHandle thread_handle() { return thread_; } | |
| 124 | |
| 125 // The thread ID. | |
| 126 PlatformThreadId thread_id() const { return thread_id_; } | |
| 127 | |
| 128 // Returns true if the thread has been started, and not yet stopped. | |
| 129 // When a thread is running, |thread_id_| is a valid id. | |
| 130 bool IsRunning() const { return thread_id_ != kInvalidThreadId; } | |
| 131 | |
| 132 protected: | |
| 133 // Called just prior to starting the message loop | |
| 134 virtual void Init() {} | |
| 135 | |
| 136 // Called to start the message loop | |
| 137 virtual void Run(MessageLoop* message_loop); | |
| 138 | |
| 139 // Called just after the message loop ends | |
| 140 virtual void CleanUp() {} | |
| 141 | |
| 142 // Called after the message loop has been deleted. In general clients | |
| 143 // should prefer to use CleanUp(). This method is used when code needs to | |
| 144 // be run after all of the MessageLoop::DestructionObservers have completed. | |
| 145 virtual void CleanUpAfterMessageLoopDestruction() {} | |
| 146 | |
| 147 static void SetThreadWasQuitProperly(bool flag); | |
| 148 static bool GetThreadWasQuitProperly(); | |
| 149 | |
| 150 void set_message_loop(MessageLoop* message_loop) { | |
| 151 message_loop_ = message_loop; | |
| 152 } | |
| 153 | |
| 154 private: | |
| 155 // PlatformThread::Delegate methods: | |
| 156 virtual void ThreadMain(); | |
| 157 | |
| 158 bool thread_was_started() const { return started_; } | |
| 159 | |
| 160 // Whether we successfully started the thread. | |
| 161 bool started_; | |
| 162 | |
| 163 // If true, we're in the middle of stopping, and shouldn't access | |
| 164 // |message_loop_|. It may non-NULL and invalid. | |
| 165 bool stopping_; | |
| 166 | |
| 167 // Used to pass data to ThreadMain. | |
| 168 struct StartupData; | |
| 169 StartupData* startup_data_; | |
| 170 | |
| 171 // The thread's handle. | |
| 172 PlatformThreadHandle thread_; | |
| 173 | |
| 174 // The thread's message loop. Valid only while the thread is alive. Set | |
| 175 // by the created thread. | |
| 176 MessageLoop* message_loop_; | |
| 177 | |
| 178 // A MessageLoopProxy implementation that targets this thread. This can | |
| 179 // outlive the thread. | |
| 180 scoped_refptr<MessageLoopProxy> message_loop_proxy_; | |
| 181 | |
| 182 // Our thread's ID. | |
| 183 PlatformThreadId thread_id_; | |
| 184 | |
| 185 // The name of the thread. Used for debugging purposes. | |
| 186 std::string name_; | |
| 187 | |
| 188 friend class ThreadQuitTask; | |
| 189 | |
| 190 DISALLOW_COPY_AND_ASSIGN(Thread); | |
| 191 }; | |
| 192 | |
| 193 } // namespace base | |
| 194 | |
| 195 #endif // BASE_THREAD_H_ | |
| OLD | NEW |