2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #import "MainThread.h"
32 #import <CoreFoundation/CoreFoundation.h>
33 #import <Foundation/NSThread.h>
35 #import <wtf/Assertions.h>
36 #import <wtf/HashSet.h>
37 #import <wtf/Threading.h>
38 #import <wtf/ThreadSpecific.h>
40 @interface JSWTFMainThreadCaller : NSObject {
45 @implementation JSWTFMainThreadCaller
49 WTF::dispatchFunctionsFromMainThread();
52 @end // implementation JSWTFMainThreadCaller
56 static JSWTFMainThreadCaller* staticMainThreadCaller;
57 static bool isTimerPosted; // This is only accessed on the 'main' thread.
58 static bool mainThreadEstablishedAsPthreadMain;
59 static pthread_t mainThreadPthread;
60 static NSThread* mainThreadNSThread;
62 #if ENABLE(PARALLEL_GC)
63 static ThreadSpecific<bool>* isGCThread;
65 static void initializeGCThreads()
67 isGCThread = new ThreadSpecific<bool>();
70 static void initializeGCThreads() { }
73 void initializeMainThreadPlatform()
75 ASSERT(!staticMainThreadCaller);
76 staticMainThreadCaller = [[JSWTFMainThreadCaller alloc] init];
78 mainThreadEstablishedAsPthreadMain = false;
79 mainThreadPthread = pthread_self();
80 mainThreadNSThread = [[NSThread currentThread] retain];
82 initializeGCThreads();
85 void initializeMainThreadToProcessMainThreadPlatform()
87 if (!pthread_main_np())
88 NSLog(@"WebKit Threading Violation - initial use of WebKit from a secondary thread.");
90 ASSERT(!staticMainThreadCaller);
91 staticMainThreadCaller = [[JSWTFMainThreadCaller alloc] init];
93 mainThreadEstablishedAsPthreadMain = true;
94 mainThreadPthread = 0;
95 mainThreadNSThread = nil;
97 initializeGCThreads();
100 static void timerFired(CFRunLoopTimerRef timer, void*)
103 isTimerPosted = false;
104 WTF::dispatchFunctionsFromMainThread();
107 static void postTimer()
109 ASSERT(isMainThread());
114 isTimerPosted = true;
115 CFRunLoopAddTimer(CFRunLoopGetCurrent(), CFRunLoopTimerCreate(0, 0, 0, 0, 0, timerFired, 0), kCFRunLoopCommonModes);
118 void scheduleDispatchFunctionsOnMainThread()
120 ASSERT(staticMainThreadCaller);
122 if (isMainThread()) {
127 if (mainThreadEstablishedAsPthreadMain) {
128 ASSERT(!mainThreadNSThread);
129 [staticMainThreadCaller performSelectorOnMainThread:@selector(call) withObject:nil waitUntilDone:NO];
133 ASSERT(mainThreadNSThread);
134 [staticMainThreadCaller performSelector:@selector(call) onThread:mainThreadNSThread withObject:nil waitUntilDone:NO];
139 if (mainThreadEstablishedAsPthreadMain) {
140 ASSERT(!mainThreadPthread);
141 return pthread_main_np();
144 ASSERT(mainThreadPthread);
145 return pthread_equal(pthread_self(), mainThreadPthread);
148 #if ENABLE(PARALLEL_GC)
149 void registerGCThread()
152 // This happens if we're running in a process that doesn't care about
160 bool isMainThreadOrGCThread()
162 if (isGCThread->isSet() && **isGCThread)
165 return isMainThread();
168 // This is necessary because JavaScriptCore.exp doesn't support preprocessor macros.
169 bool isMainThreadOrGCThread()
171 return isMainThread();