diff options
author | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-23 04:33:52 +0000 |
---|---|---|
committer | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-23 04:33:52 +0000 |
commit | 458e9521995681381912ece90eb2a8ea210ae07d (patch) | |
tree | d5eeabdee1104f65f42990bbd7edc238a57480d5 /base | |
parent | 1822c9949f19195ca0000f0be929a5398a7c24e6 (diff) | |
download | chromium_src-458e9521995681381912ece90eb2a8ea210ae07d.zip chromium_src-458e9521995681381912ece90eb2a8ea210ae07d.tar.gz chromium_src-458e9521995681381912ece90eb2a8ea210ae07d.tar.bz2 |
Add methods to base::Thread to allow Windows consumers to ask for COM to be intialized on the Thread.
This makes one functional change: when COM is initialized in STA mode, the Thread is forced to use a TYPE_UI message loop. Most of the modified consumers here didn't previously do that, but after discussion with cpu and siggi, it seems safest, even though it's more heavyweight.
BUG=none
TEST=none
Review URL: https://codereview.chromium.org/11048029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@163503 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/threading/thread.cc | 36 | ||||
-rw-r--r-- | base/threading/thread.h | 31 |
2 files changed, 60 insertions, 7 deletions
diff --git a/base/threading/thread.cc b/base/threading/thread.cc index 1ba6053..f4ba3ff 100644 --- a/base/threading/thread.cc +++ b/base/threading/thread.cc @@ -11,6 +11,10 @@ #include "base/threading/thread_restrictions.h" #include "base/synchronization/waitable_event.h" +#if defined(OS_WIN) +#include "base/win/scoped_com_initializer.h" +#endif + namespace base { namespace { @@ -45,7 +49,11 @@ struct Thread::StartupData { }; Thread::Thread(const char* name) - : started_(false), + : +#if defined(OS_WIN) + com_status_(NONE), +#endif + started_(false), stopping_(false), running_(false), startup_data_(NULL), @@ -60,11 +68,20 @@ Thread::~Thread() { } bool Thread::Start() { - return StartWithOptions(Options()); + Options options; +#if defined(OS_WIN) + if (com_status_ == STA) + options.message_loop_type = MessageLoop::TYPE_UI; +#endif + return StartWithOptions(options); } bool Thread::StartWithOptions(const Options& options) { DCHECK(!message_loop_); +#if defined(OS_WIN) + DCHECK((com_status_ != STA) || + (options.message_loop_type == MessageLoop::TYPE_UI)); +#endif SetThreadWasQuitProperly(false); @@ -90,7 +107,7 @@ bool Thread::StartWithOptions(const Options& options) { } void Thread::Stop() { - if (!thread_was_started()) + if (!started_) return; StopSoon(); @@ -157,6 +174,15 @@ void Thread::ThreadMain() { message_loop.set_thread_name(name_); message_loop_ = &message_loop; +#if defined(OS_WIN) + scoped_ptr<win::ScopedCOMInitializer> com_initializer; + if (com_status_ != NONE) { + com_initializer.reset((com_status_ == STA) ? + new win::ScopedCOMInitializer() : + new win::ScopedCOMInitializer(win::ScopedCOMInitializer::kMTA)); + } +#endif + // Let the thread do extra initialization. // Let's do this before signaling we are started. Init(); @@ -172,6 +198,10 @@ void Thread::ThreadMain() { // Let the thread do extra cleanup. CleanUp(); +#if defined(OS_WIN) + com_initializer.reset(); +#endif + // Assert that MessageLoop::Quit was called by ThreadQuitHelper. DCHECK(GetThreadWasQuitProperly()); diff --git a/base/threading/thread.h b/base/threading/thread.h index 1d24cf3..645e67c 100644 --- a/base/threading/thread.h +++ b/base/threading/thread.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef BASE_THREAD_H_ -#define BASE_THREAD_H_ +#ifndef BASE_THREADING_THREAD_H_ +#define BASE_THREADING_THREAD_H_ #include <string> @@ -57,6 +57,18 @@ class BASE_EXPORT Thread : PlatformThread::Delegate { // before it is destructed. virtual ~Thread(); +#if defined(OS_WIN) + // Causes the thread to initialize COM. This must be called before calling + // Start() or StartWithOptions(). If |use_mta| is false, the thread is also + // started with a TYPE_UI message loop. It is an error to call + // init_com_with_mta(false) and then StartWithOptions() with any message loop + // type other than TYPE_UI. + void init_com_with_mta(bool use_mta) { + DCHECK(!started_); + com_status_ = use_mta ? MTA : STA; + } +#endif + // Starts the thread. Returns true if the thread was successfully started; // otherwise, returns false. Upon successful return, the message_loop() // getter will return non-null. @@ -148,11 +160,22 @@ class BASE_EXPORT Thread : PlatformThread::Delegate { } private: - bool thread_was_started() const { return started_; } +#if defined(OS_WIN) + enum ComStatus { + NONE, + STA, + MTA, + }; +#endif // PlatformThread::Delegate methods: virtual void ThreadMain() OVERRIDE; +#if defined(OS_WIN) + // Whether this thread needs to initialize COM, and if so, in what mode. + ComStatus com_status_; +#endif + // Whether we successfully started the thread. bool started_; @@ -187,4 +210,4 @@ class BASE_EXPORT Thread : PlatformThread::Delegate { } // namespace base -#endif // BASE_THREAD_H_ +#endif // BASE_THREADING_THREAD_H_ |