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 16:58 Go to next message
Mark Melvin is currently offline Mark MelvinFriend
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?

Re: Concurrency help (modifying the workspace) [message #488951 is a reply to message #488441] Wed, 30 September 2009 20:04 Go to previous message
Mark Melvin is currently offline Mark MelvinFriend
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.
org.eclipse.core.internal.resources.ResourceException: The resource tree is locked for modifications.
at org.eclipse.core.internal.resources.WorkManager.checkIn(Work
at org.eclipse.core.internal.resources.Workspace.prepareOperati on(
at org.eclipse.core.internal.resources.File.setContents(File.ja va:354)
at org.eclipse.core.internal.resources.ProjectPreferences$ (
at org.eclipse.core.internal.preferences.EclipsePreferences.flu sh(
at org.eclipse.core.internal.resources.ProjectPreferences.flush (
at org.eclipse.core.internal.preferences.EclipsePreferences.flu sh(
at org.eclipse.core.internal.resources.ProjectPreferences.flush (
at erences.flush(
at ger.applyChanges(
at ildInfo(
at o(
at o(
at (
at odelItem.getBuildInfo( 6)
at ernalUpdate(
at odelItem.getChildren(
at odelItem.hasChildren(
at ovider.hasChildren(
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
at org.eclipse.jface.viewers.AbstractTreeViewer.isExpandable(Ab
at org.eclipse.jface.viewers.TreeViewer.isExpandable(TreeViewer .java:587)
at org.eclipse.jface.viewers.AbstractTreeViewer.isExpandable(Ab
at org.eclipse.jface.viewers.AbstractTreeViewer.updatePlus(Abst
at org.eclipse.jface.viewers.TreeViewer.updatePlus(TreeViewer.j ava:847)
at org.eclipse.jface.viewers.AbstractTreeViewer.internalRefresh (
at org.eclipse.jface.viewers.AbstractTreeViewer.internalRefresh (
at org.eclipse.ui.navigator.CommonViewer.internalRefresh(Common
at org.eclipse.jface.viewers.StructuredViewer$
at org.eclipse.jface.viewers.StructuredViewer.preservingSelecti on(
at org.eclipse.jface.viewers.TreeViewer.preservingSelection(Tre
at org.eclipse.jface.viewers.StructuredViewer.preservingSelecti on(
at org.eclipse.jface.viewers.StructuredViewer.refresh(Structure
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 ovider$
at ovider.runUpdates(
at ovider.processDelta(
at org.eclipse.ui.model.WorkbenchContentProvider.resourceChange d(
at stChanges(
at org.eclipse.core.internal.resources.Workspace.broadcastPostC hange(
at org.eclipse.core.internal.resources.Workspace.endOperation(W
at java:1809)
at org.eclipse.jface.operation.ModalContext.runInCurrentThread(
at va:372)
at .java:95)
at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginActi
at org.eclipse.jface.action.ActionContributionItem.handleWidget Selection(
at org.eclipse.jface.action.ActionContributionItem.access$2(Act
at org.eclipse.jface.action.ActionContributionItem$5.handleEven t(
at org.eclipse.swt.widgets.EventTable.sendEvent( :84)
at org.eclipse.swt.widgets.Widget.sendEvent(
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:3880)
at org.eclipse.swt.widgets.Display.readAndDispatch( :3473)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:2405)
at org.eclipse.ui.internal.Workbench.runUI(
at org.eclipse.ui.internal.Workbench.access$4( 21)
at org.eclipse.ui.internal.Workbench$
at org.eclipse.core.databinding.observable.Realm.runWithDefault (
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Work
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.j ava:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start (
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher .runApplication(
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher .start(
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( 559)
at org.eclipse.equinox.launcher.Main.basicRun(
at org.eclipse.equinox.launcher.Main.main(
!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()) {
} 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?

Previous Topic:How to get one command to affect the visibility of another command?
Next Topic:Handler Enablement
Goto Forum:

Current Time: Sat Apr 29 20:12:05 GMT 2017

Powered by FUDForum. Page generated in 0.02069 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software