diff options
author | Leo Ufimtsev | 2018-04-04 13:41:20 +0000 |
---|---|---|
committer | Leo Ufimtsev | 2018-04-04 19:11:40 +0000 |
commit | 6b73a19165f47cd767b060aa616bc877b5fc2d99 (patch) | |
tree | 2e9bc7522364a0d4b671f9e377a11c6544e77459 /bundles/org.eclipse.swt/Eclipse SWT WebKit | |
parent | 6821d31b9c58db30d37d7b468419a72377bda431 (diff) | |
download | eclipse.platform.swt-6b73a19165f47cd767b060aa616bc877b5fc2d99.tar.gz eclipse.platform.swt-6b73a19165f47cd767b060aa616bc877b5fc2d99.tar.xz eclipse.platform.swt-6b73a19165f47cd767b060aa616bc877b5fc2d99.zip |
Bug 530678 [webkit2] UI hangs after navigating through Javadoc hover,
when
clicking an icon or link to an image.
TL;DR: Fix for bug.
Details:
Clicking on a javadoc like below, (after 2 or 3 times), breaks javadoc.
/** <a href="https://bugs.eclipse.org/bugs/attachment.cgi?id=272647">Screenshot</a>
*/
It un-breaks if you manually kill Webkit* processes.
I.e, Webkit process deadlocks if Browser is disposed in the middle of a
callback.
The fix is to delay disposal until callback is completed. This is
achived by leaving a dangling reference until next display loop
is executed.
This also fixes the bug: 494158 - [Webkit1][Webkit2] JVM crash when
javadoc hover has <embed> tags.
In addition, I'm adding a jUnit to verify that the fix hasn't introduced
memory leaks. (E.g if object is not unreferenced, then one can observe
a memory leak. So by extension this fix does not introduce a memory leak
since the test passes). (Note, it's not added to be ran automatically
becaues it takes 5+ minutes to run).
Tests & verification: (gtk3.22, Webkit2.18).
- jUnit: AllTests
- Child Eclipse opens external links (multiple times) in javadoc
correctly.
- Various Browser Snippets.
- Test_Memory_leak.test_Browser().
https://bugs.eclipse.org/bugs/show_bug.cgi?id=530678
Change-Id: I2a0f0f7e2b44bce67a1212bfa4205561942e59de
Signed-off-by: Leo Ufimtsev <lufimtse@redhat.com>
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT WebKit')
-rw-r--r-- | bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java index f146139aff..498038db89 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java +++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java @@ -1057,6 +1057,8 @@ public void create (Composite parent, int style) { // As of Webkitgtk 2.18, webkitgtk2 crashes if the first instance of webview is not referenced when JVM shuts down. // There is a exit handler that tries to dereference the first instance [which if not referenced] // leads to a crash. This workaround would benefit from deeper investigation (find root cause etc...). + // [edit] Bug 530678. Note, it seems that as of Webkit2.18, webkit auto-disposes itself if parent get's disposed. + // While not directly related, see onDispose() for how to deal with disposal of this. if (WEBKIT2 && !bug522733FirstInstanceCreated && vers[0] == 2 && vers[1] >= 18) { bug522733FirstInstanceCreated = true; OS.g_object_ref(webView); @@ -2396,8 +2398,25 @@ void onDispose (Event e) { postData = null; headers = null; htmlBytes = null; - } else if (WEBKIT2) { - webView = 0; // Note, Webkit2 disposes it self on it's own. + } + if (WEBKIT2 && WebKitGTK.webkit_get_minor_version() >= 18) { + // Bug 530678. + // * As of Webkit 2.18, (it seems) webkitGtk auto-disposes itself when the parent is disposed. + // * This can cause a deadlock inside Webkit process if WebkitGTK widget's parent is disposed during a callback. + // This is because webkit process is waiting for it's callback to finish which never completes + // because parent's disposal also disposed webkitGTK widget. (Note Webkit process vs WebkitGtk widget). + // * To break the deadlock, we unparent webkitGtk temporarily and unref (dispose) it later after callback is done. + // + // If you change dispose logic, to check that you haven't introduced memory leaks, test via: + // org.eclipse.swt.tests.junit.memoryleak.Test_Memory_Leak.test_Browser() + OS.g_object_ref (webView); + GTK.gtk_container_remove (GTK.gtk_widget_get_parent (webView), webView); + long /*int*/ webViewTempRef = webView; + browser.getDisplay().asyncExec(() -> { + GTK._gtk_widget_destroy(webViewTempRef); + OS.g_object_unref (webViewTempRef); + }); + webView = 0; } } |