X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/fb8617cde5834786bd4e4afd579883e4acf5666e..4e4e5a6f2694187498445a6ac6f1634ce8141119:/wtf/mac/MainThreadMac.mm?ds=sidebyside diff --git a/wtf/mac/MainThreadMac.mm b/wtf/mac/MainThreadMac.mm index 0ddd5f6..aabaafa 100644 --- a/wtf/mac/MainThreadMac.mm +++ b/wtf/mac/MainThreadMac.mm @@ -29,8 +29,11 @@ #import "config.h" #import "MainThread.h" +#import #import +#import #import +#import @interface WTFMainThreadCaller : NSObject { } @@ -48,29 +51,103 @@ namespace WTF { -static WTFMainThreadCaller* staticMainThreadCaller = nil; -#if USE(WEB_THREAD) -static NSThread* webThread = nil; -#endif +static WTFMainThreadCaller* staticMainThreadCaller; +static bool isTimerPosted; // This is only accessed on the 'main' thread. +static bool mainThreadEstablishedAsPthreadMain; +static pthread_t mainThreadPthread; +static NSThread* mainThreadNSThread; void initializeMainThreadPlatform() { +#if !defined(BUILDING_ON_TIGER) ASSERT(!staticMainThreadCaller); staticMainThreadCaller = [[WTFMainThreadCaller alloc] init]; -#if USE(WEB_THREAD) - webThread = [[NSThread currentThread] retain]; + mainThreadEstablishedAsPthreadMain = false; + mainThreadPthread = pthread_self(); + mainThreadNSThread = [[NSThread currentThread] retain]; +#else + ASSERT_NOT_REACHED(); #endif } +void initializeMainThreadToProcessMainThreadPlatform() +{ + if (!pthread_main_np()) + NSLog(@"WebKit Threading Violation - initial use of WebKit from a secondary thread."); + + ASSERT(!staticMainThreadCaller); + staticMainThreadCaller = [[WTFMainThreadCaller alloc] init]; + + mainThreadEstablishedAsPthreadMain = true; + mainThreadPthread = 0; + mainThreadNSThread = nil; +} + +static void timerFired(CFRunLoopTimerRef timer, void*) +{ + CFRelease(timer); + isTimerPosted = false; + WTF::dispatchFunctionsFromMainThread(); +} + +static void postTimer() +{ + ASSERT(isMainThread()); + + if (isTimerPosted) + return; + + isTimerPosted = true; + CFRunLoopAddTimer(CFRunLoopGetCurrent(), CFRunLoopTimerCreate(0, 0, 0, 0, 0, timerFired, 0), kCFRunLoopCommonModes); +} + void scheduleDispatchFunctionsOnMainThread() { ASSERT(staticMainThreadCaller); -#if USE(WEB_THREAD) - [staticMainThreadCaller performSelector:@selector(call) onThread:webThread withObject:nil waitUntilDone:NO]; + + if (isMainThread()) { + postTimer(); + return; + } + + if (mainThreadEstablishedAsPthreadMain) { + ASSERT(!mainThreadNSThread); + [staticMainThreadCaller performSelectorOnMainThread:@selector(call) withObject:nil waitUntilDone:NO]; + return; + } + +#if !defined(BUILDING_ON_TIGER) + ASSERT(mainThreadNSThread); + [staticMainThreadCaller performSelector:@selector(call) onThread:mainThreadNSThread withObject:nil waitUntilDone:NO]; #else - [staticMainThreadCaller performSelectorOnMainThread:@selector(call) withObject:nil waitUntilDone:NO]; + ASSERT_NOT_REACHED(); #endif } +bool isMainThread() +{ + if (mainThreadEstablishedAsPthreadMain) { + ASSERT(!mainThreadPthread); + return pthread_main_np(); + } + +#if !defined(BUILDING_ON_TIGER) + ASSERT(mainThreadPthread); + return pthread_equal(pthread_self(), mainThreadPthread); +#else + ASSERT_NOT_REACHED(); + return false; +#endif +} + +// This function is the same as isMainThread() above except that it does not do +// a ASSERT(mainThreadPthread). This should only be used by code that can get +// invoked when the WebThread hasn't been started. See . +bool isWebThread() +{ + ASSERT(!mainThreadEstablishedAsPthreadMain); + return pthread_equal(pthread_self(), mainThreadPthread); +} + } // namespace WTF