• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #ifndef BASE_THREADING_THREAD_H_
6 #define BASE_THREADING_THREAD_H_
7 
8 #include <stddef.h>
9 
10 #include <memory>
11 #include <string>
12 
13 #include "base/base_export.h"
14 #include "base/callback.h"
15 #include "base/macros.h"
16 #include "base/message_loop/message_loop.h"
17 #include "base/message_loop/timer_slack.h"
18 #include "base/sequence_checker.h"
19 #include "base/single_thread_task_runner.h"
20 #include "base/synchronization/atomic_flag.h"
21 #include "base/synchronization/lock.h"
22 #include "base/synchronization/waitable_event.h"
23 #include "base/threading/platform_thread.h"
24 #include "build/build_config.h"
25 
26 namespace base {
27 
28 class MessagePump;
29 class RunLoop;
30 
31 // A simple thread abstraction that establishes a MessageLoop on a new thread.
32 // The consumer uses the MessageLoop of the thread to cause code to execute on
33 // the thread.  When this object is destroyed the thread is terminated.  All
34 // pending tasks queued on the thread's message loop will run to completion
35 // before the thread is terminated.
36 //
37 // WARNING! SUBCLASSES MUST CALL Stop() IN THEIR DESTRUCTORS!  See ~Thread().
38 //
39 // After the thread is stopped, the destruction sequence is:
40 //
41 //  (1) Thread::CleanUp()
42 //  (2) MessageLoop::~MessageLoop
43 //  (3.b)    MessageLoop::DestructionObserver::WillDestroyCurrentMessageLoop
44 //
45 // This API is not thread-safe: unless indicated otherwise its methods are only
46 // valid from the owning sequence (which is the one from which Start() is
47 // invoked -- should it differ from the one on which it was constructed).
48 //
49 // Sometimes it's useful to kick things off on the initial sequence (e.g.
50 // construction, Start(), task_runner()), but to then hand the Thread over to a
51 // pool of users for the last one of them to destroy it when done. For that use
52 // case, Thread::DetachFromSequence() allows the owning sequence to give up
53 // ownership. The caller is then responsible to ensure a happens-after
54 // relationship between the DetachFromSequence() call and the next use of that
55 // Thread object (including ~Thread()).
56 class BASE_EXPORT Thread : PlatformThread::Delegate {
57  public:
58   struct BASE_EXPORT Options {
59     typedef Callback<std::unique_ptr<MessagePump>()> MessagePumpFactory;
60 
61     Options();
62     Options(MessageLoop::Type type, size_t size);
63     Options(const Options& other);
64     ~Options();
65 
66     // Specifies the type of message loop that will be allocated on the thread.
67     // This is ignored if message_pump_factory.is_null() is false.
68     MessageLoop::Type message_loop_type = MessageLoop::TYPE_DEFAULT;
69 
70     // Specifies timer slack for thread message loop.
71     TimerSlack timer_slack = TIMER_SLACK_NONE;
72 
73     // Used to create the MessagePump for the MessageLoop. The callback is Run()
74     // on the thread. If message_pump_factory.is_null(), then a MessagePump
75     // appropriate for |message_loop_type| is created. Setting this forces the
76     // MessageLoop::Type to TYPE_CUSTOM.
77     MessagePumpFactory message_pump_factory;
78 
79     // Specifies the maximum stack size that the thread is allowed to use.
80     // This does not necessarily correspond to the thread's initial stack size.
81     // A value of 0 indicates that the default maximum should be used.
82     size_t stack_size = 0;
83 
84     // Specifies the initial thread priority.
85     ThreadPriority priority = ThreadPriority::NORMAL;
86 
87     // If false, the thread will not be joined on destruction. This is intended
88     // for threads that want TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN
89     // semantics. Non-joinable threads can't be joined (must be leaked and
90     // can't be destroyed or Stop()'ed).
91     // TODO(gab): allow non-joinable instances to be deleted without causing
92     // user-after-frees (proposal @ https://crbug.com/629139#c14)
93     bool joinable = true;
94   };
95 
96   // Constructor.
97   // name is a display string to identify the thread.
98   explicit Thread(const std::string& name);
99 
100   // Destroys the thread, stopping it if necessary.
101   //
102   // NOTE: ALL SUBCLASSES OF Thread MUST CALL Stop() IN THEIR DESTRUCTORS (or
103   // guarantee Stop() is explicitly called before the subclass is destroyed).
104   // This is required to avoid a data race between the destructor modifying the
105   // vtable, and the thread's ThreadMain calling the virtual method Run().  It
106   // also ensures that the CleanUp() virtual method is called on the subclass
107   // before it is destructed.
108   ~Thread() override;
109 
110 #if defined(OS_WIN)
111   // Causes the thread to initialize COM.  This must be called before calling
112   // Start() or StartWithOptions().  If |use_mta| is false, the thread is also
113   // started with a TYPE_UI message loop.  It is an error to call
114   // init_com_with_mta(false) and then StartWithOptions() with any message loop
115   // type other than TYPE_UI.
init_com_with_mta(bool use_mta)116   void init_com_with_mta(bool use_mta) {
117     DCHECK(!message_loop_);
118     com_status_ = use_mta ? MTA : STA;
119   }
120 #endif
121 
122   // Starts the thread.  Returns true if the thread was successfully started;
123   // otherwise, returns false.  Upon successful return, the message_loop()
124   // getter will return non-null.
125   //
126   // Note: This function can't be called on Windows with the loader lock held;
127   // i.e. during a DllMain, global object construction or destruction, atexit()
128   // callback.
129   bool Start();
130 
131   // Starts the thread. Behaves exactly like Start in addition to allow to
132   // override the default options.
133   //
134   // Note: This function can't be called on Windows with the loader lock held;
135   // i.e. during a DllMain, global object construction or destruction, atexit()
136   // callback.
137   bool StartWithOptions(const Options& options);
138 
139   // Starts the thread and wait for the thread to start and run initialization
140   // before returning. It's same as calling Start() and then
141   // WaitUntilThreadStarted().
142   // Note that using this (instead of Start() or StartWithOptions() causes
143   // jank on the calling thread, should be used only in testing code.
144   bool StartAndWaitForTesting();
145 
146   // Blocks until the thread starts running. Called within StartAndWait().
147   // Note that calling this causes jank on the calling thread, must be used
148   // carefully for production code.
149   bool WaitUntilThreadStarted() const;
150 
151   // Blocks until all tasks previously posted to this thread have been executed.
152   void FlushForTesting();
153 
154   // Signals the thread to exit and returns once the thread has exited. The
155   // Thread object is completely reset and may be used as if it were newly
156   // constructed (i.e., Start may be called again). Can only be called if
157   // |joinable_|.
158   //
159   // Stop may be called multiple times and is simply ignored if the thread is
160   // already stopped or currently stopping.
161   //
162   // Start/Stop are not thread-safe and callers that desire to invoke them from
163   // different threads must ensure mutual exclusion.
164   //
165   // NOTE: If you are a consumer of Thread, it is not necessary to call this
166   // before deleting your Thread objects, as the destructor will do it.
167   // IF YOU ARE A SUBCLASS OF Thread, YOU MUST CALL THIS IN YOUR DESTRUCTOR.
168   void Stop();
169 
170   // Signals the thread to exit in the near future.
171   //
172   // WARNING: This function is not meant to be commonly used. Use at your own
173   // risk. Calling this function will cause message_loop() to become invalid in
174   // the near future. This function was created to workaround a specific
175   // deadlock on Windows with printer worker thread. In any other case, Stop()
176   // should be used.
177   //
178   // Call Stop() to reset the thread object once it is known that the thread has
179   // quit.
180   void StopSoon();
181 
182   // Detaches the owning sequence, indicating that the next call to this API
183   // (including ~Thread()) can happen from a different sequence (to which it
184   // will be rebound). This call itself must happen on the current owning
185   // sequence and the caller must ensure the next API call has a happens-after
186   // relationship with this one.
187   void DetachFromSequence();
188 
189   // Returns the message loop for this thread.  Use the MessageLoop's
190   // PostTask methods to execute code on the thread.  This only returns
191   // non-null after a successful call to Start.  After Stop has been called,
192   // this will return nullptr.
193   //
194   // NOTE: You must not call this MessageLoop's Quit method directly.  Use
195   // the Thread's Stop method instead.
196   //
197   // In addition to this Thread's owning sequence, this can also safely be
198   // called from the underlying thread itself.
message_loop()199   MessageLoop* message_loop() const {
200     // This class doesn't provide synchronization around |message_loop_| and as
201     // such only the owner should access it (and the underlying thread which
202     // never sees it before it's set). In practice, many callers are coming from
203     // unrelated threads but provide their own implicit (e.g. memory barriers
204     // from task posting) or explicit (e.g. locks) synchronization making the
205     // access of |message_loop_| safe... Changing all of those callers is
206     // unfeasible; instead verify that they can reliably see
207     // |message_loop_ != nullptr| without synchronization as a proof that their
208     // external synchronization catches the unsynchronized effects of Start().
209     // TODO(gab): Despite all of the above this test has to be disabled for now
210     // per crbug.com/629139#c6.
211     // DCHECK(owning_sequence_checker_.CalledOnValidSequence() ||
212     //        (id_event_.IsSignaled() && id_ == PlatformThread::CurrentId()) ||
213     //        message_loop_);
214     return message_loop_;
215   }
216 
217   // Returns a TaskRunner for this thread. Use the TaskRunner's PostTask
218   // methods to execute code on the thread. Returns nullptr if the thread is not
219   // running (e.g. before Start or after Stop have been called). Callers can
220   // hold on to this even after the thread is gone; in this situation, attempts
221   // to PostTask() will fail.
222   //
223   // In addition to this Thread's owning sequence, this can also safely be
224   // called from the underlying thread itself.
task_runner()225   scoped_refptr<SingleThreadTaskRunner> task_runner() const {
226     // Refer to the DCHECK and comment inside |message_loop()|.
227     DCHECK(owning_sequence_checker_.CalledOnValidSequence() ||
228            (id_event_.IsSignaled() && id_ == PlatformThread::CurrentId()) ||
229            message_loop_);
230     return message_loop_ ? message_loop_->task_runner() : nullptr;
231   }
232 
233   // Returns the name of this thread (for display in debugger too).
thread_name()234   const std::string& thread_name() const { return name_; }
235 
236   // Returns the thread ID.  Should not be called before the first Start*()
237   // call.  Keeps on returning the same ID even after a Stop() call. The next
238   // Start*() call renews the ID.
239   //
240   // WARNING: This function will block if the thread hasn't started yet.
241   //
242   // This method is thread-safe.
243   PlatformThreadId GetThreadId() const;
244 
245   // Returns true if the thread has been started, and not yet stopped.
246   bool IsRunning() const;
247 
248  protected:
249   // Called just prior to starting the message loop
Init()250   virtual void Init() {}
251 
252   // Called to start the run loop
253   virtual void Run(RunLoop* run_loop);
254 
255   // Called just after the message loop ends
CleanUp()256   virtual void CleanUp() {}
257 
258   static void SetThreadWasQuitProperly(bool flag);
259   static bool GetThreadWasQuitProperly();
260 
261   // Bind this Thread to an existing MessageLoop instead of starting a new one.
262   void SetMessageLoop(MessageLoop* message_loop);
263 
using_external_message_loop()264   bool using_external_message_loop() const {
265     return using_external_message_loop_;
266   }
267 
268  private:
269 #if defined(OS_WIN)
270   enum ComStatus {
271     NONE,
272     STA,
273     MTA,
274   };
275 #endif
276 
277   // PlatformThread::Delegate methods:
278   void ThreadMain() override;
279 
280   void ThreadQuitHelper();
281 
282 #if defined(OS_WIN)
283   // Whether this thread needs to initialize COM, and if so, in what mode.
284   ComStatus com_status_ = NONE;
285 #endif
286 
287   // Mirrors the Options::joinable field used to start this thread. Verified
288   // on Stop() -- non-joinable threads can't be joined (must be leaked).
289   bool joinable_ = true;
290 
291   // If true, we're in the middle of stopping, and shouldn't access
292   // |message_loop_|. It may non-nullptr and invalid.
293   // Should be written on the thread that created this thread. Also read data
294   // could be wrong on other threads.
295   bool stopping_ = false;
296 
297   // True while inside of Run().
298   bool running_ = false;
299   mutable base::Lock running_lock_;  // Protects |running_|.
300 
301   // The thread's handle.
302   PlatformThreadHandle thread_;
303   mutable base::Lock thread_lock_;  // Protects |thread_|.
304 
305   // The thread's id once it has started.
306   PlatformThreadId id_ = kInvalidThreadId;
307   // Protects |id_| which must only be read while it's signaled.
308   mutable WaitableEvent id_event_;
309 
310   // The thread's MessageLoop and RunLoop. Valid only while the thread is alive.
311   // Set by the created thread.
312   MessageLoop* message_loop_ = nullptr;
313   RunLoop* run_loop_ = nullptr;
314 
315   // True only if |message_loop_| was externally provided by |SetMessageLoop()|
316   // in which case this Thread has no underlying |thread_| and should merely
317   // drop |message_loop_| on Stop(). In that event, this remains true after
318   // Stop() was invoked so that subclasses can use this state to build their own
319   // cleanup logic as required.
320   bool using_external_message_loop_ = false;
321 
322   // Stores Options::timer_slack_ until the message loop has been bound to
323   // a thread.
324   TimerSlack message_loop_timer_slack_ = TIMER_SLACK_NONE;
325 
326   // The name of the thread.  Used for debugging purposes.
327   const std::string name_;
328 
329   // Signaled when the created thread gets ready to use the message loop.
330   mutable WaitableEvent start_event_;
331 
332   // This class is not thread-safe, use this to verify access from the owning
333   // sequence of the Thread.
334   SequenceChecker owning_sequence_checker_;
335 
336   DISALLOW_COPY_AND_ASSIGN(Thread);
337 };
338 
339 }  // namespace base
340 
341 #endif  // BASE_THREADING_THREAD_H_
342