summaryrefslogtreecommitdiffstats
path: root/base/threading
diff options
context:
space:
mode:
authorpkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-23 04:33:52 +0000
committerpkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-23 04:33:52 +0000
commit458e9521995681381912ece90eb2a8ea210ae07d (patch)
treed5eeabdee1104f65f42990bbd7edc238a57480d5 /base/threading
parent1822c9949f19195ca0000f0be929a5398a7c24e6 (diff)
downloadchromium_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/threading')
-rw-r--r--base/threading/thread.cc36
-rw-r--r--base/threading/thread.h31
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_