Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Platform » Concurrency help (modifying the workspace)
Concurrency help (modifying the workspace) [message #488441] Mon, 28 September 2009 12:58 Go to next message
Mark Melvin is currently offline Mark Melvin
Messages: 118
Registered: July 2009
Senior Member
Hi There,

I have some code that uses a set of ProjectScope preference settings that is starting to give me major concurrency headaches. Not being an expert on things, I need a bit of advice.

Currently, I have concurrency issues that have arisen as a result of me moving to the common navigator. This isn't the common navigator's fault - my code was never really threadsafe, and now it is being hammered from many threads at once. My initial attempts at simple synchronization failed and caused deadlocks (mostly due to my builder executing the same code in the context of an autobuild, and the platform locking the workspace).

Basically, what I need to do is refactor my code to avoid calling #flush() on my project-scoped preference nodes from many different threads, but also deal with the cases where I absolutely *need* to have the preference node flushed before I can move on. This is the tough part.

Let's say I absolutely need to flush my project preferences to disk, but I am being called in the context of an automatic build, and the workspace is locked. How can I avoid deadlocks in this situation? What is the proper way for me to ensure the project preference node is flushed (waiting for it if necessary), without deadlocking the platform? I realize you can "join" the autobuild job, but it is not really that simple. The ProjectPreferences#save method jumps through some hoops to try to avoid this very issue, so I am tempted to just rely on it's behavior here. But things get pretty hairy and I am a little unsure of how to properly do this, having been burned in the past.

What is the best way to avoid these types of deadlocks if two things are both trying to lock/modify a project in the workspace? Is there a specific strategy using the Jobs or Resources API?

Thanks,
Mark.
Re: Concurrency help (modifying the workspace) [message #488951 is a reply to message #488441] Wed, 30 September 2009 16:04 Go to previous message
Mark Melvin is currently offline Mark Melvin
Messages: 118
Registered: July 2009
Senior Member
So I have all of my code cleaned up pretty much as best as I can figure, but I still get this occasionally:

!ENTRY org.eclipse.core.resources 4 4 2009-09-30 14:49:45.135
!MESSAGE Exception occurred while saving project preferences: /MyProject/.settings/my_settings.prefs.
!STACK 1
org.eclipse.core.internal.resources.ResourceException: The resource tree is locked for modifications.
at org.eclipse.core.internal.resources.WorkManager.checkIn(Work Manager.java:115)
at org.eclipse.core.internal.resources.Workspace.prepareOperati on(Workspace.java:1747)
at org.eclipse.core.internal.resources.File.setContents(File.ja va:354)
at org.eclipse.core.internal.resources.ProjectPreferences$2.run (ProjectPreferences.java:563)
at org.eclipse.core.internal.resources.ProjectPreferences.save( ProjectPreferences.java:581)
at org.eclipse.core.internal.preferences.EclipsePreferences.flu sh(EclipsePreferences.java:352)
at org.eclipse.core.internal.resources.ProjectPreferences.flush (ProjectPreferences.java:383)
at org.eclipse.core.internal.preferences.EclipsePreferences.flu sh(EclipsePreferences.java:340)
at org.eclipse.core.internal.resources.ProjectPreferences.flush (ProjectPreferences.java:383)
at com.signaklara.skt.build.preferences.derived.WorkingCopyPref erences.flush(WorkingCopyPreferences.java:529)
at com.signaklara.skt.build.preferences.derived.WorkingCopyMana ger.applyChanges(WorkingCopyManager.java:75)
at com.signaklara.skt.build.model.BuildInfoManager.initializeBu ildInfo(BuildInfoManager.java:894)
at com.signaklara.skt.build.model.BuildInfoManager.loadBuildInf o(BuildInfoManager.java:735)
at com.signaklara.skt.build.model.BuildInfoManager.findBuildInf o(BuildInfoManager.java:253)
at com.signaklara.skt.build.model.BuildInfoManager.getBuildInfo (BuildInfoManager.java:126)
at com.signaklara.skt.build.ui.navigator.AbstractBuildSettingsM odelItem.getBuildInfo(AbstractBuildSettingsModelItem.java:12 6)
at com.signaklara.skt.build.ui.navigator.BuildInfoModelItem.int ernalUpdate(BuildInfoModelItem.java:48)
at com.signaklara.skt.build.ui.navigator.AbstractBuildSettingsM odelItem.getChildren(AbstractBuildSettingsModelItem.java:52)
at com.signaklara.skt.build.ui.navigator.AbstractBuildSettingsM odelItem.hasChildren(AbstractBuildSettingsModelItem.java:67)
at com.signaklara.skt.build.ui.navigator.BuildSettingsContentPr ovider.hasChildren(BuildSettingsContentProvider.java:201)
at org.eclipse.ui.internal.navigator.extensions.SafeDelegateTre eContentProvider.hasChildren(SafeDelegateTreeContentProvider .java:106)
at org.eclipse.ui.internal.navigator.extensions.SafeDelegateTre eContentProvider.hasChildren(SafeDelegateTreeContentProvider .java:291)
at org.eclipse.ui.internal.navigator.NavigatorContentServiceCon tentProvider.hasChildren(NavigatorContentServiceContentProvi der.java:624)
at org.eclipse.jface.viewers.AbstractTreeViewer.isExpandable(Ab stractTreeViewer.java:2079)
at org.eclipse.jface.viewers.TreeViewer.isExpandable(TreeViewer .java:587)
at org.eclipse.jface.viewers.AbstractTreeViewer.isExpandable(Ab stractTreeViewer.java:2109)
at org.eclipse.jface.viewers.AbstractTreeViewer.updatePlus(Abst ractTreeViewer.java:2791)
at org.eclipse.jface.viewers.TreeViewer.updatePlus(TreeViewer.j ava:847)
at org.eclipse.jface.viewers.AbstractTreeViewer.internalRefresh (AbstractTreeViewer.java:1828)
at org.eclipse.jface.viewers.AbstractTreeViewer.internalRefresh (AbstractTreeViewer.java:1794)
at org.eclipse.ui.navigator.CommonViewer.internalRefresh(Common Viewer.java:566)
at org.eclipse.jface.viewers.StructuredViewer$8.run(StructuredV iewer.java:1484)
at org.eclipse.jface.viewers.StructuredViewer.preservingSelecti on(StructuredViewer.java:1392)
at org.eclipse.jface.viewers.TreeViewer.preservingSelection(Tre eViewer.java:402)
at org.eclipse.jface.viewers.StructuredViewer.preservingSelecti on(StructuredViewer.java:1353)
at org.eclipse.jface.viewers.StructuredViewer.refresh(Structure dViewer.java:1482)
at org.eclipse.jface.viewers.ColumnViewer.refresh(ColumnViewer. java:548)
at org.eclipse.ui.navigator.CommonViewer.refresh(CommonViewer.j ava:355)
at org.eclipse.ui.navigator.CommonViewer.refresh(CommonViewer.j ava:515)
at com.signaklara.skt.build.ui.navigator.BuildSettingsContentPr ovider$2.run(BuildSettingsContentProvider.java:303)
at com.signaklara.skt.build.ui.navigator.BuildSettingsContentPr ovider.runUpdates(BuildSettingsContentProvider.java:315)
at com.signaklara.skt.build.ui.navigator.BuildSettingsContentPr ovider.processDelta(BuildSettingsContentProvider.java:260)
at org.eclipse.ui.model.WorkbenchContentProvider.resourceChange d(WorkbenchContentProvider.java:106)
at org.eclipse.core.internal.events.NotificationManager$2.run(N otificationManager.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.broadca stChanges(NotificationManager.java:149)
at org.eclipse.core.internal.resources.Workspace.broadcastPostC hange(Workspace.java:313)
at org.eclipse.core.internal.resources.Workspace.endOperation(W orkspace.java:1022)
at org.eclipse.core.internal.resources.Workspace.run(Workspace. java:1809)
at org.eclipse.ui.actions.WorkspaceModifyOperation.run(Workspac eModifyOperation.java:118)
at org.eclipse.jface.operation.ModalContext.runInCurrentThread( ModalContext.java:464)
at org.eclipse.jface.operation.ModalContext.run(ModalContext.ja va:372)
at org.eclipse.jface.dialogs.ProgressMonitorDialog.run(Progress MonitorDialog.java:507)
at org.eclipse.compare.internal.EditionAction.updateWorkspace(E ditionAction.java:191)
at org.eclipse.compare.internal.EditionAction.doFromHistory(Edi tionAction.java:155)
at org.eclipse.compare.internal.EditionAction.run(EditionAction .java:95)
at org.eclipse.compare.internal.BaseCompareAction.run(BaseCompa reAction.java:26)
at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi on.java:251)
at org.eclipse.jface.action.ActionContributionItem.handleWidget Selection(ActionContributionItem.java:584)
at org.eclipse.jface.action.ActionContributionItem.access$2(Act ionContributionItem.java:501)
at org.eclipse.jface.action.ActionContributionItem$5.handleEven t(ActionContributionItem.java:411)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1003)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:3880)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :3473)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:2405)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2369)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:22 21)
at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:500)
at org.eclipse.core.databinding.observable.Realm.runWithDefault (Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Work bench.java:493)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.j ava:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start (IDEApplication.java:113)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(Eclips eAppHandle.java:194)
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(EclipseS tarter.java:368)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseS tarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java: 559)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:514)
at org.eclipse.equinox.launcher.Main.run(Main.java:1311)
at org.eclipse.equinox.launcher.Main.main(Main.java:1287)
!SUBENTRY 1 org.eclipse.core.resources 4 380 2009-09-30 14:49:45.135
!MESSAGE The resource tree is locked for modifications.

This happens when replacing a file from local history, which the platform locks the resource tree for. This makes perfect sense, but my question is - what the heck can I do in this situation?? Do I have any hope of doing anything useful, or do I just bail?

I can avoid the error if I just make a call to:

if (!ResourcesPlugin.getWorkspace().isTreeLocked()) {
return;
}

...in my method that is attempting to call ProjectPreferences#flush(), and 99% of the time I can live with this as my listeners will eventually get called again and all will be well. But I can't help but feel like I will eventually miss an edge case here. Is there a way to safely wait until the workspace is not locked without dead-locking the platform?

Thanks,
Mark.
Previous Topic:Catch unhandled event loop exception
Next Topic:shift/control + click on tree views
Goto Forum:
  


Current Time: Sat Aug 23 15:25:54 EDT 2014

Powered by FUDForum. Page generated in 0.01606 seconds