blob: 1b3ba144c79ce8f1435758c156348efcce33df1a [file] [log] [blame]
license.botf003cfe2008-08-24 09:55:55 +09001// Copyright (c) 2006-2008 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.
initial.commit3f4a7322008-07-27 06:49:38 +09004
maruel@google.comf6e3db82008-08-13 03:37:35 +09005#ifndef BASE_THREAD_H_
6#define BASE_THREAD_H_
initial.commit3f4a7322008-07-27 06:49:38 +09007
initial.commit3f4a7322008-07-27 06:49:38 +09008#include <string>
9
darin@google.comc18d7ae2008-08-21 18:46:32 +090010#include "base/platform_thread.h"
initial.commit3f4a7322008-07-27 06:49:38 +090011#include "base/thread_local_storage.h"
12
13class MessageLoop;
14
darin@google.comc18d7ae2008-08-21 18:46:32 +090015namespace base {
16class WaitableEvent;
17}
avi@google.com4be2f9b2008-08-08 05:12:28 +090018
initial.commit3f4a7322008-07-27 06:49:38 +090019// A simple thread abstraction that establishes a MessageLoop on a new thread.
20// The consumer uses the MessageLoop of the thread to cause code to execute on
21// the thread. When this object is destroyed the thread is terminated. All
22// pending tasks queued on the thread's message loop will run to completion
23// before the thread is terminated.
darin@google.comc18d7ae2008-08-21 18:46:32 +090024class Thread : PlatformThread::Delegate {
initial.commit3f4a7322008-07-27 06:49:38 +090025 public:
26 // Constructor.
27 // name is a display string to identify the thread.
28 explicit Thread(const char *name);
29
30 // Destroys the thread, stopping it if necessary.
31 //
32 virtual ~Thread();
33
34 // Starts the thread. Returns true if the thread was successfully started;
35 // otherwise, returns false. Upon successful return, the message_loop()
36 // getter will return non-null.
37 //
maruel@google.comf6e3db82008-08-13 03:37:35 +090038 // Note: This function can't be called on Windows with the loader lock held;
39 // i.e. during a DllMain, global object construction or destruction, atexit()
40 // callback.
initial.commit3f4a7322008-07-27 06:49:38 +090041 bool Start();
42
43 // Starts the thread. Behaves exactly like Start in addition to allow to
44 // override the default process stack size. This is not the initial stack size
45 // but the maximum stack size that thread is allowed to use.
maruel@google.comf6e3db82008-08-13 03:37:35 +090046 //
47 // Note: This function can't be called on Windows with the loader lock held;
48 // i.e. during a DllMain, global object construction or destruction, atexit()
49 // callback.
initial.commit3f4a7322008-07-27 06:49:38 +090050 bool StartWithStackSize(size_t stack_size);
51
52 // Signals the thread to exit and returns once the thread has exited. After
53 // this method returns, the Thread object is completely reset and may be used
54 // as if it were newly constructed (i.e., Start may be called again).
55 //
56 // Stop may be called multiple times and is simply ignored if the thread is
57 // already stopped.
58 //
59 // NOTE: This method is optional. It is not strictly necessary to call this
60 // method as the Thread's destructor will take care of stopping the thread if
61 // necessary.
62 //
63 void Stop();
64
maruel@google.comf6e3db82008-08-13 03:37:35 +090065 // Signals the thread to exit in the near future.
initial.commit3f4a7322008-07-27 06:49:38 +090066 //
maruel@google.comf6e3db82008-08-13 03:37:35 +090067 // WARNING: This function is not meant to be commonly used. Use at your own
maruel@google.com37377292008-08-14 00:40:45 +090068 // risk. Calling this function will cause message_loop() to become invalid in
maruel@google.comf6e3db82008-08-13 03:37:35 +090069 // the near future. This function was created to workaround a specific
70 // deadlock on Windows with printer worker thread. In any other case, Stop()
71 // should be used.
initial.commit3f4a7322008-07-27 06:49:38 +090072 //
maruel@google.com37377292008-08-14 00:40:45 +090073 // StopSoon should not be called multiple times as it is risky to do so. It
74 // could cause a timing issue in message_loop() access. Call Stop() to reset
75 // the thread object once it is known that the thread has quit.
maruel@google.comf6e3db82008-08-13 03:37:35 +090076 void StopSoon();
initial.commit3f4a7322008-07-27 06:49:38 +090077
78 // Returns the message loop for this thread. Use the MessageLoop's
avi@google.com4be2f9b2008-08-08 05:12:28 +090079 // PostTask methods to execute code on the thread. This only returns
initial.commit3f4a7322008-07-27 06:49:38 +090080 // non-null after a successful call to Start. After Stop has been called,
81 // this will return NULL.
82 //
83 // NOTE: You must not call this MessageLoop's Quit method directly. Use
84 // the Thread's Stop method instead.
85 //
darin@google.comc18d7ae2008-08-21 18:46:32 +090086 MessageLoop* message_loop() const { return message_loop_; }
initial.commit3f4a7322008-07-27 06:49:38 +090087
88 // Set the name of this thread (for display in debugger too).
89 const std::string &thread_name() { return name_; }
90
darin@google.comc18d7ae2008-08-21 18:46:32 +090091 // The native thread handle.
92 PlatformThreadHandle thread_handle() { return thread_; }
initial.commit3f4a7322008-07-27 06:49:38 +090093
94 protected:
95 // Called just prior to starting the message loop
96 virtual void Init() { }
97
98 // Called just after the message loop ends
99 virtual void CleanUp() { }
100
maruel@google.comf6e3db82008-08-13 03:37:35 +0900101 static void SetThreadWasQuitProperly(bool flag);
102 static bool GetThreadWasQuitProperly();
initial.commit3f4a7322008-07-27 06:49:38 +0900103
104 private:
darin@google.comc18d7ae2008-08-21 18:46:32 +0900105 // PlatformThread::Delegate methods:
106 virtual void ThreadMain();
maruel@google.comf6e3db82008-08-13 03:37:35 +0900107
darin@google.comc18d7ae2008-08-21 18:46:32 +0900108 // The thread's handle.
109 PlatformThreadHandle thread_;
maruel@google.comf6e3db82008-08-13 03:37:35 +0900110
darin@google.comc18d7ae2008-08-21 18:46:32 +0900111 // The thread's ID. Used for debugging purposes.
112 int thread_id_;
113
114 // The thread's message loop. Valid only while the thread is alive. Set
maruel@google.comf6e3db82008-08-13 03:37:35 +0900115 // by the created thread.
initial.commit3f4a7322008-07-27 06:49:38 +0900116 MessageLoop* message_loop_;
maruel@google.comf6e3db82008-08-13 03:37:35 +0900117
darin@google.comc18d7ae2008-08-21 18:46:32 +0900118 // Used to synchronize thread startup.
119 base::WaitableEvent* startup_event_;
120
121 // The name of the thread. Used for debugging purposes.
122 std::string name_;
123
124 // This flag indicates if we created a thread that needs to be joined.
125 bool thread_created_;
maruel@google.comf6e3db82008-08-13 03:37:35 +0900126
initial.commit3f4a7322008-07-27 06:49:38 +0900127 static TLSSlot tls_index_;
128
maruel@google.comf6e3db82008-08-13 03:37:35 +0900129 friend class ThreadQuitTask;
130
131 DISALLOW_COPY_AND_ASSIGN(Thread);
initial.commit3f4a7322008-07-27 06:49:38 +0900132};
133
maruel@google.comf6e3db82008-08-13 03:37:35 +0900134#endif // BASE_THREAD_H_
license.botf003cfe2008-08-24 09:55:55 +0900135