|
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
|
2 // Use of this source code is governed by a BSD-style license that can be |
|
3 // found in the LICENSE file. |
|
4 |
|
5 #include "base/platform_thread.h" |
|
6 |
|
7 #import <Foundation/Foundation.h> |
|
8 #include <dlfcn.h> |
|
9 |
|
10 #include "base/logging.h" |
|
11 #include "base/scoped_nsautorelease_pool.h" |
|
12 |
|
13 // A simple class that demonstrates our impressive ability to do nothing. |
|
14 @interface NoOp : NSObject |
|
15 |
|
16 // Does the deed. Or does it? |
|
17 + (void)noOp; |
|
18 |
|
19 @end |
|
20 |
|
21 @implementation NoOp |
|
22 |
|
23 + (void)noOp { |
|
24 } |
|
25 |
|
26 @end |
|
27 |
|
28 namespace base { |
|
29 |
|
30 // If Cocoa is to be used on more than one thread, it must know that the |
|
31 // application is multithreaded. Since it's possible to enter Cocoa code |
|
32 // from threads created by pthread_thread_create, Cocoa won't necessarily |
|
33 // be aware that the application is multithreaded. Spawning an NSThread is |
|
34 // enough to get Cocoa to set up for multithreaded operation, so this is done |
|
35 // if necessary before pthread_thread_create spawns any threads. |
|
36 // |
|
37 // http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/chapter_4_section_4.html |
|
38 void InitThreading() { |
|
39 // this is called early in startup, before the event loop, so provide |
|
40 // an autorelease pool to prevent leaks here |
|
41 ScopedNSAutoreleasePool pool; |
|
42 |
|
43 static BOOL multithreaded = [NSThread isMultiThreaded]; |
|
44 if (!multithreaded) { |
|
45 [NSThread detachNewThreadSelector:@selector(noOp) |
|
46 toTarget:[NoOp class] |
|
47 withObject:nil]; |
|
48 multithreaded = YES; |
|
49 |
|
50 DCHECK([NSThread isMultiThreaded]); |
|
51 } |
|
52 } |
|
53 |
|
54 } // namespace base |
|
55 |
|
56 // static |
|
57 void PlatformThread::SetName(const char* name) { |
|
58 // pthread_setname_np is only available in 10.6 or later, so test |
|
59 // for it at runtime. |
|
60 int (*dynamic_pthread_setname_np)(const char*); |
|
61 *reinterpret_cast<void**>(&dynamic_pthread_setname_np) = |
|
62 dlsym(RTLD_DEFAULT, "pthread_setname_np"); |
|
63 if (!dynamic_pthread_setname_np) |
|
64 return; |
|
65 |
|
66 // Mac OS X does not expose the length limit of the name, so |
|
67 // hardcode it. |
|
68 const int kMaxNameLength = 63; |
|
69 std::string shortened_name = std::string(name).substr(0, kMaxNameLength); |
|
70 // pthread_setname() fails (harmlessly) in the sandbox, ignore when it does. |
|
71 // See http://crbug.com/47058 |
|
72 |
|
73 // The name parameter is copied thus it's safe to release it after calling. |
|
74 // Checked against the bionic implementation in bionic/libc/bionic/pthread.c |
|
75 dynamic_pthread_setname_np(shortened_name.c_str()); |
|
76 } |
|
77 |