1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Use of this source code is governed by a BSD-style license that can be 3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// found in the LICENSE file. 4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#ifndef BASE_THREADING_THREAD_H_ 6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#define BASE_THREADING_THREAD_H_ 7b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 8cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include <stddef.h> 9cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko 10b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <string> 11b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 12b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/base_export.h" 13b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/callback.h" 14cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/macros.h" 15b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/memory/scoped_ptr.h" 16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/message_loop/message_loop.h" 17b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/message_loop/timer_slack.h" 18b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/single_thread_task_runner.h" 19b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/synchronization/lock.h" 20cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/synchronization/waitable_event.h" 21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/threading/platform_thread.h" 22cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "build/build_config.h" 23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace base { 25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass MessagePump; 27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// A simple thread abstraction that establishes a MessageLoop on a new thread. 29b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// The consumer uses the MessageLoop of the thread to cause code to execute on 30b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// the thread. When this object is destroyed the thread is terminated. All 31b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// pending tasks queued on the thread's message loop will run to completion 32b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// before the thread is terminated. 33b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// WARNING! SUBCLASSES MUST CALL Stop() IN THEIR DESTRUCTORS! See ~Thread(). 35b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// After the thread is stopped, the destruction sequence is: 37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 38b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// (1) Thread::CleanUp() 39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// (2) MessageLoop::~MessageLoop 40b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// (3.b) MessageLoop::DestructionObserver::WillDestroyCurrentMessageLoop 41b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass BASE_EXPORT Thread : PlatformThread::Delegate { 42b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat public: 43b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat struct BASE_EXPORT Options { 44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat typedef Callback<scoped_ptr<MessagePump>()> MessagePumpFactory; 45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 46b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Options(); 47b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Options(MessageLoop::Type type, size_t size); 48b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ~Options(); 49b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 50b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Specifies the type of message loop that will be allocated on the thread. 51b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // This is ignored if message_pump_factory.is_null() is false. 52b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat MessageLoop::Type message_loop_type; 53b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 54b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Specifies timer slack for thread message loop. 55b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat TimerSlack timer_slack; 56b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 57b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Used to create the MessagePump for the MessageLoop. The callback is Run() 58b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // on the thread. If message_pump_factory.is_null(), then a MessagePump 59b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // appropriate for |message_loop_type| is created. Setting this forces the 60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // MessageLoop::Type to TYPE_CUSTOM. 61b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat MessagePumpFactory message_pump_factory; 62b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 63b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Specifies the maximum stack size that the thread is allowed to use. 64b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // This does not necessarily correspond to the thread's initial stack size. 65b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // A value of 0 indicates that the default maximum should be used. 66b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t stack_size; 67b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 68b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Specifies the initial thread priority. 69b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ThreadPriority priority; 70b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat }; 71b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 72b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Constructor. 73b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // name is a display string to identify the thread. 74b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat explicit Thread(const std::string& name); 75b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 76b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Destroys the thread, stopping it if necessary. 77b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // 78b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // NOTE: ALL SUBCLASSES OF Thread MUST CALL Stop() IN THEIR DESTRUCTORS (or 79b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // guarantee Stop() is explicitly called before the subclass is destroyed). 80b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // This is required to avoid a data race between the destructor modifying the 81b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // vtable, and the thread's ThreadMain calling the virtual method Run(). It 82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // also ensures that the CleanUp() virtual method is called on the subclass 83b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // before it is destructed. 84b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ~Thread() override; 85b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if defined(OS_WIN) 87b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Causes the thread to initialize COM. This must be called before calling 88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Start() or StartWithOptions(). If |use_mta| is false, the thread is also 89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // started with a TYPE_UI message loop. It is an error to call 90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // init_com_with_mta(false) and then StartWithOptions() with any message loop 91b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // type other than TYPE_UI. 92b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void init_com_with_mta(bool use_mta) { 93cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko DCHECK(!message_loop_); 94b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat com_status_ = use_mta ? MTA : STA; 95b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 96b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 97b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 98b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Starts the thread. Returns true if the thread was successfully started; 99b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // otherwise, returns false. Upon successful return, the message_loop() 100b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // getter will return non-null. 101b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // 102b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Note: This function can't be called on Windows with the loader lock held; 103b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // i.e. during a DllMain, global object construction or destruction, atexit() 104b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // callback. 105b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool Start(); 106b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 107b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Starts the thread. Behaves exactly like Start in addition to allow to 108b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // override the default options. 109b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // 110b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Note: This function can't be called on Windows with the loader lock held; 111b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // i.e. during a DllMain, global object construction or destruction, atexit() 112b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // callback. 113b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool StartWithOptions(const Options& options); 114b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 115b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Starts the thread and wait for the thread to start and run initialization 116b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // before returning. It's same as calling Start() and then 117b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // WaitUntilThreadStarted(). 118b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Note that using this (instead of Start() or StartWithOptions() causes 119b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // jank on the calling thread, should be used only in testing code. 120b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool StartAndWaitForTesting(); 121b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 122b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Blocks until the thread starts running. Called within StartAndWait(). 123b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Note that calling this causes jank on the calling thread, must be used 124b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // carefully for production code. 125cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko bool WaitUntilThreadStarted() const; 126b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 127b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Signals the thread to exit and returns once the thread has exited. After 128b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // this method returns, the Thread object is completely reset and may be used 129b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // as if it were newly constructed (i.e., Start may be called again). 130b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // 131b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Stop may be called multiple times and is simply ignored if the thread is 132b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // already stopped. 133b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // 134b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // NOTE: If you are a consumer of Thread, it is not necessary to call this 135b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // before deleting your Thread objects, as the destructor will do it. 136b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // IF YOU ARE A SUBCLASS OF Thread, YOU MUST CALL THIS IN YOUR DESTRUCTOR. 137b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void Stop(); 138b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 139b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Signals the thread to exit in the near future. 140b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // 141b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // WARNING: This function is not meant to be commonly used. Use at your own 142b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // risk. Calling this function will cause message_loop() to become invalid in 143b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // the near future. This function was created to workaround a specific 144b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // deadlock on Windows with printer worker thread. In any other case, Stop() 145b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // should be used. 146b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // 147b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // StopSoon should not be called multiple times as it is risky to do so. It 148b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // could cause a timing issue in message_loop() access. Call Stop() to reset 149b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // the thread object once it is known that the thread has quit. 150b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void StopSoon(); 151b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 152b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Returns the message loop for this thread. Use the MessageLoop's 153b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // PostTask methods to execute code on the thread. This only returns 154b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // non-null after a successful call to Start. After Stop has been called, 155cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // this will return nullptr. 156b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // 157b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // NOTE: You must not call this MessageLoop's Quit method directly. Use 158b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // the Thread's Stop method instead. 159b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // 160b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat MessageLoop* message_loop() const { return message_loop_; } 161b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 162b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Returns a TaskRunner for this thread. Use the TaskRunner's PostTask 163cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // methods to execute code on the thread. Returns nullptr if the thread is not 164b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // running (e.g. before Start or after Stop have been called). Callers can 165b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // hold on to this even after the thread is gone; in this situation, attempts 166b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // to PostTask() will fail. 167b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat scoped_refptr<SingleThreadTaskRunner> task_runner() const { 168b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return message_loop_ ? message_loop_->task_runner() : nullptr; 169b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 170b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 171b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Returns the name of this thread (for display in debugger too). 172b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const std::string& thread_name() const { return name_; } 173b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 174b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // The native thread handle. 175b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat PlatformThreadHandle thread_handle() { return thread_; } 176b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 177cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // Returns the thread ID. Should not be called before the first Start*() 178cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // call. Keeps on returning the same ID even after a Stop() call. The next 179cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // Start*() call renews the ID. 180cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // 181cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // WARNING: This function will block if the thread hasn't started yet. 182cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // 183cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko PlatformThreadId GetThreadId() const; 184b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 185b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Returns true if the thread has been started, and not yet stopped. 186b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool IsRunning() const; 187b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 188b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat protected: 189b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Called just prior to starting the message loop 190b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat virtual void Init() {} 191b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 192b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Called to start the message loop 193b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat virtual void Run(MessageLoop* message_loop); 194b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 195b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Called just after the message loop ends 196b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat virtual void CleanUp() {} 197b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 198b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat static void SetThreadWasQuitProperly(bool flag); 199b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat static bool GetThreadWasQuitProperly(); 200b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 201b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void set_message_loop(MessageLoop* message_loop) { 202b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat message_loop_ = message_loop; 203b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 204b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 205b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat private: 206b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if defined(OS_WIN) 207b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat enum ComStatus { 208b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat NONE, 209b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat STA, 210b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat MTA, 211b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat }; 212b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 213b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 214b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // PlatformThread::Delegate methods: 215b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void ThreadMain() override; 216b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 217b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if defined(OS_WIN) 218b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Whether this thread needs to initialize COM, and if so, in what mode. 219b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ComStatus com_status_; 220b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 221b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 222b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // If true, we're in the middle of stopping, and shouldn't access 223cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // |message_loop_|. It may non-nullptr and invalid. 224cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // Should be written on the thread that created this thread. Also read data 225cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // could be wrong on other threads. 226b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool stopping_; 227b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 228b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // True while inside of Run(). 229b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool running_; 230cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko mutable base::Lock running_lock_; // Protects |running_|. 231b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 232b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // The thread's handle. 233b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat PlatformThreadHandle thread_; 234cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko mutable base::Lock thread_lock_; // Protects |thread_|. 235cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko 236cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // The thread's id once it has started. 237cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko PlatformThreadId id_; 238cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko mutable WaitableEvent id_event_; // Protects |id_|. 239b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 240b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // The thread's message loop. Valid only while the thread is alive. Set 241b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // by the created thread. 242b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat MessageLoop* message_loop_; 243b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 244b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Stores Options::timer_slack_ until the message loop has been bound to 245b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // a thread. 246b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat TimerSlack message_loop_timer_slack_; 247b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 248b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // The name of the thread. Used for debugging purposes. 249b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat std::string name_; 250b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 251cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // Signaled when the created thread gets ready to use the message loop. 252cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko mutable WaitableEvent start_event_; 253b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 254b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat friend void ThreadQuitHelper(); 255b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 256b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DISALLOW_COPY_AND_ASSIGN(Thread); 257b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}; 258b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 259b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace base 260b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 261b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif // BASE_THREADING_THREAD_H_ 262