0

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:
mmentovai@google.com
2008-08-28 01:17:02 +00:00
parent 4d5e036157
commit 6e683db29d
5 changed files with 74 additions and 10 deletions

@ -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;

@ -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());
}