Changeset 247914 in webkit
- Timestamp:
- Jul 29, 2019 12:12:40 PM (5 years ago)
- Location:
- trunk/Source/WebKit
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r247908 r247914 1 2019-07-29 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 UI process occasionally hangs in -[UIKeyboardTaskQueue lockWhenReadyForMainThread] 4 https://bugs.webkit.org/show_bug.cgi?id=200215 5 <rdar://problem/52976965> 6 7 Reviewed by Tim Horton. 8 9 To implement autocorrection on iOS, UIKit sometimes needs to request contextual information from WebKit. This is 10 handled as a sync IPC message in WebKit, since UIKit would otherwise proceed to block the main thread after 11 sending the request, preventing WebKit from handling any IPC responses in the UI process (potentially resulting 12 in deadlock if any other sync IPC messages were to arrive in the UI process during this time). 13 14 The synchronous nature of this autocorrection request means that if any sync IPC message were to be 15 simultaneously dispatched in the opposite direction (i.e. web to UI process), we need to immediately handle the 16 incoming sync message in the UI process (otherwise, we'd end up deadlocking for 1 second until the 17 autocorrection context request hits a 1-second IPC timeout). 18 19 One such synchronous message from the web process to the UI process is WebPageProxy::CreateNewPage, triggered as 20 a result of synchronously opening a new window. Due to Safari changes in iOS 13 (<rdar://problem/51755088>), 21 this message now calls into code which then causes UIKit to call *back into* -[WKContentView 22 requestAutocorrectionContextWithCompletionHandler:] for the newly opened web view, under the scope of the call 23 to -requestAutocorrectionContextWithCompletionHandler: in the original web view. 24 25 This caused a crash, which was tracked in <rdar://problem/52590170>. There was an attempt to fix this in r247345 26 by invoking the existing handler well before storing the new one; while this avoided the crash, it didn't solve 27 the root problem, which was that keyboard task queues would get into a bad state after this scenario; this would 28 manifest in a UI process hang under -[UIKeyboardTaskQueue lockWhenReadyForMainThread] during the next user 29 gesture, which is tracked by this bug (<rdar://problem/52976965>). 30 31 As it turns out, the keyboard task queue gets into a bad state because it is architected in such a way that 32 tasks added to the queue under the scope of parent task must be finished executing before their parents; 33 otherwise, the call to -[UIKeyboardTaskExecutionContext returnExecutionToParentWithInfo:] never happens when 34 handling the child task. This has the effect of causing the keyboard task queue to end up with a 35 UIKeyboardTaskExecutionContext that can never return execution to its parent context, such that if the task 36 queue is then told to wait until any future task is finished executing, it will hang forever, waiting for these 37 stuck tasks to finish executing (which never happens, because they're all waiting to return execution to their 38 parents which are already done executing!) 39 40 To fix this hang and avoid ever getting into this bad state, we need to invoke the autocorrection request 41 handlers in this order: 42 43 (1) Receive outer autocorrection context request. 44 (2) Receive inner autocorrection context request. 45 (3) Invoke inner autocorrection context request completion handler. 46 (4) Invoke outer autocorrection context request completion handler. 47 48 ...instead of swapping (3) and (4), like we do currently. 49 50 * UIProcess/ios/WKContentViewInteraction.mm: 51 (-[WKContentView resignFirstResponderForWebView]): 52 53 Remove the hack added in r247345 to try and avoid reentrant autocorrection context requests; we don't need this 54 anymore, since we should now be able to handle these reentrant requests in the way UIKit expects. 55 56 (-[WKContentView requestAutocorrectionContextWithCompletionHandler:]): 57 58 Add an early return in the case where the request is synchronous and there's already a pending autocorrection 59 context to ensure that the completion handler for the nested request is invoked before the outer request is 60 finished. 61 1 62 2019-07-29 Youenn Fablet <youenn@apple.com> 2 63 -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
r247875 r247914 1262 1262 1263 1263 [self endEditingAndUpdateFocusAppearanceWithReason:EndEditingReasonResigningFirstResponder]; 1264 [self _cancelPendingAutocorrectionContextHandler];1265 1264 1266 1265 // If the user explicitly dismissed the keyboard then we will lose first responder … … 3895 3894 const bool useSyncRequest = true; 3896 3895 3897 [self _cancelPendingAutocorrectionContextHandler]; 3896 if (useSyncRequest && _pendingAutocorrectionContextHandler) { 3897 completionHandler(WKAutocorrectionContext.emptyAutocorrectionContext); 3898 return; 3899 } 3898 3900 3899 3901 _pendingAutocorrectionContextHandler = completionHandler;
Note: See TracChangeset
for help on using the changeset viewer.