Bug 232506

Summary: [hovering] TextViewerHoverManager can interrupt the presenter thread at any point
Product: [Eclipse Project] Platform Reporter: Dmitry Karasik <Dmitry_Karasik>
Component: TextAssignee: Platform-Text-Inbox <platform-text-inbox>
Status: ASSIGNED --- QA Contact:
Severity: normal    
Priority: P3 CC: daniel_megert, jean-michel_lemieux
Version: 3.3.2Keywords: needinfo
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard:

Description Dmitry Karasik CLA 2008-05-16 10:39:26 EDT
If the editor text is changed when the presenter thread is running, the presenter thread gets interrupted. This causes file/socket descriptors to be closed on unsuspecting code invoked by that thread.
Comment 1 Dani Megert CLA 2008-05-16 12:17:22 EDT
Sorry but this is pretty generic. Please provide steps and more details.
http://www.eclipse.org/eclipse/platform-text/development/bug-incomplete.htm
Comment 2 Dmitry Karasik CLA 2008-05-16 13:16:44 EDT
I thought my description made it pretty obvious what the problem is.

To reproduce a specific instance of the problem:

have an EFS provider that keeps its own metadata.
Open a java editor with some NLSed strings.
Place cursor over the externalized string, and at the same time type a character.
If you did the above at the right time, the thread computing the hover will get interrupted, causing the currently read filedescriptor to be closed and corrupting the metadata kept by the EFS provider.

 java.nio.channels.ClosedByInterruptException
	at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:212)

	at sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:663)

	at com.ibm.team.repository.common.internal.content.util.FileChannelUtil.readFully(FileChannelUtil.java:69)

	at com.ibm.team.repository.common.internal.content.util.BTreeHeap.readFully(BTreeHeap.java:185)

	at com.ibm.team.repository.common.internal.content.util.PersistentBTreeHeap.init(PersistentBTreeHeap.java:63)

	at com.ibm.team.repository.common.internal.content.util.PersistentBTreeHeap.<init>(PersistentBTreeHeap.java:36)

	at com.ibm.team.filesystem.client.internal.PersistentHeapManager$AutoClosingPersistentFileHeap.<init>(PersistentHeapManager.java:57)

	at com.ibm.team.filesystem.client.internal.PersistentHeapManager.getPersistentFileHeap(PersistentHeapManager.java:31)

	at com.ibm.team.filesystem.client.internal.Store.newPersistentBTreeHeap(Store.java:45)

	at com.ibm.team.repository.common.internal.content.util.PersistentDiskBackedHashMap.initFromFile(PersistentDiskBackedHashMap.java:80)

	at com.ibm.team.filesystem.client.internal.Store.<init>(Store.java:29)

	at com.ibm.team.filesystem.client.internal.SharingMetadata2$MetadataStore.<init>(SharingMetadata2.java:97)

	at com.ibm.team.filesystem.client.internal.SharingMetadata2$Directory.initEntries(SharingMetadata2.java:789)

	at com.ibm.team.filesystem.client.internal.LockableMap.init(LockableMap.java:38)

	at com.ibm.team.filesystem.client.internal.SharingMetadata2$Directory.init(SharingMetadata2.java:783)

	at com.ibm.team.filesystem.client.internal.SharingMetadata2$Directory.<init>(SharingMetadata2.java:778)

	at com.ibm.team.filesystem.client.internal.SharingMetadata2$MetadataDiskBackedMapManager.getLockableMap(SharingMetadata2.java:726)

	at com.ibm.team.filesystem.client.internal.DiskBackedMapManager.loadMap(DiskBackedMapManager.java:75)

	at com.ibm.team.filesystem.client.internal.SharingMetadata2.loadDirectory(SharingMetadata2.java:1235)

	at com.ibm.team.filesystem.client.internal.SharingMetadata2.getFileItemInfo(SharingMetadata2.java:1449)

	at com.ibm.team.filesystem.client.internal.MetadataChangeTracker.getFileItemInfo(MetadataChangeTracker.java:407)

	at com.ibm.team.filesystem.client.internal.copyfileareas.CopyFileAreaStore.getItemInfo(CopyFileAreaStore.java:1431)

	at com.ibm.team.filesystem.client.internal.ManagedFileStore.getVersionableHandle(ManagedFileStore.java:911)

	at com.ibm.team.filesystem.client.internal.ManagedFileStore.fetchInfoInternal(ManagedFileStore.java:370)

	at com.ibm.team.filesystem.client.internal.ManagedFileStore.fetchInfo(ManagedFileStore.java:347)

	at org.eclipse.core.filesystem.provider.FileStore.fetchInfo(FileStore.java:275)

	at org.eclipse.core.internal.localstore.FileSystemResourceManager.read(FileSystemResourceManager.java:601)

	at org.eclipse.core.internal.resources.File.getContents(File.java:287)

	at org.eclipse.core.internal.resources.File.getContents(File.java:276)

	at org.eclipse.jdt.internal.corext.refactoring.nls.NLSHintHelper.getProperties(NLSHintHelper.java:439)

	at org.eclipse.jdt.internal.ui.text.java.hover.NLSStringHover.getHoverInfo(NLSStringHover.java:116)

	at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo(BestMatchHover.java:102)

	at org.eclipse.jdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy.getHoverInfo(JavaEditorTextHoverProxy.java:69)

	at org.eclipse.jface.text.TextViewerHoverManager$4.run(TextViewerHoverManager.java:165)

Comment 3 Dani Megert CLA 2008-05-19 05:19:44 EDT
It's by design that the hover thread gets interrupted and has been like that since day one. You need to protect your code against such situations, as they can happen  with other threads as well.
Comment 4 Dmitry Karasik CLA 2008-05-19 10:22:33 EDT
Some fds cannot be reopened, either because they were passed in to the program (i.e. stdin, stdout, stderr) or because you may have interrupted a long running transaction and thus undone work that was done as part of some other invocation.

You must not call Thread.interrupt() unless you really mean to have fds closed on code that is running. There is no way for the thread to protect itself against interruption, so unless you control the IO code you have no business calling Thread.interrupt().
Comment 5 Dani Megert CLA 2008-05-19 10:35:52 EDT
> so unless you control the IO code you have no business
>calling Thread.interrupt().
This is not spec'ed in JLS. Instead Thread.interrupt() clearly describes what happens and which exceptions are thrown. Even if we stop doing this that (or any other thread using your code) can be interrupted for many other reasons.
Comment 6 Dmitry Karasik CLA 2008-05-19 10:43:27 EDT
It is speced in the javadoc for Thread.interrupt() that it will close the fd. If that is not your intention then you should not be calling Thread.interrupt().

A thread cannot be interrupted for any other reason than somebody calling Thread.interrupt() on it. Consequently the person calling that method has to have the intention of closing fds.
Comment 7 Eclipse Webmaster CLA 2019-09-06 15:30:32 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.