summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/base.gypi15
-rw-r--r--base/debug/trace_event_impl.cc2
-rw-r--r--base/synchronization/lock_unittest.cc14
-rw-r--r--base/threading/platform_thread.h64
-rw-r--r--base/threading/platform_thread_android.cc105
-rw-r--r--base/threading/platform_thread_linux.cc103
-rw-r--r--base/threading/platform_thread_mac.mm48
-rw-r--r--base/threading/platform_thread_posix.cc201
-rw-r--r--base/threading/platform_thread_unittest.cc4
-rw-r--r--base/threading/platform_thread_win.cc26
-rw-r--r--base/threading/thread.cc7
-rw-r--r--base/threading/thread.h3
-rw-r--r--base/threading/thread_restrictions.h1
-rw-r--r--chrome/browser/content_settings/content_settings_pref_provider_unittest.cc2
-rw-r--r--chrome/browser/printing/print_job.cc2
-rw-r--r--chrome_frame/chrome_frame_automation.h3
-rw-r--r--content/renderer/media/webrtc_local_audio_track_unittest.cc8
-rw-r--r--media/audio/audio_device_thread.cc12
-rw-r--r--media/audio/cross_process_notification_win.cc10
-rw-r--r--media/filters/video_renderer_base.cc12
-rw-r--r--remoting/base/auto_thread.cc8
21 files changed, 448 insertions, 202 deletions
diff --git a/base/base.gypi b/base/base.gypi
index c802284..6492073 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -473,6 +473,8 @@
'threading/non_thread_safe_impl.cc',
'threading/non_thread_safe_impl.h',
'threading/platform_thread.h',
+ 'threading/platform_thread_android.cc',
+ 'threading/platform_thread_linux.cc',
'threading/platform_thread_mac.mm',
'threading/platform_thread_posix.cc',
'threading/platform_thread_win.cc',
@@ -655,8 +657,11 @@
'threading/sequenced_worker_pool.cc',
'third_party/dynamic_annotations/dynamic_annotations.c',
],
- # Metrics won't work in the NaCl sandbox.
- 'sources/': [ ['exclude', '^metrics/'] ],
+ 'sources/': [
+ # Metrics won't work in the NaCl sandbox.
+ ['exclude', '^metrics/'],
+ ['include', '^threading/platform_thread_linux\\.cc$'],
+ ],
}],
['OS == "android" and >(nacl_untrusted_build)==0', {
'sources!': [
@@ -674,6 +679,12 @@
['include', '^worker_pool_linux\\.cc$'],
],
}],
+ ['OS == "android" and _toolset == "host" and host_os == "linux"', {
+ 'sources/': [
+ # Pull in specific files for host builds.
+ ['include', '^threading/platform_thread_linux\\.cc$'],
+ ],
+ }],
['OS == "ios" and _toolset != "host"', {
'sources/': [
# Pull in specific Mac files for iOS (which have been filtered out
diff --git a/base/debug/trace_event_impl.cc b/base/debug/trace_event_impl.cc
index 70d92ce..67254c1 100644
--- a/base/debug/trace_event_impl.cc
+++ b/base/debug/trace_event_impl.cc
@@ -977,7 +977,7 @@ void TraceLog::SetDisabled() {
lock_.Release();
PlatformThread::Join(sampling_thread_handle_);
lock_.Acquire();
- sampling_thread_handle_ = 0;
+ sampling_thread_handle_ = PlatformThreadHandle();
sampling_thread_.reset();
}
diff --git a/base/synchronization/lock_unittest.cc b/base/synchronization/lock_unittest.cc
index e87571d..16144755 100644
--- a/base/synchronization/lock_unittest.cc
+++ b/base/synchronization/lock_unittest.cc
@@ -51,7 +51,7 @@ class BasicLockTestThread : public PlatformThread::Delegate {
TEST(LockTest, Basic) {
Lock lock;
BasicLockTestThread thread(&lock);
- PlatformThreadHandle handle = kNullThreadHandle;
+ PlatformThreadHandle handle;
ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
@@ -117,7 +117,7 @@ TEST(LockTest, TryLock) {
// This thread will not be able to get the lock.
{
TryLockTestThread thread(&lock);
- PlatformThreadHandle handle = kNullThreadHandle;
+ PlatformThreadHandle handle;
ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
@@ -131,7 +131,7 @@ TEST(LockTest, TryLock) {
// This thread will....
{
TryLockTestThread thread(&lock);
- PlatformThreadHandle handle = kNullThreadHandle;
+ PlatformThreadHandle handle;
ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
@@ -178,7 +178,7 @@ TEST(LockTest, MutexTwoThreads) {
int value = 0;
MutexLockTestThread thread(&lock, &value);
- PlatformThreadHandle handle = kNullThreadHandle;
+ PlatformThreadHandle handle;
ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
@@ -196,9 +196,9 @@ TEST(LockTest, MutexFourThreads) {
MutexLockTestThread thread1(&lock, &value);
MutexLockTestThread thread2(&lock, &value);
MutexLockTestThread thread3(&lock, &value);
- PlatformThreadHandle handle1 = kNullThreadHandle;
- PlatformThreadHandle handle2 = kNullThreadHandle;
- PlatformThreadHandle handle3 = kNullThreadHandle;
+ PlatformThreadHandle handle1;
+ PlatformThreadHandle handle2;
+ PlatformThreadHandle handle3;
ASSERT_TRUE(PlatformThread::Create(0, &thread1, &handle1));
ASSERT_TRUE(PlatformThread::Create(0, &thread2, &handle2));
diff --git a/base/threading/platform_thread.h b/base/threading/platform_thread.h
index 576695a..c597500 100644
--- a/base/threading/platform_thread.h
+++ b/base/threading/platform_thread.h
@@ -23,27 +23,66 @@
namespace base {
-// PlatformThreadHandle should not be assumed to be a numeric type, since the
-// standard intends to allow pthread_t to be a structure. This means you
-// should not initialize it to a value, like 0. If it's a member variable, the
-// constructor can safely "value initialize" using () in the initializer list.
#if defined(OS_WIN)
typedef DWORD PlatformThreadId;
-typedef void* PlatformThreadHandle; // HANDLE
-const PlatformThreadHandle kNullThreadHandle = NULL;
#elif defined(OS_POSIX)
-typedef pthread_t PlatformThreadHandle;
-const PlatformThreadHandle kNullThreadHandle = 0;
typedef pid_t PlatformThreadId;
#endif
-const PlatformThreadId kInvalidThreadId = 0;
+class PlatformThreadHandle {
+ public:
+#if defined(OS_WIN)
+ typedef void* Handle;
+#elif defined(OS_POSIX)
+ typedef pthread_t Handle;
+#endif
+
+ PlatformThreadHandle()
+ : handle_(0),
+ id_(0) {
+ }
+
+ explicit PlatformThreadHandle(Handle handle)
+ : handle_(handle),
+ id_(0) {
+ }
+
+ PlatformThreadHandle(Handle handle,
+ PlatformThreadId id)
+ : handle_(handle),
+ id_(id) {
+ }
+
+ bool is_equal(const PlatformThreadHandle& other) {
+ return handle_ == other.handle_;
+ }
+
+ bool is_null() {
+ return !handle_;
+ }
+
+ Handle platform_handle() {
+ return handle_;
+ }
+
+ private:
+ friend class PlatformThread;
+
+ Handle handle_;
+ PlatformThreadId id_;
+};
+
+const PlatformThreadId kInvalidThreadId(0);
// Valid values for SetThreadPriority()
enum ThreadPriority{
kThreadPriority_Normal,
// Suitable for low-latency, glitch-resistant audio.
- kThreadPriority_RealtimeAudio
+ kThreadPriority_RealtimeAudio,
+ // Suitable for threads which generate data for the display (at ~60Hz).
+ kThreadPriority_Display,
+ // Suitable for threads that shouldn't disrupt high priority work.
+ kThreadPriority_Background
};
// A namespace for low-level thread functions.
@@ -62,6 +101,9 @@ class BASE_EXPORT PlatformThread {
// Gets the current thread id, which may be useful for logging purposes.
static PlatformThreadId CurrentId();
+ // Get the current handle.
+ static PlatformThreadHandle CurrentHandle();
+
// Yield the current thread so another thread can be scheduled.
static void YieldCurrentThread();
@@ -106,8 +148,6 @@ class BASE_EXPORT PlatformThread {
// |thread_handle|.
static void Join(PlatformThreadHandle thread_handle);
- // Sets the priority of the thread specified in |handle| to |priority|.
- // This does not work on Linux, use CreateWithPriority() instead.
static void SetThreadPriority(PlatformThreadHandle handle,
ThreadPriority priority);
diff --git a/base/threading/platform_thread_android.cc b/base/threading/platform_thread_android.cc
new file mode 100644
index 0000000..2802635
--- /dev/null
+++ b/base/threading/platform_thread_android.cc
@@ -0,0 +1,105 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/threading/platform_thread.h"
+
+#include <errno.h>
+#include <sys/resource.h>
+
+#include "base/android/jni_android.h"
+#include "base/android/thread_utils.h"
+#include "base/lazy_instance.h"
+#include "base/logging.h"
+#include "base/threading/thread_id_name_manager.h"
+#include "base/tracked_objects.h"
+#include "jni/ThreadUtils_jni.h"
+
+namespace base {
+
+namespace {
+int ThreadNiceValue(ThreadPriority priority) {
+ // These nice values are taken from Android, which uses nice
+ // values like linux, but defines some preset nice values.
+ // Process.THREAD_PRIORITY_AUDIO = -16
+ // Process.THREAD_PRIORITY_BACKGROUND = 10
+ // Process.THREAD_PRIORITY_DEFAULT = 0;
+ // Process.THREAD_PRIORITY_DISPLAY = -4;
+ // Process.THREAD_PRIORITY_FOREGROUND = -2;
+ // Process.THREAD_PRIORITY_LESS_FAVORABLE = 1;
+ // Process.THREAD_PRIORITY_LOWEST = 19;
+ // Process.THREAD_PRIORITY_MORE_FAVORABLE = -1;
+ // Process.THREAD_PRIORITY_URGENT_AUDIO = -19;
+ // Process.THREAD_PRIORITY_URGENT_DISPLAY = -8;
+ // We use -6 for display, but we may want to split this
+ // into urgent (-8) and non-urgent (-4).
+ static const int threadPriorityAudio = -16;
+ static const int threadPriorityBackground = 10;
+ static const int threadPriorityDefault = 0;
+ static const int threadPriorityDisplay = -6;
+ switch (priority) {
+ case kThreadPriority_RealtimeAudio:
+ return threadPriorityAudio;
+ case kThreadPriority_Background:
+ return threadPriorityBackground;
+ case kThreadPriority_Normal:
+ return threadPriorityDefault;
+ case kThreadPriority_Display:
+ return threadPriorityDisplay;
+ default:
+ NOTREACHED() << "Unknown priority.";
+ return 0;
+ }
+}
+} // namespace
+
+//static
+void PlatformThread::SetThreadPriority(PlatformThreadHandle handle,
+ ThreadPriority priority) {
+ // On Android, we set the Audio priority through JNI as Audio priority
+ // will also allow the process to run while it is backgrounded.
+ if (priority == kThreadPriority_RealtimeAudio) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_ThreadUtils_setThreadPriorityAudio(env, PlatformThread::CurrentId());
+ return;
+ }
+
+ // setpriority(2) will set a thread's priority if it is passed a tid as
+ // the 'process identifier', not affecting the rest of the threads in the
+ // process. Setting this priority will only succeed if the user has been
+ // granted permission to adjust nice values on the system.
+ DCHECK_NE(handle.id_, kInvalidThreadId);
+ int kNiceSetting = ThreadNiceValue(priority);
+ if (setpriority(PRIO_PROCESS, handle.id_, kNiceSetting))
+ LOG(ERROR) << "Failed to set nice value of thread to " << kNiceSetting;
+}
+
+void PlatformThread::SetName(const char* name) {
+ ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name);
+ tracked_objects::ThreadData::InitializeThreadContext(name);
+}
+
+
+void InitThreading() {
+}
+
+void InitOnThread() {
+ // Threads on linux/android may inherit their priority from the thread
+ // where they were created. This sets all new threads to the default.
+ PlatformThread::SetThreadPriority(PlatformThread::CurrentHandle(),
+ kThreadPriority_Normal);
+}
+
+void TerminateOnThread() {
+ base::android::DetachFromVM();
+}
+
+size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) {
+ return 0;
+}
+
+bool RegisterThreadUtils(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+} // namespace base
diff --git a/base/threading/platform_thread_linux.cc b/base/threading/platform_thread_linux.cc
new file mode 100644
index 0000000..42e12c7
--- /dev/null
+++ b/base/threading/platform_thread_linux.cc
@@ -0,0 +1,103 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/threading/platform_thread.h"
+
+#include <errno.h>
+#include <sched.h>
+
+#include "base/lazy_instance.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/safe_strerror_posix.h"
+#include "base/threading/thread_id_name_manager.h"
+#include "base/threading/thread_restrictions.h"
+#include "base/tracked_objects.h"
+
+#if defined(OS_LINUX)
+#include <sys/prctl.h>
+#include <sys/resource.h>
+#include <sys/syscall.h>
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+namespace base {
+
+namespace {
+int ThreadNiceValue(ThreadPriority priority) {
+ static const int threadPriorityAudio = -10;
+ static const int threadPriorityBackground = 10;
+ static const int threadPriorityDefault = 0;
+ static const int threadPriorityDisplay = -6;
+ switch (priority) {
+ case kThreadPriority_RealtimeAudio:
+ return threadPriorityAudio;
+ case kThreadPriority_Background:
+ return threadPriorityBackground;
+ case kThreadPriority_Normal:
+ return threadPriorityDefault;
+ case kThreadPriority_Display:
+ return threadPriorityDisplay;
+ default:
+ NOTREACHED() << "Unknown priority.";
+ return 0;
+ }
+}
+} // namespace
+
+// static
+void PlatformThread::SetName(const char* name) {
+ ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name);
+ tracked_objects::ThreadData::InitializeThreadContext(name);
+
+#ifndef OS_NACL
+ // On linux we can get the thread names to show up in the debugger by setting
+ // the process name for the LWP. We don't want to do this for the main
+ // thread because that would rename the process, causing tools like killall
+ // to stop working.
+ if (PlatformThread::CurrentId() == getpid())
+ return;
+
+ // http://0pointer.de/blog/projects/name-your-threads.html
+ // Set the name for the LWP (which gets truncated to 15 characters).
+ // Note that glibc also has a 'pthread_setname_np' api, but it may not be
+ // available everywhere and it's only benefit over using prctl directly is
+ // that it can set the name of threads other than the current thread.
+ int err = prctl(PR_SET_NAME, name);
+ // We expect EPERM failures in sandboxed processes, just ignore those.
+ if (err < 0 && errno != EPERM)
+ DPLOG(ERROR) << "prctl(PR_SET_NAME)";
+#endif
+}
+
+// static
+void PlatformThread::SetThreadPriority(PlatformThreadHandle handle,
+ ThreadPriority priority) {
+#ifndef OS_NACL
+ // setpriority(2) will set a thread's priority if it is passed a tid as
+ // the 'process identifier', not affecting the rest of the threads in the
+ // process. Setting this priority will only succeed if the user has been
+ // granted permission to adjust nice values on the system.
+ DCHECK_NE(handle.id_, kInvalidThreadId);
+ int kNiceSetting = ThreadNiceValue(priority);
+ if (setpriority(PRIO_PROCESS, handle.id_, kNiceSetting))
+ LOG(ERROR) << "Failed to set nice value of thread to " << kNiceSetting;
+#endif
+}
+
+void InitThreading() {
+}
+
+void InitOnThread() {
+}
+
+void TerminateOnThread() {
+}
+
+size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) {
+ return 0;
+}
+
+} // namespace base
diff --git a/base/threading/platform_thread_mac.mm b/base/threading/platform_thread_mac.mm
index 48041a0..d81a286 100644
--- a/base/threading/platform_thread_mac.mm
+++ b/base/threading/platform_thread_mac.mm
@@ -5,10 +5,12 @@
#include "base/threading/platform_thread.h"
#import <Foundation/Foundation.h>
+#include <algorithm>
#include <dlfcn.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <mach/thread_policy.h>
+#include <sys/resource.h>
#include "base/lazy_instance.h"
#include "base/logging.h"
@@ -163,7 +165,7 @@ void SetPriorityRealtimeAudio(mach_port_t mach_thread_id) {
void PlatformThread::SetThreadPriority(PlatformThreadHandle handle,
ThreadPriority priority) {
// Convert from pthread_t to mach thread identifier.
- mach_port_t mach_thread_id = pthread_mach_thread_np(handle);
+ mach_port_t mach_thread_id = pthread_mach_thread_np(handle.handle_);
switch (priority) {
case kThreadPriority_Normal:
@@ -172,7 +174,51 @@ void PlatformThread::SetThreadPriority(PlatformThreadHandle handle,
case kThreadPriority_RealtimeAudio:
SetPriorityRealtimeAudio(mach_thread_id);
break;
+ default:
+ NOTREACHED() << "Unknown priority.";
+ break;
+ }
+}
+
+size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) {
+#if defined(OS_IOS)
+ return 0;
+#else
+ // The Mac OS X default for a pthread stack size is 512kB.
+ // Libc-594.1.4/pthreads/pthread.c's pthread_attr_init uses
+ // DEFAULT_STACK_SIZE for this purpose.
+ //
+ // 512kB isn't quite generous enough for some deeply recursive threads that
+ // otherwise request the default stack size by specifying 0. Here, adopt
+ // glibc's behavior as on Linux, which is to use the current stack size
+ // limit (ulimit -s) as the default stack size. See
+ // glibc-2.11.1/nptl/nptl-init.c's __pthread_initialize_minimal_internal. To
+ // avoid setting the limit below the Mac OS X default or the minimum usable
+ // stack size, these values are also considered. If any of these values
+ // can't be determined, or if stack size is unlimited (ulimit -s unlimited),
+ // stack_size is left at 0 to get the system default.
+ //
+ // Mac OS X normally only applies ulimit -s to the main thread stack. On
+ // contemporary OS X and Linux systems alike, this value is generally 8MB
+ // or in that neighborhood.
+ size_t default_stack_size = 0;
+ struct rlimit stack_rlimit;
+ if (pthread_attr_getstacksize(&attributes, &default_stack_size) == 0 &&
+ getrlimit(RLIMIT_STACK, &stack_rlimit) == 0 &&
+ stack_rlimit.rlim_cur != RLIM_INFINITY) {
+ default_stack_size =
+ std::max(std::max(default_stack_size,
+ static_cast<size_t>(PTHREAD_STACK_MIN)),
+ static_cast<size_t>(stack_rlimit.rlim_cur));
}
+ return default_stack_size;
+#endif
+}
+
+void InitOnThread() {
+}
+
+void TerminateOnThread() {
}
} // namespace base
diff --git a/base/threading/platform_thread_posix.cc b/base/threading/platform_thread_posix.cc
index 43e58b7..b1c0e9d 100644
--- a/base/threading/platform_thread_posix.cc
+++ b/base/threading/platform_thread_posix.cc
@@ -11,6 +11,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/safe_strerror_posix.h"
+#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_id_name_manager.h"
#include "base/threading/thread_restrictions.h"
#include "base/tracked_objects.h"
@@ -28,74 +29,53 @@
#include <unistd.h>
#endif
-#if defined(OS_ANDROID)
-#include <sys/resource.h>
-#include "base/android/thread_utils.h"
-#include "jni/ThreadUtils_jni.h"
-#endif
-
namespace base {
-#if defined(OS_MACOSX)
void InitThreading();
-#endif
+void InitOnThread();
+void TerminateOnThread();
+size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes);
namespace {
struct ThreadParams {
+ ThreadParams()
+ : delegate(NULL),
+ joinable(false),
+ priority(kThreadPriority_Normal),
+ handle(NULL),
+ handle_set(false, false) {
+ }
+
PlatformThread::Delegate* delegate;
bool joinable;
ThreadPriority priority;
+ PlatformThreadHandle* handle;
+ WaitableEvent handle_set;
};
-void SetCurrentThreadPriority(ThreadPriority priority) {
-#if defined(OS_LINUX) || defined(OS_ANDROID)
- switch (priority) {
- case kThreadPriority_Normal:
- NOTREACHED() << "Don't reset priority as not all processes can.";
- break;
- case kThreadPriority_RealtimeAudio:
-#if defined(OS_LINUX)
- const int kNiceSetting = -10;
- // Linux isn't posix compliant with setpriority(2), it will set a thread
- // priority if it is passed a tid, not affecting the rest of the threads
- // in the process. Setting this priority will only succeed if the user
- // has been granted permission to adjust nice values on the system.
- if (setpriority(PRIO_PROCESS, PlatformThread::CurrentId(), kNiceSetting))
- DVLOG(1) << "Failed to set nice value of thread to " << kNiceSetting;
-#elif defined(OS_ANDROID)
- JNIEnv* env = base::android::AttachCurrentThread();
- Java_ThreadUtils_setThreadPriorityAudio(env, PlatformThread::CurrentId());
-#endif // defined(OS_LINUX)
- break;
- }
-#else // !defined(OS_LINUX) && !defined(OS_ANDROID)
- PlatformThread::SetThreadPriority(pthread_self(), priority);
-#endif
-}
-
void* ThreadFunc(void* params) {
-#if defined(OS_ANDROID)
- // Threads on linux/android may inherit their priority from the thread
- // where they were created. This sets all threads to the default.
- // TODO(epenner): Move thread priorities to base. (crbug.com/170549)
- if (setpriority(PRIO_PROCESS, PlatformThread::CurrentId(), 0))
- DVLOG(1) << "Failed to reset initial thread nice value to zero.";
-#endif
+ base::InitOnThread();
ThreadParams* thread_params = static_cast<ThreadParams*>(params);
+
PlatformThread::Delegate* delegate = thread_params->delegate;
if (!thread_params->joinable)
base::ThreadRestrictions::SetSingletonAllowed(false);
- // If there is a non-default priority for this thread, set it now.
- if (thread_params->priority != kThreadPriority_Normal)
- SetCurrentThreadPriority(thread_params->priority);
+ if (thread_params->priority != kThreadPriority_Normal) {
+ PlatformThread::SetThreadPriority(PlatformThread::CurrentHandle(),
+ thread_params->priority);
+ }
+
+ // Stash the id in the handle so the calling thread has a complete
+ // handle, and unblock the parent thread.
+ *(thread_params->handle) = PlatformThreadHandle(pthread_self(),
+ PlatformThread::CurrentId());
+ thread_params->handle_set.Signal();
- delete thread_params;
delegate->ThreadMain();
-#if defined(OS_ANDROID)
- base::android::DetachFromVM();
-#endif
+
+ base::TerminateOnThread();
return NULL;
}
@@ -103,60 +83,36 @@ bool CreateThread(size_t stack_size, bool joinable,
PlatformThread::Delegate* delegate,
PlatformThreadHandle* thread_handle,
ThreadPriority priority) {
-#if defined(OS_MACOSX)
base::InitThreading();
-#endif // OS_MACOSX
bool success = false;
pthread_attr_t attributes;
pthread_attr_init(&attributes);
- // Pthreads are joinable by default, so only specify the detached attribute if
- // the thread should be non-joinable.
+ // Pthreads are joinable by default, so only specify the detached
+ // attribute if the thread should be non-joinable.
if (!joinable) {
pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
}
-#if defined(OS_MACOSX) && !defined(OS_IOS)
- // The Mac OS X default for a pthread stack size is 512kB.
- // Libc-594.1.4/pthreads/pthread.c's pthread_attr_init uses
- // DEFAULT_STACK_SIZE for this purpose.
- //
- // 512kB isn't quite generous enough for some deeply recursive threads that
- // otherwise request the default stack size by specifying 0. Here, adopt
- // glibc's behavior as on Linux, which is to use the current stack size
- // limit (ulimit -s) as the default stack size. See
- // glibc-2.11.1/nptl/nptl-init.c's __pthread_initialize_minimal_internal. To
- // avoid setting the limit below the Mac OS X default or the minimum usable
- // stack size, these values are also considered. If any of these values
- // can't be determined, or if stack size is unlimited (ulimit -s unlimited),
- // stack_size is left at 0 to get the system default.
- //
- // Mac OS X normally only applies ulimit -s to the main thread stack. On
- // contemporary OS X and Linux systems alike, this value is generally 8MB
- // or in that neighborhood.
- if (stack_size == 0) {
- size_t default_stack_size;
- struct rlimit stack_rlimit;
- if (pthread_attr_getstacksize(&attributes, &default_stack_size) == 0 &&
- getrlimit(RLIMIT_STACK, &stack_rlimit) == 0 &&
- stack_rlimit.rlim_cur != RLIM_INFINITY) {
- stack_size = std::max(std::max(default_stack_size,
- static_cast<size_t>(PTHREAD_STACK_MIN)),
- static_cast<size_t>(stack_rlimit.rlim_cur));
- }
- }
-#endif // OS_MACOSX && !OS_IOS
+ // Get a better default if available.
+ if (stack_size == 0)
+ stack_size = base::GetDefaultThreadStackSize(attributes);
if (stack_size > 0)
pthread_attr_setstacksize(&attributes, stack_size);
- ThreadParams* params = new ThreadParams;
- params->delegate = delegate;
- params->joinable = joinable;
- params->priority = priority;
-
- int err = pthread_create(thread_handle, &attributes, ThreadFunc, params);
+ ThreadParams params;
+ params.delegate = delegate;
+ params.joinable = joinable;
+ params.priority = priority;
+ params.handle = thread_handle;
+
+ pthread_t handle = 0;
+ int err = pthread_create(&handle,
+ &attributes,
+ ThreadFunc,
+ &params);
success = !err;
if (!success) {
errno = err;
@@ -164,8 +120,13 @@ bool CreateThread(size_t stack_size, bool joinable,
}
pthread_attr_destroy(&attributes);
- if (!success)
- delete params;
+
+ // Don't let this call complete until the thread id
+ // is set in the handle.
+ if (success)
+ params.handle_set.Wait();
+ CHECK_EQ(handle, thread_handle->platform_handle());
+
return success;
}
@@ -193,6 +154,11 @@ PlatformThreadId PlatformThread::CurrentId() {
#endif
}
+//static
+PlatformThreadHandle PlatformThread::CurrentHandle() {
+ return PlatformThreadHandle(pthread_self(), CurrentId());
+}
+
// static
void PlatformThread::YieldCurrentThread() {
sched_yield();
@@ -213,42 +179,6 @@ void PlatformThread::Sleep(TimeDelta duration) {
sleep_time = remaining;
}
-#if defined(OS_LINUX)
-// static
-void PlatformThread::SetName(const char* name) {
- ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name);
- tracked_objects::ThreadData::InitializeThreadContext(name);
-
- // On linux we can get the thread names to show up in the debugger by setting
- // the process name for the LWP. We don't want to do this for the main
- // thread because that would rename the process, causing tools like killall
- // to stop working.
- if (PlatformThread::CurrentId() == getpid())
- return;
-
- // http://0pointer.de/blog/projects/name-your-threads.html
- // Set the name for the LWP (which gets truncated to 15 characters).
- // Note that glibc also has a 'pthread_setname_np' api, but it may not be
- // available everywhere and it's only benefit over using prctl directly is
- // that it can set the name of threads other than the current thread.
- int err = prctl(PR_SET_NAME, name);
- // We expect EPERM failures in sandboxed processes, just ignore those.
- if (err < 0 && errno != EPERM)
- DPLOG(ERROR) << "prctl(PR_SET_NAME)";
-}
-#elif defined(OS_MACOSX)
-// Mac is implemented in platform_thread_mac.mm.
-#else
-// static
-void PlatformThread::SetName(const char* name) {
- ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name);
- tracked_objects::ThreadData::InitializeThreadContext(name);
-
- // (This should be relatively simple to implement for the BSDs; I
- // just don't have one handy to test the code on.)
-}
-#endif // defined(OS_LINUX)
-
// static
const char* PlatformThread::GetName() {
return ThreadIdNameManager::GetInstance()->GetName(CurrentId());
@@ -257,6 +187,7 @@ const char* PlatformThread::GetName() {
// static
bool PlatformThread::Create(size_t stack_size, Delegate* delegate,
PlatformThreadHandle* thread_handle) {
+ base::ThreadRestrictions::ScopedAllowWait allow_wait;
return CreateThread(stack_size, true /* joinable thread */,
delegate, thread_handle, kThreadPriority_Normal);
}
@@ -265,6 +196,7 @@ bool PlatformThread::Create(size_t stack_size, Delegate* delegate,
bool PlatformThread::CreateWithPriority(size_t stack_size, Delegate* delegate,
PlatformThreadHandle* thread_handle,
ThreadPriority priority) {
+ base::ThreadRestrictions::ScopedAllowWait allow_wait;
return CreateThread(stack_size, true, // joinable thread
delegate, thread_handle, priority);
}
@@ -273,6 +205,7 @@ bool PlatformThread::CreateWithPriority(size_t stack_size, Delegate* delegate,
bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) {
PlatformThreadHandle unused;
+ base::ThreadRestrictions::ScopedAllowWait allow_wait;
bool result = CreateThread(stack_size, false /* non-joinable thread */,
delegate, &unused, kThreadPriority_Normal);
return result;
@@ -284,21 +217,7 @@ void PlatformThread::Join(PlatformThreadHandle thread_handle) {
// the thread referred to by |thread_handle| may still be running long-lived /
// blocking tasks.
base::ThreadRestrictions::AssertIOAllowed();
- pthread_join(thread_handle, NULL);
-}
-
-#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
-// Mac OS X uses lower-level mach APIs and Android uses Java APIs.
-// static
-void PlatformThread::SetThreadPriority(PlatformThreadHandle, ThreadPriority) {
- // TODO(crogers): Implement, see http://crbug.com/116172
-}
-#endif
-
-#if defined(OS_ANDROID)
-bool RegisterThreadUtils(JNIEnv* env) {
- return RegisterNativesImpl(env);
+ pthread_join(thread_handle.handle_, NULL);
}
-#endif // defined(OS_ANDROID)
} // namespace base
diff --git a/base/threading/platform_thread_unittest.cc b/base/threading/platform_thread_unittest.cc
index e37709a..59f29da 100644
--- a/base/threading/platform_thread_unittest.cc
+++ b/base/threading/platform_thread_unittest.cc
@@ -29,7 +29,7 @@ class TrivialThread : public PlatformThread::Delegate {
TEST(PlatformThreadTest, Trivial) {
TrivialThread thread;
- PlatformThreadHandle handle = kNullThreadHandle;
+ PlatformThreadHandle handle;
ASSERT_FALSE(thread.did_run());
ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
@@ -80,7 +80,7 @@ TEST(PlatformThreadTest, Function) {
PlatformThreadId main_thread_id = PlatformThread::CurrentId();
FunctionTestThread thread;
- PlatformThreadHandle handle = kNullThreadHandle;
+ PlatformThreadHandle handle;
ASSERT_FALSE(thread.did_run());
ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
diff --git a/base/threading/platform_thread_win.cc b/base/threading/platform_thread_win.cc
index 9e877b3..904f2b4 100644
--- a/base/threading/platform_thread_win.cc
+++ b/base/threading/platform_thread_win.cc
@@ -64,7 +64,6 @@ DWORD __stdcall ThreadFunc(void* params) {
bool CreateThreadInternal(size_t stack_size,
PlatformThread::Delegate* delegate,
PlatformThreadHandle* out_thread_handle) {
- PlatformThreadHandle thread_handle;
unsigned int flags = 0;
if (stack_size > 0 && base::win::GetVersion() >= base::win::VERSION_XP) {
flags = STACK_SIZE_PARAM_IS_A_RESERVATION;
@@ -81,7 +80,7 @@ bool CreateThreadInternal(size_t stack_size,
// have to work running on CreateThread() threads anyway, since we run code
// on the Windows thread pool, etc. For some background on the difference:
// http://www.microsoft.com/msj/1099/win32/win321099.aspx
- thread_handle = CreateThread(
+ void* thread_handle = CreateThread(
NULL, stack_size, ThreadFunc, params, flags, NULL);
if (!thread_handle) {
delete params;
@@ -89,7 +88,7 @@ bool CreateThreadInternal(size_t stack_size,
}
if (out_thread_handle)
- *out_thread_handle = thread_handle;
+ *out_thread_handle = PlatformThreadHandle(thread_handle);
else
CloseHandle(thread_handle);
return true;
@@ -103,6 +102,12 @@ PlatformThreadId PlatformThread::CurrentId() {
}
// static
+PlatformThreadHandle PlatformThread::CurrentHandle() {
+ NOTIMPLEMENTED(); // See OpenThread()
+ return PlatformThreadHandle();
+}
+
+// static
void PlatformThread::YieldCurrentThread() {
::Sleep(0);
}
@@ -164,7 +169,7 @@ bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) {
// static
void PlatformThread::Join(PlatformThreadHandle thread_handle) {
- DCHECK(thread_handle);
+ DCHECK(thread_handle.handle_);
// TODO(willchan): Enable this check once I can get it to work for Windows
// shutdown.
// Joining another thread may block the current thread for a long time, since
@@ -176,17 +181,17 @@ void PlatformThread::Join(PlatformThreadHandle thread_handle) {
// Wait for the thread to exit. It should already have terminated but make
// sure this assumption is valid.
- DWORD result = WaitForSingleObject(thread_handle, INFINITE);
+ DWORD result = WaitForSingleObject(thread_handle.handle_, INFINITE);
if (result != WAIT_OBJECT_0) {
// Debug info for bug 127931.
DWORD error = GetLastError();
debug::Alias(&error);
debug::Alias(&result);
- debug::Alias(&thread_handle);
+ debug::Alias(&thread_handle.handle_);
CHECK(false);
}
- CloseHandle(thread_handle);
+ CloseHandle(thread_handle.handle_);
}
// static
@@ -194,10 +199,13 @@ void PlatformThread::SetThreadPriority(PlatformThreadHandle handle,
ThreadPriority priority) {
switch (priority) {
case kThreadPriority_Normal:
- ::SetThreadPriority(handle, THREAD_PRIORITY_NORMAL);
+ ::SetThreadPriority(handle.handle_, THREAD_PRIORITY_NORMAL);
break;
case kThreadPriority_RealtimeAudio:
- ::SetThreadPriority(handle, THREAD_PRIORITY_TIME_CRITICAL);
+ ::SetThreadPriority(handle.handle_, THREAD_PRIORITY_TIME_CRITICAL);
+ break;
+ default:
+ NOTREACHED() << "Unknown priority.";
break;
}
}
diff --git a/base/threading/thread.cc b/base/threading/thread.cc
index 35e88a7..8b3dc2b 100644
--- a/base/threading/thread.cc
+++ b/base/threading/thread.cc
@@ -148,6 +148,13 @@ bool Thread::IsRunning() const {
return running_;
}
+void Thread::SetPriority(ThreadPriority priority) {
+ // The thread must be started (and id known) for this to be
+ // compatible with all platforms.
+ DCHECK_NE(thread_id_, kInvalidThreadId);
+ PlatformThread::SetThreadPriority(thread_, priority);
+}
+
void Thread::Run(MessageLoop* message_loop) {
message_loop->Run();
}
diff --git a/base/threading/thread.h b/base/threading/thread.h
index cf1a86d..15f73a0 100644
--- a/base/threading/thread.h
+++ b/base/threading/thread.h
@@ -142,6 +142,9 @@ class BASE_EXPORT Thread : PlatformThread::Delegate {
// Returns true if the thread has been started, and not yet stopped.
bool IsRunning() const;
+ // Sets the thread priority. The thread must already be started.
+ void SetPriority(ThreadPriority priority);
+
protected:
// Called just prior to starting the message loop
virtual void Init() {}
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h
index 51cfa27..5abc8dc9 100644
--- a/base/threading/thread_restrictions.h
+++ b/base/threading/thread_restrictions.h
@@ -182,6 +182,7 @@ class BASE_EXPORT ThreadRestrictions {
friend class SimpleThread;
friend class Thread;
friend class ThreadTestHelper;
+ friend class PlatformThread;
// END ALLOWED USAGE.
// BEGIN USAGE THAT NEEDS TO BE FIXED.
diff --git a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
index c287abb..656d517 100644
--- a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
+++ b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
@@ -79,7 +79,7 @@ class DeadlockCheckerObserver {
// Check whether |provider_| holds its lock. For this, we need a
// separate thread.
DeadlockCheckerThread thread(provider_);
- base::PlatformThreadHandle handle = base::kNullThreadHandle;
+ base::PlatformThreadHandle handle;
ASSERT_TRUE(base::PlatformThread::Create(0, &thread, &handle));
base::PlatformThread::Join(handle);
notification_received_ = true;
diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc
index 13cb4ca..6c91282 100644
--- a/chrome/browser/printing/print_job.cc
+++ b/chrome/browser/printing/print_job.cc
@@ -331,7 +331,7 @@ void PrintJob::ControlledWorkerShutdown() {
// - We don't want to run tasks while the thread is quitting.
// - We want this code path to wait on the thread to quit before continuing.
MSG msg;
- HANDLE thread_handle = worker_->thread_handle();
+ HANDLE thread_handle = worker_->thread_handle().platform_handle();
for (; thread_handle;) {
// Note that we don't do any kind of message prioritization since we don't
// execute any pending task or timer.
diff --git a/chrome_frame/chrome_frame_automation.h b/chrome_frame/chrome_frame_automation.h
index e903268..150a778 100644
--- a/chrome_frame/chrome_frame_automation.h
+++ b/chrome_frame/chrome_frame_automation.h
@@ -226,7 +226,8 @@ class AutomationProxyCacheEntry
DWORD WaitForThread(DWORD timeout) { // NOLINT
DCHECK(thread_.get());
- return ::WaitForSingleObject(thread_->thread_handle(), timeout);
+ return ::WaitForSingleObject(thread_->thread_handle().platform_handle(),
+ timeout);
}
bool IsSameProfile(const std::wstring& name) const {
diff --git a/content/renderer/media/webrtc_local_audio_track_unittest.cc b/content/renderer/media/webrtc_local_audio_track_unittest.cc
index 7e2f473..3d11fae 100644
--- a/content/renderer/media/webrtc_local_audio_track_unittest.cc
+++ b/content/renderer/media/webrtc_local_audio_track_unittest.cc
@@ -30,13 +30,13 @@ class FakeAudioThread : public base::PlatformThread::Delegate {
public:
explicit FakeAudioThread(const scoped_refptr<WebRtcAudioCapturer>& capturer)
: capturer_(capturer),
- thread_(base::kNullThreadHandle),
+ thread_(),
closure_(false, false) {
DCHECK(capturer);
audio_bus_ = media::AudioBus::Create(capturer_->audio_parameters());
}
- virtual ~FakeAudioThread() { DCHECK(!thread_); }
+ virtual ~FakeAudioThread() { DCHECK(thread_.is_null()); }
// base::PlatformThread::Delegate:
virtual void ThreadMain() OVERRIDE {
@@ -57,13 +57,13 @@ class FakeAudioThread : public base::PlatformThread::Delegate {
void Start() {
base::PlatformThread::CreateWithPriority(
0, this, &thread_, base::kThreadPriority_RealtimeAudio);
- CHECK(thread_ != base::kNullThreadHandle);
+ CHECK(!thread_.is_null());
}
void Stop() {
closure_.Signal();
base::PlatformThread::Join(thread_);
- thread_ = base::kNullThreadHandle;
+ thread_ = base::PlatformThreadHandle();
}
private:
diff --git a/media/audio/audio_device_thread.cc b/media/audio/audio_device_thread.cc
index 7583c9e..f68c045 100644
--- a/media/audio/audio_device_thread.cc
+++ b/media/audio/audio_device_thread.cc
@@ -94,31 +94,31 @@ bool AudioDeviceThread::IsStopped() {
AudioDeviceThread::Thread::Thread(AudioDeviceThread::Callback* callback,
base::SyncSocket::Handle socket,
const char* thread_name)
- : thread_(base::kNullThreadHandle),
+ : thread_(),
callback_(callback),
socket_(socket),
thread_name_(thread_name) {
}
AudioDeviceThread::Thread::~Thread() {
- DCHECK_EQ(thread_, base::kNullThreadHandle) << "Stop wasn't called";
+ DCHECK(thread_.is_null());
}
void AudioDeviceThread::Thread::Start() {
base::AutoLock auto_lock(callback_lock_);
- DCHECK_EQ(thread_, base::kNullThreadHandle);
+ DCHECK(thread_.is_null());
// This reference will be released when the thread exists.
AddRef();
PlatformThread::CreateWithPriority(0, this, &thread_,
base::kThreadPriority_RealtimeAudio);
- CHECK(thread_ != base::kNullThreadHandle);
+ CHECK(!thread_.is_null());
}
void AudioDeviceThread::Thread::Stop(base::MessageLoop* loop_for_join) {
socket_.Shutdown();
- base::PlatformThreadHandle thread = base::kNullThreadHandle;
+ base::PlatformThreadHandle thread = base::PlatformThreadHandle();
{ // NOLINT
base::AutoLock auto_lock(callback_lock_);
@@ -126,7 +126,7 @@ void AudioDeviceThread::Thread::Stop(base::MessageLoop* loop_for_join) {
std::swap(thread, thread_);
}
- if (thread != base::kNullThreadHandle) {
+ if (!thread.is_null()) {
if (loop_for_join) {
loop_for_join->PostTask(FROM_HERE,
base::Bind(&base::PlatformThread::Join, thread));
diff --git a/media/audio/cross_process_notification_win.cc b/media/audio/cross_process_notification_win.cc
index 65e0e43..53bf0f4 100644
--- a/media/audio/cross_process_notification_win.cc
+++ b/media/audio/cross_process_notification_win.cc
@@ -121,7 +121,9 @@ class ExtraWaitThread : public base::PlatformThread::Delegate {
&events_[MAXIMUM_WAIT_OBJECTS - 2],
count_ - (MAXIMUM_WAIT_OBJECTS - 2),
&thread_signaled_event));
- base::PlatformThread::Create(0, extra_wait_thread.get(), &next_thread);
+ base::PlatformThreadHandle handle;
+ base::PlatformThread::Create(0, extra_wait_thread.get(), &handle);
+ next_thread = handle.platform_handle();
event_count = MAXIMUM_WAIT_OBJECTS;
events[MAXIMUM_WAIT_OBJECTS - 1] = next_thread;
@@ -140,7 +142,7 @@ class ExtraWaitThread : public base::PlatformThread::Delegate {
// so on), we must wait for ours to exit before we can check the
// propagated event offset.
if (next_thread) {
- base::PlatformThread::Join(next_thread);
+ base::PlatformThread::Join(base::PlatformThreadHandle(next_thread));
next_thread = NULL;
}
if (thread_signaled_event != -1)
@@ -156,7 +158,7 @@ class ExtraWaitThread : public base::PlatformThread::Delegate {
}
if (next_thread)
- base::PlatformThread::Join(next_thread);
+ base::PlatformThread::Join(base::PlatformThreadHandle(next_thread));
}
private:
@@ -232,7 +234,7 @@ int CrossProcessNotification::WaitMultiple(const Notifications& notifications,
base::PlatformThread::Create(0, &wait_thread, &thread);
HANDLE events[MAXIMUM_WAIT_OBJECTS];
std::copy(&handles[0], &handles[MAXIMUM_WAIT_OBJECTS - 1], &events[0]);
- events[MAXIMUM_WAIT_OBJECTS - 1] = thread;
+ events[MAXIMUM_WAIT_OBJECTS - 1] = thread.platform_handle();
wait = ::WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, &events[0], FALSE,
INFINITE);
wait_failed = wait < WAIT_OBJECT_0 ||
diff --git a/media/filters/video_renderer_base.cc b/media/filters/video_renderer_base.cc
index f79e99d..84e48c4 100644
--- a/media/filters/video_renderer_base.cc
+++ b/media/filters/video_renderer_base.cc
@@ -35,7 +35,7 @@ VideoRendererBase::VideoRendererBase(
received_end_of_stream_(false),
frame_available_(&lock_),
state_(kUninitialized),
- thread_(base::kNullThreadHandle),
+ thread_(),
pending_read_(false),
drop_frames_(drop_frames),
playback_rate_(0),
@@ -48,7 +48,7 @@ VideoRendererBase::VideoRendererBase(
VideoRendererBase::~VideoRendererBase() {
base::AutoLock auto_lock(lock_);
CHECK(state_ == kStopped || state_ == kUninitialized) << state_;
- CHECK_EQ(thread_, base::kNullThreadHandle);
+ CHECK(thread_.is_null());
}
void VideoRendererBase::Play(const base::Closure& callback) {
@@ -100,15 +100,15 @@ void VideoRendererBase::Stop(const base::Closure& callback) {
DoStopOrError_Locked();
// Clean up our thread if present.
- base::PlatformThreadHandle thread_to_join = base::kNullThreadHandle;
- if (thread_ != base::kNullThreadHandle) {
+ base::PlatformThreadHandle thread_to_join = base::PlatformThreadHandle();
+ if (!thread_.is_null()) {
// Signal the thread since it's possible to get stopped with the video
// thread waiting for a read to complete.
frame_available_.Signal();
std::swap(thread_, thread_to_join);
}
- if (thread_to_join != base::kNullThreadHandle) {
+ if (!thread_to_join.is_null()) {
base::AutoUnlock auto_unlock(lock_);
base::PlatformThread::Join(thread_to_join);
}
@@ -212,7 +212,7 @@ void VideoRendererBase::OnVideoFrameStreamInitialized(bool success,
#if defined(OS_WIN)
// Bump up our priority so our sleeping is more accurate.
// TODO(scherkus): find out if this is necessary, but it seems to help.
- ::SetThreadPriority(thread_, THREAD_PRIORITY_ABOVE_NORMAL);
+ ::SetThreadPriority(thread_.platform_handle(), THREAD_PRIORITY_ABOVE_NORMAL);
#endif // defined(OS_WIN)
base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
}
diff --git a/remoting/base/auto_thread.cc b/remoting/base/auto_thread.cc
index d79af49..9890bc3 100644
--- a/remoting/base/auto_thread.cc
+++ b/remoting/base/auto_thread.cc
@@ -92,7 +92,7 @@ AutoThread::AutoThread(const char* name)
#if defined(OS_WIN)
com_init_type_(COM_INIT_NONE),
#endif
- thread_(0),
+ thread_(),
name_(name),
was_quit_properly_(false) {
}
@@ -102,7 +102,7 @@ AutoThread::AutoThread(const char* name, AutoThreadTaskRunner* joiner)
#if defined(OS_WIN)
com_init_type_(COM_INIT_NONE),
#endif
- thread_(0),
+ thread_(),
name_(name),
was_quit_properly_(false),
joiner_(joiner) {
@@ -112,14 +112,14 @@ AutoThread::~AutoThread() {
DCHECK(!startup_data_);
// Wait for the thread to exit.
- if (thread_) {
+ if (!thread_.is_null()) {
base::PlatformThread::Join(thread_);
}
}
scoped_refptr<AutoThreadTaskRunner> AutoThread::StartWithType(
base::MessageLoop::Type type) {
- DCHECK(!thread_);
+ DCHECK(thread_.is_null());
#if defined(OS_WIN)
DCHECK(com_init_type_ != COM_INIT_STA || type == base::MessageLoop::TYPE_UI);
#endif