Initialize Tizen 2.3
[external/chromium.git] / base / threading / thread.h
1 // Copyright (c) 2011 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/base_export.h"
12 #include "base/message_loop.h"
13 #include "base/message_loop_proxy.h"
14 #include "base/threading/platform_thread.h"
15
16 namespace base {
17
18 // A simple thread abstraction that establishes a MessageLoop on a new thread.
19 // The consumer uses the MessageLoop of the thread to cause code to execute on
20 // the thread.  When this object is destroyed the thread is terminated.  All
21 // pending tasks queued on the thread's message loop will run to completion
22 // before the thread is terminated.
23 //
24 // After the thread is stopped, the destruction sequence is:
25 //
26 //  (1) Thread::CleanUp()
27 //  (2) MessageLoop::~MessageLoop
28 //  (3.b)    MessageLoop::DestructionObserver::WillDestroyCurrentMessageLoop
29 class BASE_EXPORT Thread : PlatformThread::Delegate {
30  public:
31   struct Options {
32     Options() : message_loop_type(MessageLoop::TYPE_DEFAULT), stack_size(0) {}
33     Options(MessageLoop::Type type, size_t size)
34         : message_loop_type(type), stack_size(size) {}
35
36     // Specifies the type of message loop that will be allocated on the thread.
37     MessageLoop::Type message_loop_type;
38
39     // Specifies the maximum stack size that the thread is allowed to use.
40     // This does not necessarily correspond to the thread's initial stack size.
41     // A value of 0 indicates that the default maximum should be used.
42     size_t stack_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() const {
116     return message_loop_->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   bool thread_was_started() const { return started_; }
156
157   // PlatformThread::Delegate methods:
158   virtual void ThreadMain();
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   // Our thread's ID.
179   PlatformThreadId thread_id_;
180
181   // The name of the thread.  Used for debugging purposes.
182   std::string name_;
183
184   friend class ThreadQuitTask;
185
186   DISALLOW_COPY_AND_ASSIGN(Thread);
187 };
188
189 }  // namespace base
190
191 #endif  // BASE_THREAD_H_