|
|
Created:
4 years, 5 months ago by Changwan Ryu Modified:
4 years, 4 months ago CC:
chromium-reviews, darin-cc_chromium.org, jam, yabinh Base URL:
https://chromium.googlesource.com/chromium/src.git@master Target Ref:
refs/pending/heads/master Project:
chromium Visibility:
Public. |
DescriptionCache proxy view return value to avoid deadlock
If WebView has an active IME but the Android app calls
InputMethodManager#hideSoftInputFromWindow() on a non-UI thread,
then a deadlock may happen.
One example case is when JavaScript triggers it through JavascriptInterface
(therefore, on JavaBridge thread.)
The deadlock scenario is as follows:
1) InputMethodManager#hideSoftFromWindow() calls
ThreadedInputConnectionProxyView#getWindowToken() on JavaBridge thread
while holding InputMethodManager#mH.
Then getWindowToken() waits for UI thread to become available.
2) At almost same time, InputMethodManager#restartInput() was waiting for
InputMethodManager#mH on UI thread
This deadlock can be avoided by caching return values as atomic objects.
Alternative approach I've tried: check the current thread and block
it only when it's IME thread - this may still leave room for deadlock
between IME thread and UI thread.
BUG=630937
Committed: https://crrev.com/43ceb11f9abf67fea18e8a731a9ef61f5cfe22fc
Cr-Commit-Position: refs/heads/master@{#408925}
Patch Set 1 #
Total comments: 3
Patch Set 2 : caching approach #
Total comments: 5
Patch Set 3 : do not set root view on detachment #
Total comments: 2
Patch Set 4 : set to null #Messages
Total messages: 43 (22 generated)
The CQ bit was checked by changwan@chromium.org to run a CQ dry run
changwan@chromium.org changed reviewers: + aelias@chromium.org
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
changwan@chromium.org changed reviewers: + aelias@chromium.org
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
https://codereview.chromium.org/2175263002/diff/1/content/public/android/java... File content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java (right): https://codereview.chromium.org/2175263002/diff/1/content/public/android/java... content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java:138: if (Looper.myLooper() == mImeThreadHandler.getLooper()) { I think it's a bad practice to alter behavior based on current looper, since that's a form of global state. Could we instead change WebView to stop calling ThreadedInputConnectionProxyView directly on JavaBridge thread (for example, with an extra task-post hop)?
https://codereview.chromium.org/2175263002/diff/1/content/public/android/java... File content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java (right): https://codereview.chromium.org/2175263002/diff/1/content/public/android/java... content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java:138: if (Looper.myLooper() == mImeThreadHandler.getLooper()) { On 2016/07/25 22:11:47, aelias wrote: > I think it's a bad practice to alter behavior based on current looper, since > that's a form of global state. Could we instead change WebView to stop calling > ThreadedInputConnectionProxyView directly on JavaBridge thread (for example, > with an extra task-post hop)? We just look up looper in order to check whether the current thread is the IME thread or not. WebView was simply calling IMM#hideSoftInputFromWindow() on JavaBridge thread, which is somewhat awkward but the current practice is that we allow calling this function on non-UI thread. But in that function IMM had to call ThreadedInputConnectionProxyView#getWindowToken() as it's the currently served view. The current logic blocks JavaBridge thread which isn't intended.
https://codereview.chromium.org/2175263002/diff/1/content/public/android/java... File content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java (right): https://codereview.chromium.org/2175263002/diff/1/content/public/android/java... content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java:138: if (Looper.myLooper() == mImeThreadHandler.getLooper()) { Can you change WebView to post a task to IME thread to invoke hideSoftInputFromWindow, and add a thread assertion to hideSoftInputFromWindow? > We just look up looper in order to check whether the current thread is the IME thread or not. I understand, but I still think this is a form of global state and a bad practice to change behavior on.
Description was changed from ========== Block proxy view only when it's from IME thread WebView can access ThreadedInputConnectionProxyView on JavaBridge thread if the underlying JavaScript triggers it. If InputMethodManager#hideSoftKeyboard() was calling TICPV#getWindowToken() on JavaBridge thread while holding InputMethodManager#mH, and InputMethodManager#restartInput() was waiting for InputMethodManager#mH while on UI thread, then there will be a deadlock. This deadlock can be prevented if we rigorously check the current thread and block it only when it's IME thread. BUG=630937 ========== to ========== Block proxy view only when it's from IME thread If WebView has an active IME but the Android app calls InputMethodManager#hideSoftInputFromWindow() on a non-UI thread, then a deadlock may happen. One example case is when JavaScript triggers it through JavascriptInterface (therefore, on JavaBridge thread.) The deadlock scenario is as follows: 1) InputMethodManager#hideSoftFromWindow() calls ThreadedInputConnectionProxyView#getWindowToken() on JavaBridge thread while holding InputMethodManager#mH. 2) At almost same time, InputMethodManager#restartInput() was waiting for InputMethodManager#mH on UI thread We were running ThreadedInputConnectionProxyView's methods on UI thread in case they were triggered by IME thread. But we did not intend to block all the threads while waiting for UI thread to become available. This deadlock can be prevented if we check the current thread and block it only when it's IME thread. BUG=630937 ==========
On 2016/07/26 00:14:43, aelias wrote: > https://codereview.chromium.org/2175263002/diff/1/content/public/android/java... > File > content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java > (right): > > https://codereview.chromium.org/2175263002/diff/1/content/public/android/java... > content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java:138: > if (Looper.myLooper() == mImeThreadHandler.getLooper()) { > Can you change WebView to post a task to IME thread to invoke > hideSoftInputFromWindow, and add a thread assertion to hideSoftInputFromWindow? Unfortunately, no. In this case, Android app (com.google.android.gms.ui) directly calls IMM#hideSoftInputFromWindow, not through us, so we do not have any control here. In this scenario, it was triggered by JavaScript code, but Android app may also call this function on a completely random thread of its own and end up encountering the same problem. I've cleaned up the description of this CL to make it clear. > > > We just look up looper in order to check whether the current thread is the IME > thread or not. > > I understand, but I still think this is a form of global state and a bad > practice to change behavior on. I couldn't think of a better solution here. Please advise.
How about caching a copy of the window token on the proxy view?
On 2016/07/26 00:59:33, aelias wrote: > How about caching a copy of the window token on the proxy view? Hmm... I think getWindowToken() is just one example. InputMethodManager also calls mServedView.hasWindowFocus(), mServedView.isFocused() while holding mH, and this can lead to the same deadlock. Probably we don't want to cache all these functions...
All those examples seem reasonable to cache so far, I think it's worth a try.
The CQ bit was checked by changwan@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
Description was changed from ========== Block proxy view only when it's from IME thread If WebView has an active IME but the Android app calls InputMethodManager#hideSoftInputFromWindow() on a non-UI thread, then a deadlock may happen. One example case is when JavaScript triggers it through JavascriptInterface (therefore, on JavaBridge thread.) The deadlock scenario is as follows: 1) InputMethodManager#hideSoftFromWindow() calls ThreadedInputConnectionProxyView#getWindowToken() on JavaBridge thread while holding InputMethodManager#mH. 2) At almost same time, InputMethodManager#restartInput() was waiting for InputMethodManager#mH on UI thread We were running ThreadedInputConnectionProxyView's methods on UI thread in case they were triggered by IME thread. But we did not intend to block all the threads while waiting for UI thread to become available. This deadlock can be prevented if we check the current thread and block it only when it's IME thread. BUG=630937 ========== to ========== Cache proxy view return value to avoid deadlock If WebView has an active IME but the Android app calls InputMethodManager#hideSoftInputFromWindow() on a non-UI thread, then a deadlock may happen. One example case is when JavaScript triggers it through JavascriptInterface (therefore, on JavaBridge thread.) The deadlock scenario is as follows: 1) InputMethodManager#hideSoftFromWindow() calls ThreadedInputConnectionProxyView#getWindowToken() on JavaBridge thread while holding InputMethodManager#mH. 2) At almost same time, InputMethodManager#restartInput() was waiting for InputMethodManager#mH on UI thread This deadlock can be avoided by caching return values as atomic objects. Alternative approach I've tried: check the current thread and block it only when it's IME thread - this may still leave room for deadlock between IME thread and UI thread. BUG=630937 ==========
On 2016/07/26 01:24:12, aelias wrote: > All those examples seem reasonable to cache so far, I think it's worth a try. Ok, changed to caching as suggested. Could you take another look?
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
aelias@chromium.org changed reviewers: + tedchoc@chromium.org
lgtm, adding tedchoc@ for ContentViewCore OWNERS
https://codereview.chromium.org/2175263002/diff/20001/content/public/android/... File content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java (right): https://codereview.chromium.org/2175263002/diff/20001/content/public/android/... content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java:52: mFocused.set(gainFocus); should these all have thread checks? or does it matter? wondering if we expect this on the UI thread or not. https://codereview.chromium.org/2175263002/diff/20001/content/public/android/... content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java:72: mRootView.set(mContainerView.getRootView()); why do you need to do this? should we be setting the root view to null in this case?
https://codereview.chromium.org/2175263002/diff/20001/content/public/android/... File content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java (right): https://codereview.chromium.org/2175263002/diff/20001/content/public/android/... content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java:52: mFocused.set(gainFocus); On 2016/07/27 00:16:36, Ted C wrote: > should these all have thread checks? or does it matter? wondering if we expect > this on the UI thread or not. As shown in the crbug.com/630937, com.google.android.gms.ui calls IMM#hideSoftInputFromWindow() on JavaBridge thread, so IMM was calling mServedView#getWindowToken() on the same JavaBridge thread, not UI thread (and has been working without error). In general, this view is exposed only to IMM, so I don't think we need thread checks. https://codereview.chromium.org/2175263002/diff/20001/content/public/android/... content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java:72: mRootView.set(mContainerView.getRootView()); On 2016/07/27 00:16:36, Ted C wrote: > why do you need to do this? should we be setting the root view to null in this > case? According to View#getRootView() this should not be null but the root of the view hierarchy even when window is not attached.
Description was changed from ========== Cache proxy view return value to avoid deadlock If WebView has an active IME but the Android app calls InputMethodManager#hideSoftInputFromWindow() on a non-UI thread, then a deadlock may happen. One example case is when JavaScript triggers it through JavascriptInterface (therefore, on JavaBridge thread.) The deadlock scenario is as follows: 1) InputMethodManager#hideSoftFromWindow() calls ThreadedInputConnectionProxyView#getWindowToken() on JavaBridge thread while holding InputMethodManager#mH. 2) At almost same time, InputMethodManager#restartInput() was waiting for InputMethodManager#mH on UI thread This deadlock can be avoided by caching return values as atomic objects. Alternative approach I've tried: check the current thread and block it only when it's IME thread - this may still leave room for deadlock between IME thread and UI thread. BUG=630937 ========== to ========== Cache proxy view return value to avoid deadlock If WebView has an active IME but the Android app calls InputMethodManager#hideSoftInputFromWindow() on a non-UI thread, then a deadlock may happen. One example case is when JavaScript triggers it through JavascriptInterface (therefore, on JavaBridge thread.) The deadlock scenario is as follows: 1) InputMethodManager#hideSoftFromWindow() calls ThreadedInputConnectionProxyView#getWindowToken() on JavaBridge thread while holding InputMethodManager#mH. Then getWindowToken() waits for UI thread to become available. 2) At almost same time, InputMethodManager#restartInput() was waiting for InputMethodManager#mH on UI thread This deadlock can be avoided by caching return values as atomic objects. Alternative approach I've tried: check the current thread and block it only when it's IME thread - this may still leave room for deadlock between IME thread and UI thread. BUG=630937 ==========
https://codereview.chromium.org/2175263002/diff/20001/content/public/android/... File content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java (right): https://codereview.chromium.org/2175263002/diff/20001/content/public/android/... content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java:72: mRootView.set(mContainerView.getRootView()); On 2016/07/27 00:48:45, Changwan Ryu wrote: > On 2016/07/27 00:16:36, Ted C wrote: > > why do you need to do this? should we be setting the root view to null in > this > > case? > > According to View#getRootView() this should not be null but the root of the view > hierarchy even when window is not attached. Umm...where do you see that? There javadoc does not mention that. Looking at the code for getRootView(): https://github.com/android/platform_frameworks_base/blob/master/core/java/and... It returns null if mAttachInfo is null. mAttachInfo is set to null in dispatchDetachedFromWindow. I'm not sure whether mParent is set to null as part of this, but it is called in ViewRootImpls.java code: https://github.com/android/platform_frameworks_base/blob/4535e11fb7010f2b104d... While I'm not convinced you shouldn't be setting this to null, it might be happening by default because the containers root view might be null here and you'd be implicitly setting it to null (but that depends on the ordering of the observers for detaching from the window). If you're assuming this to be non-null, then why do you think the root view will change in the time between attach and detach? Shouldn't it only change in attach? I'm just confused why you'd be needing to update this as it shouldn't ever change unless it were to be attached to a different window.
On 2016/07/27 17:30:20, Ted C wrote: > https://codereview.chromium.org/2175263002/diff/20001/content/public/android/... > File > content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java > (right): > > https://codereview.chromium.org/2175263002/diff/20001/content/public/android/... > content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java:72: > mRootView.set(mContainerView.getRootView()); > On 2016/07/27 00:48:45, Changwan Ryu wrote: > > On 2016/07/27 00:16:36, Ted C wrote: > > > why do you need to do this? should we be setting the root view to null in > > this > > > case? > > > > According to View#getRootView() this should not be null but the root of the > view > > hierarchy even when window is not attached. > > Umm...where do you see that? > > There javadoc does not mention that. > > Looking at the code for getRootView(): > https://github.com/android/platform_frameworks_base/blob/master/core/java/and... > > It returns null if mAttachInfo is null. mAttachInfo is set to null in > dispatchDetachedFromWindow. I'm not sure whether mParent is set to null as part > of this, but it is called in ViewRootImpls.java code: > https://github.com/android/platform_frameworks_base/blob/4535e11fb7010f2b104d... > > While I'm not convinced you shouldn't be setting this to null, it might be > happening by default because the containers root view might be null here and > you'd be implicitly setting it to null (but that depends on the ordering of the > observers for detaching from the window). > > If you're assuming this to be non-null, then why do you think the root view will > change in the time between attach and detach? Shouldn't it only change in > attach? I'm just confused why you'd be needing to update this as it shouldn't > ever change unless it were to be attached to a different window. You're right that top ancestor's mParent is eventually set to null on window detachment. Then WebView#getRootView() will return 'this' or one of its non-null ancestor. It will be viewrootimpl when attached to a window, and it will just be the top-level view when detached from the window. I also assumed that it can be changed on attaching / detaching because View#dispatchDetachedFromWindow() will set mAttachInfo to null while dispatchAttachedToWindow() will set the value to something non-null. In any case, I always wanted to ask the container view to make sure of the behavior.
On 2016/07/28 02:02:18, Changwan Ryu wrote: > On 2016/07/27 17:30:20, Ted C wrote: > > > https://codereview.chromium.org/2175263002/diff/20001/content/public/android/... > > File > > > content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java > > (right): > > > > > https://codereview.chromium.org/2175263002/diff/20001/content/public/android/... > > > content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java:72: > > mRootView.set(mContainerView.getRootView()); > > On 2016/07/27 00:48:45, Changwan Ryu wrote: > > > On 2016/07/27 00:16:36, Ted C wrote: > > > > why do you need to do this? should we be setting the root view to null in > > > this > > > > case? > > > > > > According to View#getRootView() this should not be null but the root of the > > view > > > hierarchy even when window is not attached. > > > > Umm...where do you see that? > > > > There javadoc does not mention that. > > > > Looking at the code for getRootView(): > > > https://github.com/android/platform_frameworks_base/blob/master/core/java/and... > > > > It returns null if mAttachInfo is null. mAttachInfo is set to null in > > dispatchDetachedFromWindow. I'm not sure whether mParent is set to null as > part > > of this, but it is called in ViewRootImpls.java code: > > > https://github.com/android/platform_frameworks_base/blob/4535e11fb7010f2b104d... > > > > While I'm not convinced you shouldn't be setting this to null, it might be > > happening by default because the containers root view might be null here and > > you'd be implicitly setting it to null (but that depends on the ordering of > the > > observers for detaching from the window). > > > > If you're assuming this to be non-null, then why do you think the root view > will > > change in the time between attach and detach? Shouldn't it only change in > > attach? I'm just confused why you'd be needing to update this as it shouldn't > > ever change unless it were to be attached to a different window. > > You're right that top ancestor's mParent is eventually set to null on window > detachment. Then WebView#getRootView() > will return 'this' or one of its non-null ancestor. It will be viewrootimpl when > attached to a window, and it will just be > the top-level view when detached from the window. > > I also assumed that it can be changed on attaching / detaching because > View#dispatchDetachedFromWindow() > will set mAttachInfo to null while dispatchAttachedToWindow() will set the value > to something non-null. > > In any case, I always wanted to ask the container view to make sure of the > behavior. Hmm… Actually, mParent is set to null *after* onOriginalViewDetachedFromWindow(), while mAttachInfo will be set to null *before* calling onOriginalViewDetachedFromWindow(). So we do not approximate the original method correctly in this case. In practice, getRootView() is never called when window is detaching or detached. It's only called when window-attached view gets focused. So I just removed the updating code from onOriginalViewDetachedFromWindow. PTAL
lgtm w/ comment but at this point, I'll leave it to you to decide if it is the best course of action or not https://codereview.chromium.org/2175263002/diff/40001/content/public/android/... File content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java (right): https://codereview.chromium.org/2175263002/diff/40001/content/public/android/... content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java:72: // anyways. While getRootView might not be called anymore, we're now holding onto a view reference that the original view will drop, which seems like a bad thing to me. I still think we should be setting this to null to ensure we're never holding onto stale view refs.
The CQ bit was checked by changwan@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
Thanks for the reviews. Submitting. https://codereview.chromium.org/2175263002/diff/40001/content/public/android/... File content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java (right): https://codereview.chromium.org/2175263002/diff/40001/content/public/android/... content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java:72: // anyways. On 2016/07/28 16:29:17, Ted C wrote: > While getRootView might not be called anymore, we're now holding onto a view > reference that the original view will drop, which seems like a bad thing to me. > I still think we should be setting this to null to ensure we're never holding > onto stale view refs. Done. Now set to null now on detachment.
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
The CQ bit was checked by changwan@chromium.org
The patchset sent to the CQ was uploaded after l-g-t-m from aelias@chromium.org, tedchoc@chromium.org Link to the patchset: https://codereview.chromium.org/2175263002/#ps60001 (title: "set to null")
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
Message was sent while issue was closed.
Description was changed from ========== Cache proxy view return value to avoid deadlock If WebView has an active IME but the Android app calls InputMethodManager#hideSoftInputFromWindow() on a non-UI thread, then a deadlock may happen. One example case is when JavaScript triggers it through JavascriptInterface (therefore, on JavaBridge thread.) The deadlock scenario is as follows: 1) InputMethodManager#hideSoftFromWindow() calls ThreadedInputConnectionProxyView#getWindowToken() on JavaBridge thread while holding InputMethodManager#mH. Then getWindowToken() waits for UI thread to become available. 2) At almost same time, InputMethodManager#restartInput() was waiting for InputMethodManager#mH on UI thread This deadlock can be avoided by caching return values as atomic objects. Alternative approach I've tried: check the current thread and block it only when it's IME thread - this may still leave room for deadlock between IME thread and UI thread. BUG=630937 ========== to ========== Cache proxy view return value to avoid deadlock If WebView has an active IME but the Android app calls InputMethodManager#hideSoftInputFromWindow() on a non-UI thread, then a deadlock may happen. One example case is when JavaScript triggers it through JavascriptInterface (therefore, on JavaBridge thread.) The deadlock scenario is as follows: 1) InputMethodManager#hideSoftFromWindow() calls ThreadedInputConnectionProxyView#getWindowToken() on JavaBridge thread while holding InputMethodManager#mH. Then getWindowToken() waits for UI thread to become available. 2) At almost same time, InputMethodManager#restartInput() was waiting for InputMethodManager#mH on UI thread This deadlock can be avoided by caching return values as atomic objects. Alternative approach I've tried: check the current thread and block it only when it's IME thread - this may still leave room for deadlock between IME thread and UI thread. BUG=630937 ==========
Message was sent while issue was closed.
Committed patchset #4 (id:60001)
Message was sent while issue was closed.
Description was changed from ========== Cache proxy view return value to avoid deadlock If WebView has an active IME but the Android app calls InputMethodManager#hideSoftInputFromWindow() on a non-UI thread, then a deadlock may happen. One example case is when JavaScript triggers it through JavascriptInterface (therefore, on JavaBridge thread.) The deadlock scenario is as follows: 1) InputMethodManager#hideSoftFromWindow() calls ThreadedInputConnectionProxyView#getWindowToken() on JavaBridge thread while holding InputMethodManager#mH. Then getWindowToken() waits for UI thread to become available. 2) At almost same time, InputMethodManager#restartInput() was waiting for InputMethodManager#mH on UI thread This deadlock can be avoided by caching return values as atomic objects. Alternative approach I've tried: check the current thread and block it only when it's IME thread - this may still leave room for deadlock between IME thread and UI thread. BUG=630937 ========== to ========== Cache proxy view return value to avoid deadlock If WebView has an active IME but the Android app calls InputMethodManager#hideSoftInputFromWindow() on a non-UI thread, then a deadlock may happen. One example case is when JavaScript triggers it through JavascriptInterface (therefore, on JavaBridge thread.) The deadlock scenario is as follows: 1) InputMethodManager#hideSoftFromWindow() calls ThreadedInputConnectionProxyView#getWindowToken() on JavaBridge thread while holding InputMethodManager#mH. Then getWindowToken() waits for UI thread to become available. 2) At almost same time, InputMethodManager#restartInput() was waiting for InputMethodManager#mH on UI thread This deadlock can be avoided by caching return values as atomic objects. Alternative approach I've tried: check the current thread and block it only when it's IME thread - this may still leave room for deadlock between IME thread and UI thread. BUG=630937 Committed: https://crrev.com/43ceb11f9abf67fea18e8a731a9ef61f5cfe22fc Cr-Commit-Position: refs/heads/master@{#408925} ==========
Message was sent while issue was closed.
Patchset 4 (id:??) landed as https://crrev.com/43ceb11f9abf67fea18e8a731a9ef61f5cfe22fc Cr-Commit-Position: refs/heads/master@{#408925} |