WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
172362
Make sure implementation of InitializeWebKit2() always run on the main thread
https://bugs.webkit.org/show_bug.cgi?id=172362
Summary
Make sure implementation of InitializeWebKit2() always run on the main thread
Chris Dumez
Reported
2017-05-19 09:41:33 PDT
Make sure implementation of InitializeWebKit2() always run on the main thread as it is not safe to run it on any other thread (see <
rdar://problem/32280185
>).
Attachments
Patch
(9.71 KB, patch)
2017-05-19 10:06 PDT
,
Chris Dumez
no flags
Details
Formatted Diff
Diff
View All
Add attachment
proposed patch, testcase, etc.
Radar WebKit Bug Importer
Comment 1
2017-05-19 09:42:03 PDT
<
rdar://problem/32295678
>
Chris Dumez
Comment 2
2017-05-19 10:06:46 PDT
Created
attachment 310670
[details]
Patch
Chris Dumez
Comment 3
2017-05-19 10:07:39 PDT
I have verified locally that <
rdar://problem/32280185
> no longer reproduces with this patch, even though the client is using the API on a background thread.
Geoffrey Garen
Comment 4
2017-05-19 10:40:20 PDT
Comment on
attachment 310670
[details]
Patch I think this is a fine work-around for the threading problems we've discovered in Safari. In the long run, I think we need to remove this design. Instead of wallpapering over threading problems, since this is a main-thread-only API, we should ASSERT that it's only invoked on the main thread, and fix the cases where that's not true.
Chris Dumez
Comment 5
2017-05-19 11:16:45 PDT
(In reply to Geoffrey Garen from
comment #4
)
> Comment on
attachment 310670
[details]
> Patch > > I think this is a fine work-around for the threading problems we've > discovered in Safari. > > In the long run, I think we need to remove this design. Instead of > wallpapering over threading problems, since this is a main-thread-only API, > we should ASSERT that it's only invoked on the main thread, and fix the > cases where that's not true.
Understood, we should try and ASSERT later once we've fixed API usage on non-main thread on client side.
WebKit Commit Bot
Comment 6
2017-05-19 11:44:17 PDT
Comment on
attachment 310670
[details]
Patch Clearing flags on attachment: 310670 Committed
r217137
: <
http://trac.webkit.org/changeset/217137
>
WebKit Commit Bot
Comment 7
2017-05-19 11:44:19 PDT
All reviewed patches have been landed. Closing bug.
Darin Adler
Comment 8
2017-05-19 14:47:31 PDT
(In reply to Chris Dumez from
comment #5
)
> Understood, we should try and ASSERT later once we've fixed API usage on > non-main thread on client side.
In the past for Objective-C APIs we made a linked on or after check. If the call was from code linked with a new enough version of WebKit, we threw an Objective-C exception if the API was called on the wrong thread. That worked well.
Csaba Osztrogonác
Comment 9
2017-05-22 03:40:47 PDT
(In reply to WebKit Commit Bot from
comment #6
)
> Comment on
attachment 310670
[details]
> Patch > > Clearing flags on attachment: 310670 > > Committed
r217137
: <
http://trac.webkit.org/changeset/217137
>
FYI, it broke the Apple Mac cmake build, because you missed to add the new file to the build system: Undefined symbols for architecture x86_64: "WebKit::InitializeWebKit2()", referenced from: API::Object::Object() in APIObject.cpp.o WebKit::WebProcessPool::create(API::ProcessPoolConfiguration&) in WebProcessPool.cpp.o API::WebsiteDataStore::defaultDataStore() in APIWebsiteDataStore.cpp.o -[WKWebViewConfiguration init] in WKWebViewConfiguration.mm.o -[_WKUserStyleSheet initWithSource:forMainFrameOnly:] in _WKUserStyleSheet.mm.o -[_WKUserStyleSheet initWithSource:forMainFrameOnly:legacyWhitelist:legacyBlacklist:userContentWorld:] in _WKUserStyleSheet.mm.o -[_WKUserStyleSheet initWithSource:forMainFrameOnly:legacyWhitelist:legacyBlacklist:baseURL:userContentWorld:] in _WKUserStyleSheet.mm.o ... ld: symbol(s) not found for architecture x86_64
Csaba Osztrogonác
Comment 10
2017-05-26 02:51:18 PDT
fix landed in
https://trac.webkit.org/changeset/217484/webkit
Rob Phillips
Comment 11
2020-04-24 13:43:24 PDT
Hi everybody - this bug fix has caused a dead lock race condition in ad frameworks (all being init'ed at the same time) that use WebKit to check user agent strings in the same way. This started happening for us in iOS 13.4.x but likely has been around a while. A dead lock happens under this scenario: - Both Frameworks A and B are initialized on a background queue in a serial order - Framework A creates a WKWebView on the background queue without dispatching back to main thread first - Framework B dispatches onto main thread from the background queue to create a WKWebView as well - Both Framework A and B are now stuck in InitializeWebKit2() - Within InitializeWebKit2(), Framework A's dispatch_sync is waiting on the main thread to be available so it can - Within InitializeWebKit2(), Framework B hangs the main thread while waiting for the std::call_once to finish (the same std::call_once used in Framework A's initialization) See:
https://github.com/WebKit/webkit/blob/master/Source/WebKit/Shared/Cocoa/WebKit2InitializeCocoa.mm#L71
Please advise on whether this can be changed back to just asserting since web views should just assert if they are init'ed on anything but the main thread. From this bug report, it appears this just worked around a Safari bug a few years ago. This advice from the comments below is sound:
>In the long run, I think we need to remove this design. Instead of wallpapering over threading problems, since this is a main-thread-only API, we should ASSERT that it's only invoked on the main thread, and fix the cases where that's not true.
Thanks!
Chris Dumez
Comment 12
2020-04-24 13:47:31 PDT
(In reply to Rob Phillips from
comment #11
)
> Hi everybody - this bug fix has caused a dead lock race condition in ad > frameworks (all being init'ed at the same time) that use WebKit to check > user agent strings in the same way. This started happening for us in iOS > 13.4.x but likely has been around a while. > > A dead lock happens under this scenario: > > - Both Frameworks A and B are initialized on a background queue in a serial > order > - Framework A creates a WKWebView on the background queue without > dispatching back to main thread first
That's a bug and should be fixed in the framework.
> - Framework B dispatches onto main thread from the background queue to > create a WKWebView as well > - Both Framework A and B are now stuck in InitializeWebKit2() > - Within InitializeWebKit2(), Framework A's dispatch_sync is waiting on the > main thread to be available so it can > - Within InitializeWebKit2(), Framework B hangs the main thread while > waiting for the std::call_once to finish (the same std::call_once used in > Framework A's initialization) > > See: > >
https://github.com/WebKit/webkit/blob/master/Source/WebKit/Shared/Cocoa/
> WebKit2InitializeCocoa.mm#L71 > > Please advise on whether this can be changed back to just asserting since > web views should just assert if they are init'ed on anything but the main > thread. From this bug report, it appears this just worked around a Safari > bug a few years ago. > > This advice from the comments below is sound: > >In the long run, I think we need to remove this design. Instead of wallpapering over threading problems, since this is a main-thread-only API, we should ASSERT that it's only invoked on the main thread, and fix the cases where that's not true. > > Thanks!
Rob Phillips
Comment 13
2020-04-24 14:10:27 PDT
Agreed re: it being an ad framework bug; but it's also a bug in WebKit. Instead of asserting (which is what a lot of UIKit does now) which would allow for a proper stack trace and crash report, we instead get a dead lock / watchdog kill which we can't know about or debug unless customers send us crash reports from their device. The proper thing to do here would be to assert in InitializeWebKit2() if not called from the main thread
Darin Adler
Comment 14
2020-04-24 16:13:54 PDT
(In reply to Rob Phillips from
comment #13
)
> The proper thing to do here would be to assert in InitializeWebKit2() if not > called from the main thread
An interesting claim!
Chris Dumez
Comment 15
2020-04-24 16:17:26 PDT
(In reply to Darin Adler from
comment #14
)
> (In reply to Rob Phillips from
comment #13
) > > The proper thing to do here would be to assert in InitializeWebKit2() if not > > called from the main thread > > An interesting claim!
We may be able to get away with it if we do it behind a linked-on-after check so that only apps that get rebuilt against the latest SDK would get the new behavior (CRASH if InitializeWebKit2() is called from non main thread).
Darin Adler
Comment 16
2020-04-24 16:25:30 PDT
Sure. That’s what the WebCore ThreadCheck.h header is about. WebCoreThreadViolationCheckRoundOne WebCoreThreadViolationCheckRoundTwo WebCoreThreadViolationCheckRoundThree
Rob Phillips
Comment 17
2020-04-25 13:09:49 PDT
(In reply to Darin Adler from
comment #14
)
> (In reply to Rob Phillips from
comment #13
) > > The proper thing to do here would be to assert in InitializeWebKit2() if not > > called from the main thread > > An interesting claim!
😄Apologies, my *preference would be. Either way, thanks for the consideration folks. I'm patching around the ad frameworks we're using for now
Yusuke Suzuki
Comment 18
2020-04-25 14:08:08 PDT
This can be a dead lock if the main thread is waiting for the initialization of WebKit done in the different thread, is my understanding correct? 1. The main thread dispatches a task in a A thread and waiting for the result from that thread at some point. 2. A thread calls WebKit APIs 3. A thread posts a task to the main thread to initialize WebKit 4. dead lock
Yusuke Suzuki
Comment 19
2020-04-25 14:15:52 PDT
(In reply to Yusuke Suzuki from
comment #18
)
> This can be a dead lock if the main thread is waiting for the initialization > of WebKit done in the different thread, is my understanding correct? > > 1. The main thread dispatches a task in a A thread and waiting for the > result from that thread at some point. > 2. A thread calls WebKit APIs > 3. A thread posts a task to the main thread to initialize WebKit > 4. dead lock
Ah, I was just looking at the patch, and not looking at @Rob's comment!
Chris Dumez
Comment 20
2020-05-22 15:29:23 PDT
(In reply to Chris Dumez from
comment #15
)
> (In reply to Darin Adler from
comment #14
) > > (In reply to Rob Phillips from
comment #13
) > > > The proper thing to do here would be to assert in InitializeWebKit2() if not > > > called from the main thread > > > > An interesting claim! > > We may be able to get away with it if we do it behind a linked-on-after > check so that only apps that get rebuilt against the latest SDK would get > the new behavior (CRASH if InitializeWebKit2() is called from non main > thread).
Doing so in
Bug 212283
.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug