1
// Copyright (c) 2012 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.
5
#ifndef BASE_THREADING_THREAD_H_
6
#define BASE_THREADING_THREAD_H_
10
#include "base/base_export.h"
11
#include "base/callback.h"
12
#include "base/memory/scoped_ptr.h"
13
#include "base/message_loop/message_loop.h"
14
#include "base/message_loop/message_loop_proxy.h"
15
#include "base/threading/platform_thread.h"
21
// A simple thread abstraction that establishes a MessageLoop on a new thread.
22
// The consumer uses the MessageLoop of the thread to cause code to execute on
23
// the thread. When this object is destroyed the thread is terminated. All
24
// pending tasks queued on the thread's message loop will run to completion
25
// before the thread is terminated.
27
// WARNING! SUBCLASSES MUST CALL Stop() IN THEIR DESTRUCTORS! See ~Thread().
29
// After the thread is stopped, the destruction sequence is:
31
// (1) Thread::CleanUp()
32
// (2) MessageLoop::~MessageLoop
33
// (3.b) MessageLoop::DestructionObserver::WillDestroyCurrentMessageLoop
34
class BASE_EXPORT Thread : PlatformThread::Delegate {
36
struct BASE_EXPORT Options {
37
typedef Callback<scoped_ptr<MessagePump>()> MessagePumpFactory;
40
Options(MessageLoop::Type type, size_t size);
43
// Specifies the type of message loop that will be allocated on the thread.
44
// This is ignored if message_pump_factory.is_null() is false.
45
MessageLoop::Type message_loop_type;
47
// Used to create the MessagePump for the MessageLoop. The callback is Run()
48
// on the thread. If message_pump_factory.is_null(), then a MessagePump
49
// appropriate for |message_loop_type| is created. Setting this forces the
50
// MessageLoop::Type to TYPE_CUSTOM.
51
MessagePumpFactory message_pump_factory;
53
// Specifies the maximum stack size that the thread is allowed to use.
54
// This does not necessarily correspond to the thread's initial stack size.
55
// A value of 0 indicates that the default maximum should be used.
60
// name is a display string to identify the thread.
61
explicit Thread(const char* name);
63
// Destroys the thread, stopping it if necessary.
65
// NOTE: ALL SUBCLASSES OF Thread MUST CALL Stop() IN THEIR DESTRUCTORS (or
66
// guarantee Stop() is explicitly called before the subclass is destroyed).
67
// This is required to avoid a data race between the destructor modifying the
68
// vtable, and the thread's ThreadMain calling the virtual method Run(). It
69
// also ensures that the CleanUp() virtual method is called on the subclass
70
// before it is destructed.
74
// Causes the thread to initialize COM. This must be called before calling
75
// Start() or StartWithOptions(). If |use_mta| is false, the thread is also
76
// started with a TYPE_UI message loop. It is an error to call
77
// init_com_with_mta(false) and then StartWithOptions() with any message loop
78
// type other than TYPE_UI.
79
void init_com_with_mta(bool use_mta) {
81
com_status_ = use_mta ? MTA : STA;
85
// Starts the thread. Returns true if the thread was successfully started;
86
// otherwise, returns false. Upon successful return, the message_loop()
87
// getter will return non-null.
89
// Note: This function can't be called on Windows with the loader lock held;
90
// i.e. during a DllMain, global object construction or destruction, atexit()
94
// Starts the thread. Behaves exactly like Start in addition to allow to
95
// override the default options.
97
// Note: This function can't be called on Windows with the loader lock held;
98
// i.e. during a DllMain, global object construction or destruction, atexit()
100
bool StartWithOptions(const Options& options);
102
// Signals the thread to exit and returns once the thread has exited. After
103
// this method returns, the Thread object is completely reset and may be used
104
// as if it were newly constructed (i.e., Start may be called again).
106
// Stop may be called multiple times and is simply ignored if the thread is
109
// NOTE: If you are a consumer of Thread, it is not necessary to call this
110
// before deleting your Thread objects, as the destructor will do it.
111
// IF YOU ARE A SUBCLASS OF Thread, YOU MUST CALL THIS IN YOUR DESTRUCTOR.
114
// Signals the thread to exit in the near future.
116
// WARNING: This function is not meant to be commonly used. Use at your own
117
// risk. Calling this function will cause message_loop() to become invalid in
118
// the near future. This function was created to workaround a specific
119
// deadlock on Windows with printer worker thread. In any other case, Stop()
122
// StopSoon should not be called multiple times as it is risky to do so. It
123
// could cause a timing issue in message_loop() access. Call Stop() to reset
124
// the thread object once it is known that the thread has quit.
127
// Returns the message loop for this thread. Use the MessageLoop's
128
// PostTask methods to execute code on the thread. This only returns
129
// non-null after a successful call to Start. After Stop has been called,
130
// this will return NULL.
132
// NOTE: You must not call this MessageLoop's Quit method directly. Use
133
// the Thread's Stop method instead.
135
MessageLoop* message_loop() const { return message_loop_; }
137
// Returns a MessageLoopProxy for this thread. Use the MessageLoopProxy's
138
// PostTask methods to execute code on the thread. This only returns
139
// non-NULL after a successful call to Start. After Stop has been called,
140
// this will return NULL. Callers can hold on to this even after the thread
142
scoped_refptr<MessageLoopProxy> message_loop_proxy() const {
143
return message_loop_ ? message_loop_->message_loop_proxy() : NULL;
146
// Returns the name of this thread (for display in debugger too).
147
const std::string& thread_name() const { return name_; }
149
// The native thread handle.
150
PlatformThreadHandle thread_handle() { return thread_; }
153
PlatformThreadId thread_id() const { return thread_id_; }
155
// Returns true if the thread has been started, and not yet stopped.
156
bool IsRunning() const;
158
// Sets the thread priority. The thread must already be started.
159
void SetPriority(ThreadPriority priority);
162
// Called just prior to starting the message loop
163
virtual void Init() {}
165
// Called to start the message loop
166
virtual void Run(MessageLoop* message_loop);
168
// Called just after the message loop ends
169
virtual void CleanUp() {}
171
static void SetThreadWasQuitProperly(bool flag);
172
static bool GetThreadWasQuitProperly();
174
void set_message_loop(MessageLoop* message_loop) {
175
message_loop_ = message_loop;
187
// PlatformThread::Delegate methods:
188
virtual void ThreadMain() OVERRIDE;
191
// Whether this thread needs to initialize COM, and if so, in what mode.
192
ComStatus com_status_;
195
// Whether we successfully started the thread.
198
// If true, we're in the middle of stopping, and shouldn't access
199
// |message_loop_|. It may non-NULL and invalid.
202
// True while inside of Run().
205
// Used to pass data to ThreadMain.
207
StartupData* startup_data_;
209
// The thread's handle.
210
PlatformThreadHandle thread_;
212
// The thread's message loop. Valid only while the thread is alive. Set
213
// by the created thread.
214
MessageLoop* message_loop_;
217
PlatformThreadId thread_id_;
219
// The name of the thread. Used for debugging purposes.
222
friend void ThreadQuitHelper();
224
DISALLOW_COPY_AND_ASSIGN(Thread);
229
#endif // BASE_THREADING_THREAD_H_