WTF::callOnMainThread should not require the main runloop to be initialized
authortzagallo@apple.com <tzagallo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jun 2020 19:38:13 +0000 (19:38 +0000)
committertzagallo@apple.com <tzagallo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jun 2020 19:38:13 +0000 (19:38 +0000)
https://bugs.webkit.org/show_bug.cgi?id=213612
<rdar://problem/64446028>

Reviewed by Yusuke Suzuki.

When using JavaScriptCore as a framework, the WTF main runloop is never initialized. However,
the inspector uses CFString wrappers, which use `callOnMainThread` when deallocating the
underlying string. For now, we bring back the old `JSWTFMainThreadCaller` to ensure we have
a way of dispatching to the main thread, even when the main runloop hasn't been initialized.

* wtf/RunLoop.cpp:
(WTF::RunLoop::mainIfExists):
* wtf/RunLoop.h:
* wtf/cocoa/MainThreadCocoa.mm:
(-[JSWTFMainThreadCaller call]):
(WTF::initializeMainThreadPlatform):
(WTF::scheduleDispatchFunctionsOnMainThread):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@263524 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WTF/ChangeLog
Source/WTF/wtf/RunLoop.cpp
Source/WTF/wtf/RunLoop.h
Source/WTF/wtf/cocoa/MainThreadCocoa.mm

index dd5f3ce..43130b0 100644 (file)
@@ -1,3 +1,24 @@
+2020-06-25  Tadeu Zagallo  <tzagallo@apple.com>
+
+        WTF::callOnMainThread should not require the main runloop to be initialized
+        https://bugs.webkit.org/show_bug.cgi?id=213612
+        <rdar://problem/64446028>
+
+        Reviewed by Yusuke Suzuki.
+
+        When using JavaScriptCore as a framework, the WTF main runloop is never initialized. However,
+        the inspector uses CFString wrappers, which use `callOnMainThread` when deallocating the
+        underlying string. For now, we bring back the old `JSWTFMainThreadCaller` to ensure we have
+        a way of dispatching to the main thread, even when the main runloop hasn't been initialized.
+
+        * wtf/RunLoop.cpp:
+        (WTF::RunLoop::mainIfExists):
+        * wtf/RunLoop.h:
+        * wtf/cocoa/MainThreadCocoa.mm:
+        (-[JSWTFMainThreadCaller call]):
+        (WTF::initializeMainThreadPlatform):
+        (WTF::scheduleDispatchFunctionsOnMainThread):
+
 2020-06-24  Umar Iqbal  <uiqbal@apple.com>
 
         We should resurrect the older patch that collects some statistics of web API calls
index c3cbece..fb4b29b 100644 (file)
@@ -57,6 +57,7 @@ void RunLoop::initializeMain()
     if (s_mainRunLoop)
         return;
     initializeMainThread();
+    WTF::storeStoreFence();
     s_mainRunLoop = &RunLoop::current();
 }
 
@@ -72,6 +73,11 @@ RunLoop& RunLoop::main()
     return *s_mainRunLoop;
 }
 
+RunLoop* RunLoop::mainIfExists()
+{
+    return s_mainRunLoop;
+}
+
 #if USE(WEB_THREAD)
 void RunLoop::initializeWeb()
 {
index d1b43ba..cdde1ff 100644 (file)
@@ -67,6 +67,7 @@ public:
 
     WTF_EXPORT_PRIVATE static RunLoop& current();
     WTF_EXPORT_PRIVATE static RunLoop& main();
+    WTF_EXPORT_PRIVATE static RunLoop* mainIfExists();
 #if USE(WEB_THREAD)
     WTF_EXPORT_PRIVATE static RunLoop& web();
     WTF_EXPORT_PRIVATE static RunLoop* webIfExists();
index faaf530..93916b8 100644 (file)
 #import <wtf/ios/WebCoreThread.h>
 #endif
 
+@interface JSWTFMainThreadCaller : NSObject
+- (void)call;
+@end
+
+@implementation JSWTFMainThreadCaller
+
+- (void)call
+{
+    WTF::dispatchFunctionsFromMainThread();
+}
+
+@end
+
 #define LOG_CHANNEL_PREFIX Log
 
 namespace WTF {
@@ -54,6 +67,8 @@ WTFLogChannel LogThreading = { WTFLogChannelState::On, "Threading", WTFLogLevel:
 WTFLogChannel LogThreading = { WTFLogChannelState::On, "Threading", WTFLogLevel::Error, LOG_CHANNEL_WEBKIT_SUBSYSTEM, OS_LOG_DEFAULT };
 #endif
 
+static JSWTFMainThreadCaller* staticMainThreadCaller;
+
 #if USE(WEB_THREAD)
 // When the Web thread is enabled, we consider it to be the main thread, not pthread main.
 static pthread_t s_webThreadPthread;
@@ -67,6 +82,9 @@ void initializeMainThreadPlatform()
     if (!pthread_main_np())
         RELEASE_LOG_FAULT(Threading, "WebKit Threading Violation - initial use of WebKit from a secondary thread.");
     ASSERT(pthread_main_np());
+
+    ASSERT(!staticMainThreadCaller);
+    staticMainThreadCaller = [[JSWTFMainThreadCaller alloc] init];
 }
 
 void scheduleDispatchFunctionsOnMainThread()
@@ -78,7 +96,12 @@ void scheduleDispatchFunctionsOnMainThread()
     }
 #endif
 
-    RunLoop::main().dispatch(dispatchFunctionsFromMainThread);
+    if (RunLoop::mainIfExists()) {
+        RunLoop::main().dispatch(dispatchFunctionsFromMainThread);
+        return;
+    }
+
+    [staticMainThreadCaller performSelectorOnMainThread:@selector(call) withObject:nil waitUntilDone:NO];
 }
 
 void dispatchAsyncOnMainThreadWithWebThreadLockIfNeeded(void (^block)())