Ensure Cocoa sets up its multithreaded environment
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1476 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
@ -83,6 +83,7 @@
|
||||
7BD8F4D50E65B55000034DE9 /* scoped_ptr_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BD8F4CF0E65B4A900034DE9 /* scoped_ptr_unittest.cc */; };
|
||||
7BD8F6D30E65DB0200034DE9 /* bzip2_error_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BD8F6D20E65DB0200034DE9 /* bzip2_error_handler.cc */; };
|
||||
7BD8F7740E65E89800034DE9 /* string16.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BD8F7730E65E89800034DE9 /* string16.cc */; };
|
||||
7BF164F30E660CA500AA999E /* platform_thread_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7BF164F20E660CA500AA999E /* platform_thread_mac.mm */; };
|
||||
820EB4F70E3A613F009668FC /* string_piece.cc in Sources */ = {isa = PBXBuildFile; fileRef = 820EB4F50E3A613F009668FC /* string_piece.cc */; };
|
||||
820EB4FA0E3A6178009668FC /* string_util_icu.cc in Sources */ = {isa = PBXBuildFile; fileRef = 820EB4F90E3A6178009668FC /* string_util_icu.cc */; };
|
||||
820EB5020E3A618B009668FC /* tracked.cc in Sources */ = {isa = PBXBuildFile; fileRef = 820EB4FE0E3A618B009668FC /* tracked.cc */; };
|
||||
@ -360,6 +361,7 @@
|
||||
7BED30C70E59F63000A747DB /* staticlib.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = staticlib.xcconfig; sourceTree = "<group>"; };
|
||||
7BEFC29C0D99832D000829AD /* lock_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lock_impl.h; sourceTree = "<group>"; };
|
||||
7BEFC29D0D99832D000829AD /* lock_impl_posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lock_impl_posix.cc; sourceTree = "<group>"; };
|
||||
7BF164F20E660CA500AA999E /* platform_thread_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = platform_thread_mac.mm; sourceTree = "<group>"; };
|
||||
820EB4EB0E3A60FE009668FC /* idle_timer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = idle_timer.cc; sourceTree = "<group>"; };
|
||||
820EB4EC0E3A60FE009668FC /* idle_timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = idle_timer.h; sourceTree = "<group>"; };
|
||||
820EB4EF0E3A610A009668FC /* linked_ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linked_ptr.h; sourceTree = "<group>"; };
|
||||
@ -790,6 +792,7 @@
|
||||
A5CB82960E5C74E300FD6825 /* platform_test.h */,
|
||||
A5CB82970E5C74E300FD6825 /* platform_test_mac.mm */,
|
||||
82E23FCB0D9C219600F8B40A /* platform_thread.h */,
|
||||
7BF164F20E660CA500AA999E /* platform_thread_mac.mm */,
|
||||
93E703160E5D63E00046259B /* platform_thread_posix.cc */,
|
||||
825403400D92D2210006B936 /* port.h */,
|
||||
E4AFA4B40E50D8B000201347 /* pr_time_unittest.cc */,
|
||||
@ -1188,6 +1191,7 @@
|
||||
93611ADF0E5A7FC500F9405D /* message_pump_default.cc in Sources */,
|
||||
ABF4B9B50DC2BC9F00A6E319 /* path_service.cc in Sources */,
|
||||
824654A60DC25CD7007C2BAA /* pickle.cc in Sources */,
|
||||
7BF164F30E660CA500AA999E /* platform_thread_mac.mm in Sources */,
|
||||
93E703170E5D63E00046259B /* platform_thread_posix.cc in Sources */,
|
||||
7BD8F4A10E65AA4600034DE9 /* process_util_posix.cc in Sources */,
|
||||
824654DF0DC26521007C2BAA /* prtime.cc in Sources */,
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "base/condition_variable.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/platform_test.h"
|
||||
#include "base/platform_thread.h"
|
||||
#include "base/scoped_ptr.h"
|
||||
#include "base/spin_wait.h"
|
||||
@ -20,7 +21,7 @@ namespace {
|
||||
// Define our test class, with several common variables.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class ConditionVariableTest : public testing::Test {
|
||||
class ConditionVariableTest : public PlatformTest {
|
||||
public:
|
||||
const TimeDelta kZeroMs;
|
||||
const TimeDelta kTenMs;
|
||||
|
48
base/platform_thread_mac.mm
Normal file
48
base/platform_thread_mac.mm
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2006-2008 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/platform_thread.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
|
||||
// A simple class that demonstrates our impressive ability to do nothing.
|
||||
@interface NoOp : NSObject
|
||||
|
||||
// Does the deed. Or does it?
|
||||
+ (void)noOp;
|
||||
|
||||
@end
|
||||
|
||||
@implementation NoOp
|
||||
|
||||
+ (void)noOp {
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace base {
|
||||
|
||||
// If Cocoa is to be used on more than one thread, it must know that the
|
||||
// application is multithreaded. Since it's possible to enter Cocoa code
|
||||
// from threads created by pthread_thread_create, Cocoa won't necessarily
|
||||
// be aware that the application is multithreaded. Spawning an NSThread is
|
||||
// enough to get Cocoa to set up for multithreaded operation, so this is done
|
||||
// if necessary before pthread_thread_create spawns any threads.
|
||||
//
|
||||
// http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/chapter_4_section_4.html
|
||||
void InitThreading() {
|
||||
static BOOL multithreaded = [NSThread isMultiThreaded];
|
||||
if (!multithreaded) {
|
||||
[NSThread detachNewThreadSelector:@selector(noOp)
|
||||
toTarget:[NoOp class]
|
||||
withObject:nil];
|
||||
multithreaded = YES;
|
||||
|
||||
DCHECK([NSThread isMultiThreaded]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace base
|
@ -14,6 +14,12 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
namespace base {
|
||||
void InitThreading();
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
static void* ThreadFunc(void* closure) {
|
||||
PlatformThread::Delegate* delegate =
|
||||
static_cast<PlatformThread::Delegate*>(closure);
|
||||
@ -65,18 +71,22 @@ void PlatformThread::SetName(const char* name) {
|
||||
// static
|
||||
bool PlatformThread::Create(size_t stack_size, Delegate* delegate,
|
||||
PlatformThreadHandle* thread_handle) {
|
||||
#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 we don't need to specify any special
|
||||
// attributes to be able to call pthread_join later.
|
||||
|
||||
|
||||
if (stack_size > 0)
|
||||
pthread_attr_setstacksize(&attributes, stack_size);
|
||||
|
||||
success = !pthread_create(thread_handle, &attributes, ThreadFunc, delegate);
|
||||
|
||||
|
||||
pthread_attr_destroy(&attributes);
|
||||
return success;
|
||||
}
|
||||
@ -85,4 +95,3 @@ bool PlatformThread::Create(size_t stack_size, Delegate* delegate,
|
||||
void PlatformThread::Join(PlatformThreadHandle thread_handle) {
|
||||
pthread_join(thread_handle, NULL);
|
||||
}
|
||||
|
||||
|
@ -4,12 +4,15 @@
|
||||
|
||||
#include "base/lock.h"
|
||||
#include "base/message_loop.h"
|
||||
#include "base/platform_test.h"
|
||||
#include "base/string_util.h"
|
||||
#include "base/thread.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
using base::Thread;
|
||||
|
||||
typedef PlatformTest ThreadTest;
|
||||
|
||||
namespace {
|
||||
|
||||
class ToggleValue : public Task {
|
||||
@ -36,7 +39,7 @@ class SleepSome : public Task {
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(ThreadTest, Restart) {
|
||||
TEST_F(ThreadTest, Restart) {
|
||||
Thread a("Restart");
|
||||
a.Stop();
|
||||
EXPECT_FALSE(a.message_loop());
|
||||
@ -52,7 +55,7 @@ TEST(ThreadTest, Restart) {
|
||||
EXPECT_FALSE(a.message_loop());
|
||||
}
|
||||
|
||||
TEST(ThreadTest, StartWithOptions_StackSize) {
|
||||
TEST_F(ThreadTest, StartWithOptions_StackSize) {
|
||||
Thread a("StartWithStackSize");
|
||||
// Ensure that the thread can work with only 12 kb and still process a
|
||||
// message.
|
||||
@ -73,7 +76,7 @@ TEST(ThreadTest, StartWithOptions_StackSize) {
|
||||
EXPECT_TRUE(was_invoked);
|
||||
}
|
||||
|
||||
TEST(ThreadTest, TwoTasks) {
|
||||
TEST_F(ThreadTest, TwoTasks) {
|
||||
bool was_invoked = false;
|
||||
{
|
||||
Thread a("TwoTasks");
|
||||
@ -89,7 +92,7 @@ TEST(ThreadTest, TwoTasks) {
|
||||
EXPECT_TRUE(was_invoked);
|
||||
}
|
||||
|
||||
TEST(ThreadTest, StopSoon) {
|
||||
TEST_F(ThreadTest, StopSoon) {
|
||||
Thread a("StopSoon");
|
||||
EXPECT_TRUE(a.Start());
|
||||
EXPECT_TRUE(a.message_loop());
|
||||
@ -99,9 +102,8 @@ TEST(ThreadTest, StopSoon) {
|
||||
EXPECT_FALSE(a.message_loop());
|
||||
}
|
||||
|
||||
TEST(ThreadTest, ThreadName) {
|
||||
TEST_F(ThreadTest, ThreadName) {
|
||||
Thread a("ThreadName");
|
||||
EXPECT_TRUE(a.Start());
|
||||
EXPECT_EQ("ThreadName", a.thread_name());
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user