Bug 468270 - Deadlock in AutoShareProjects
Summary: Deadlock in AutoShareProjects
Status: RESOLVED FIXED
Alias: None
Product: EGit
Classification: Technology
Component: Core (show other bugs)
Version: 4.0   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 4.0   Edit
Assignee: Andrey Loskutov CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-05-26 04:36 EDT by Andrey Loskutov CLA
Modified: 2015-06-07 09:49 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrey Loskutov CLA 2015-05-26 04:36:13 EDT
Eclipse 3.8.2, egit 4.0.0.201504272231: our automated testsuite reports this deadlock in test which first creates new project and then tries to open it. I cannot unfortunately share the test code.

I have never seen this by myself, but test always fails if "autosharing" is enabled. I'm investigating this right now.

!ENTRY org.eclipse.core.jobs 4 2 2015-05-19 15:20:56.684
!MESSAGE Deadlock detected. All locks owned by thread main will be suspended.
!STACK 0
java.lang.IllegalStateException
	at org.eclipse.core.internal.jobs.DeadlockDetector.reportDeadlock(DeadlockDetector.java:599)
	at org.eclipse.core.internal.jobs.DeadlockDetector.lockWaitStart(DeadlockDetector.java:403)
	at org.eclipse.core.internal.jobs.LockManager.addLockWaitThread(LockManager.java:158)
	at org.eclipse.core.internal.jobs.OrderedLock.doAcquire(OrderedLock.java:174)
	at org.eclipse.core.internal.jobs.OrderedLock.acquire(OrderedLock.java:110)
	at org.eclipse.core.internal.jobs.OrderedLock.acquire(OrderedLock.java:84)
	at org.eclipse.team.core.RepositoryProvider.mapExistingProvider(RepositoryProvider.java:217)
	at org.eclipse.team.core.RepositoryProvider.getProvider(RepositoryProvider.java:578)
	at org.eclipse.egit.core.project.RepositoryMapping.getMapping(RepositoryMapping.java:320)
	at org.eclipse.egit.core.project.RepositoryMapping.getMapping(RepositoryMapping.java:306)
	at org.eclipse.egit.core.Activator$AutoShareProjects.visitConnect(Activator.java:347)
	at org.eclipse.egit.core.Activator$AutoShareProjects.access$0(Activator.java:334)
	at org.eclipse.egit.core.Activator$AutoShareProjects$1.visit(Activator.java:316)
	at org.eclipse.core.internal.events.ResourceDelta.accept(ResourceDelta.java:69)
	at org.eclipse.core.internal.events.ResourceDelta.accept(ResourceDelta.java:80)
	at org.eclipse.core.internal.events.ResourceDelta.accept(ResourceDelta.java:49)
	at org.eclipse.egit.core.Activator$AutoShareProjects.resourceChanged(Activator.java:313)
	at org.eclipse.core.internal.events.NotificationManager$1.run(NotificationManager.java:291)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.core.internal.events.NotificationManager.notify(NotificationManager.java:285)
	at org.eclipse.core.internal.events.NotificationManager.broadcastChanges(NotificationManager.java:149)
	at org.eclipse.core.internal.resources.Workspace.broadcastPostChange(Workspace.java:395)
	at org.eclipse.core.internal.resources.Workspace.endOperation(Workspace.java:1530)
	at org.eclipse.core.internal.resources.Project.open(Project.java:1169)
	at org.eclipse.core.internal.resources.Project.open(Project.java:1180)
	at com.verigy.itee.core.test.util.TestProjectDefinitionReader.testReadForOpenedProject(TestProjectDefinitionReader.java:68)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at junit.framework.TestCase.runTest(TestCase.java:176)
	at junit.framework.TestCase.runBare(TestCase.java:141)
	at junit.framework.TestResult$1.protect(TestResult.java:122)
	at junit.framework.TestResult.runProtected(TestResult.java:142)
	at junit.framework.TestResult.run(TestResult.java:125)
	at junit.framework.TestCase.run(TestCase.java:129)
	at junit.framework.TestSuite.runTest(TestSuite.java:255)
	at com.verigy.itee.core.test.TestSuite93k.runTest(TestSuite93k.java:135)
	at junit.framework.TestSuite.run(TestSuite.java:250)
	at junit.framework.TestSuite.runTest(TestSuite.java:255)
	at com.verigy.itee.core.test.TestSuite93k.runTest(TestSuite93k.java:121)
	at junit.framework.TestSuite.run(TestSuite.java:250)
	at com.verigy.itee.testframework.runner.JunitTestRunner$JunitRunnable.run(JunitTestRunner.java:172)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3537)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3189)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499)
	at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
	at com.verigy.itee.testframework.application.TestFrameworkTestApplication.start(TestFrameworkTestApplication.java:290)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1414)
!SUBENTRY 1 org.eclipse.core.jobs 4 2 2015-05-19 15:20:56.685
!MESSAGE Thread main has locks: P/testReadForOpenedProject, OrderedLock (0) and is waiting for lock OrderedLock (1)
!SUBENTRY 1 org.eclipse.core.jobs 4 2 2015-05-19 15:20:56.685
!MESSAGE Thread Worker-10 has locks: MultiRule[P/testReadForOpenedProject1], OrderedLock (1) and is waiting for lock OrderedLock (0)
Comment 1 Andrey Loskutov CLA 2015-05-26 05:09:19 EDT
OK, seems to be following:

AutoShareProjects triggers ConnectProviderOperation in a job which triggers RepositoryProvider.map() which holds the mapping lock during it's operation. The code in RepositoryProvider.map() is doing something before releasing the mapping lock which seem to trigger resource changes (my guess?) and so triggering AutoShareProjects listener again.

AutoShareProjects implements resource change listener and calls innocently looking RepositoryMapping.getMapping(resource) method which internally can trigger RepositoryProvider.mapExistingProvider() which tries to acquire mapping lock from RepositoryProvider which is held by ConnectProviderOperation.

So the solution would be to decouple AutoShareProjects.resourceChanged() from the calling thread, so that it is executed not in the same thread as the resource change is sent.
Comment 2 Andrey Loskutov CLA 2015-05-26 08:40:11 EDT
Fix: https://git.eclipse.org/r/48631