Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 145676 Details for
Bug 287096
[hotbug] ModelManagerImpl is highly susceptible to deadlock
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
Proposed patch (for 3.1 stream)
modelImpl.patch (text/plain), 12.18 KB, created by
Min Idzelis
on 2009-08-26 09:53:18 EDT
(
hide
)
Description:
Proposed patch (for 3.1 stream)
Filename:
MIME Type:
Creator:
Min Idzelis
Created:
2009-08-26 09:53:18 EDT
Size:
12.18 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.wst.sse.core >Index: src/org/eclipse/wst/sse/core/internal/SSECorePlugin.java >=================================================================== >RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/SSECorePlugin.java,v >retrieving revision 1.17 >diff -u -r1.17 SSECorePlugin.java >--- src/org/eclipse/wst/sse/core/internal/SSECorePlugin.java 25 Feb 2009 22:44:04 -0000 1.17 >+++ src/org/eclipse/wst/sse/core/internal/SSECorePlugin.java 26 Aug 2009 13:45:43 -0000 >@@ -16,6 +16,7 @@ > import org.eclipse.core.runtime.Preferences; > import org.eclipse.wst.sse.core.StructuredModelManager; > import org.eclipse.wst.sse.core.internal.encoding.CommonEncodingPreferenceNames; >+import org.eclipse.wst.sse.core.internal.model.ModelManagerImpl; > import org.eclipse.wst.sse.core.internal.modelhandler.ModelHandlerRegistry; > import org.eclipse.wst.sse.core.internal.preferences.CommonModelPreferenceNames; > import org.eclipse.wst.sse.core.internal.provisional.IModelManager; >@@ -62,10 +63,13 @@ > public void stop(BundleContext context) throws Exception { > savePluginPreferences(); > >+ ((ModelManagerImpl) ModelManagerImpl.getInstance()).removePreferenceListener(); >+ > TaskScanningScheduler.shutdown(); > > FileBufferModelManager.shutdown(); > >+ > super.stop(context); > } > >Index: src/org/eclipse/wst/sse/core/internal/model/ModelManagerImpl.java >=================================================================== >RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/model/ModelManagerImpl.java,v >retrieving revision 1.36 >diff -u -r1.36 ModelManagerImpl.java >--- src/org/eclipse/wst/sse/core/internal/model/ModelManagerImpl.java 22 Apr 2009 03:58:35 -0000 1.36 >+++ src/org/eclipse/wst/sse/core/internal/model/ModelManagerImpl.java 26 Aug 2009 13:45:43 -0000 >@@ -40,6 +40,7 @@ > import org.eclipse.core.runtime.IPath; > import org.eclipse.core.runtime.IStatus; > import org.eclipse.core.runtime.NullProgressMonitor; >+import org.eclipse.core.runtime.OperationCanceledException; > import org.eclipse.core.runtime.Path; > import org.eclipse.core.runtime.Platform; > import org.eclipse.core.runtime.QualifiedName; >@@ -47,9 +48,16 @@ > import org.eclipse.core.runtime.content.IContentDescription; > import org.eclipse.core.runtime.jobs.ILock; > import org.eclipse.core.runtime.jobs.Job; >+import org.eclipse.core.runtime.preferences.ConfigurationScope; >+import org.eclipse.core.runtime.preferences.IEclipsePreferences; >+import org.eclipse.core.runtime.preferences.IPreferencesService; >+import org.eclipse.core.runtime.preferences.IScopeContext; >+import org.eclipse.core.runtime.preferences.InstanceScope; >+import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; > import org.eclipse.jface.text.BadLocationException; > import org.eclipse.jface.text.IDocument; > import org.eclipse.jface.text.IRegion; >+import org.eclipse.osgi.util.NLS; > import org.eclipse.text.edits.MultiTextEdit; > import org.eclipse.text.edits.ReplaceEdit; > import org.eclipse.text.edits.TextEdit; >@@ -96,6 +104,27 @@ > */ > public class ModelManagerImpl implements IModelManager { > >+ private static int WAIT_DELAY = getInt("org.eclipse.wst.sse.core.modelmanager.maxWaitDuringConcurrentLoad"); >+ private static boolean ALLOW_INTERRUPT_WAITING_THREAD = getBoolean("org.eclipse.wst.sse.core.modelmanager.allowInterruptsDuringConcurrentLoad"); >+ private static IEclipsePreferences.IPreferenceChangeListener LISTENER; >+ static { >+ InstanceScope scope = new InstanceScope(); >+ IEclipsePreferences instancePrefs = scope.getNode(SSECorePlugin.ID); >+ LISTENER = new IEclipsePreferences.IPreferenceChangeListener() { >+ >+ public void preferenceChange(PreferenceChangeEvent event) { >+ >+ if ("modelmanager.maxWaitDuringConcurrentLoad".equals(event.getKey())) { >+ WAIT_DELAY = getInt("org.eclipse.wst.sse.core.modelmanager.maxWaitDuringConcurrentLoad"); >+ } >+ else if ("modelmanager.allowInterruptsDuringConcurrentLoad".equals(event.getKey())) { >+ ALLOW_INTERRUPT_WAITING_THREAD = getBoolean("org.eclipse.wst.sse.core.modelmanager.allowInterruptsDuringConcurrentLoad"); >+ } >+ } >+ }; >+ instancePrefs.addPreferenceChangeListener(LISTENER); >+ } >+ > static class ReadEditType { > ReadEditType(String type) { > } >@@ -109,7 +138,8 @@ > int referenceCountForRead; > IStructuredModel theSharedModel; > boolean initializing = true; >- boolean doWait = true; >+ volatile boolean doWait = true; >+ final Object loadLock = new Object(); > > SharedObject(IStructuredModel sharedModel) { > theSharedModel = sharedModel; >@@ -124,13 +154,39 @@ > * is up-to-date. > */ > public synchronized void waitForLoadAttempt() { >- while(initializing) { >+ long start = System.currentTimeMillis(); >+ // Note: A WAIT_DELAY of 0 is infinite >+ int maxTimeMs = Math.max(0, WAIT_DELAY); >+ final int waitInterval = Math.min(250, maxTimeMs); >+ boolean interrupted = false; >+ while (initializing && maxTimeMs >= 0) { > try { >- wait(); >+ wait(waitInterval); >+ maxTimeMs -= waitInterval; > } > catch (InterruptedException e) { >- // ignore interruption! >+ interrupted = true; >+ if (ALLOW_INTERRUPT_WAITING_THREAD) { >+ break; >+ } >+ } >+ } >+ if (initializing) { >+ long totalWaitTime = System.currentTimeMillis() - start; >+ if (interrupted) { >+ throw new OperationCanceledException( >+ "Waiting thread interrupted during simultenous model load. Load aborted. (Waited " >+ + totalWaitTime + "ms)"); > } >+ else { >+ throw new OperationCanceledException( >+ "Waiting thread timed-out during simultenous model load. Load aborted. (Waited " >+ + totalWaitTime + "ms)"); >+ } >+ } >+ if (interrupted) { >+ // Propagate (don't swallow) the interrupt >+ Thread.currentThread().interrupt(); > } > } > >@@ -166,6 +222,12 @@ > return instance; > } > >+ public void removePreferenceListener() { >+ InstanceScope scope = new InstanceScope(); >+ IEclipsePreferences instancePrefs = scope.getNode(SSECorePlugin.ID); >+ instancePrefs.removePreferenceChangeListener(LISTENER); >+ } >+ > /** > * Our cache of managed objects > */ >@@ -183,9 +245,12 @@ > ModelManagerImpl() { > super(); > fManagedObjects = new HashMap(); >- // To prevent deadlocks: always acquire multiple locks in this order: SYNC, sharedObject. >- // DO NOT acquire a SYNC within a sharedObject lock, unless you already own the SYNC lock >- // Tip: Try to hold the smallest number of locks you can >+ /** >+ * NOTES: To prevent deadlocks: always acquire multiple locks in this >+ * order: SYNC->sharedObject.loadLock->sharedObject DO NOT acquire a >+ * SYNC within a sharedObject lock, unless you already own the SYNC lock >+ * Tip: Try to hold the smallest number of locks you can >+ */ > } > > private IStructuredModel _commonCreateModel(IFile file, String id, IModelHandler handler, URIResolver resolver, ReadEditType rwType, EncodingRule encodingRule) throws IOException,CoreException { >@@ -262,7 +327,7 @@ > SharedObject sharedObject) throws CoreException, IOException { > // XXX: Does not integrate with FileBuffers > boolean doRemove = false; >- synchronized(sharedObject) { >+ synchronized (sharedObject.loadLock) { > InputStream inputStream = null; > IStructuredModel model = null; > try { >@@ -283,9 +348,11 @@ > } > } > if (model != null) { >+ synchronized (sharedObject) { > // add to our cache > sharedObject.theSharedModel=model; > _initCount(sharedObject, rwType); >+ } > } else { > doRemove = true; > } >@@ -348,7 +415,7 @@ > URIResolver resolver, ReadEditType rwType, String encoding, String lineDelimiter, > SharedObject sharedObject) throws IOException { > boolean doRemove = false; >- synchronized(sharedObject) { >+ synchronized (sharedObject.loadLock) { > IStructuredModel model = null; > try { > model = _commonCreateModel(id, handler, resolver); >@@ -380,9 +447,10 @@ > ((AbstractStructuredModel) model).setContentTypeIdentifier(description.getContentType().getId()); > } > } >- >+ synchronized (sharedObject) { > sharedObject.theSharedModel = model; > _initCount(sharedObject, rwType); >+ } > } else { > doRemove = true; > } >@@ -492,13 +560,15 @@ > > private void _doCommonGetModel(IFile file, String id, SharedObject sharedObject,ReadEditType rwType) { > boolean doRemove = false; >- synchronized(sharedObject) { >+ synchronized (sharedObject.loadLock) { > sharedObject.doWait=false; > IStructuredModel model = FileBufferModelManager.getInstance().getModel(file); > sharedObject.doWait=true; > if (model != null) { >+ synchronized (sharedObject) { > sharedObject.theSharedModel=model; > _initCount(sharedObject, rwType); >+ } > } else { > doRemove = true; > } >@@ -582,10 +652,14 @@ > sharedObject = new SharedObject(null); > fManagedObjects.put(id, sharedObject); > SYNC.release(); >- synchronized(sharedObject) { >- sharedObject.theSharedModel = FileBufferModelManager.getInstance().getModel(document); >+ synchronized (sharedObject.loadLock) { >+ IStructuredModel model = FileBufferModelManager.getInstance() >+ .getModel(document); >+ synchronized (sharedObject) { >+ sharedObject.theSharedModel = model; > _initCount(sharedObject, accessType); > sharedObject.setLoaded(); >+ } > } > break; > } else if (sharedObject == testObject) { >@@ -2098,4 +2172,87 @@ > SYNC.release(); > return inUse; > } >+ >+ private static String getProperty(String property) { >+ // Preference overrides system property overrides env-var >+ >+ IPreferencesService preferencesService = Platform.getPreferencesService(); >+ IScopeContext[] lookupOrder = new IScopeContext[] { >+ new InstanceScope(), new ConfigurationScope() >+ }; >+ String key = property; >+ if (property != null && property.startsWith(SSECorePlugin.ID)) { >+ // +1, include the "." >+ key = property.substring(SSECorePlugin.ID.length() + 1, property.length()); >+ } >+ String value = preferencesService.getString(SSECorePlugin.ID, key, null, lookupOrder); >+ if (value == null) { >+ value = System.getProperty(property); >+ } >+ if (value == null) { >+ value = System.getenv(property); >+ } >+ return value; >+ } >+ >+ private static String getDefault(String property) { >+ // this is the "default-default" >+ if ("org.eclipse.wst.sse.core.modelmanager.maxWaitDuringConcurrentLoad".equals(property)) { >+ return "0"; >+ } >+ else if ("org.eclipse.wst.sse.core.modelmanager.allowInterruptsDuringConcurrentLoad" >+ .equals(property)) { >+ return "false"; >+ } >+ return null; >+ } >+ >+ private static boolean getBoolean(String key) { >+ String property = getProperty(key); >+ // if (property != null) { >+ // System.out.println("Tweak: " + key + "=" + Boolean.parseBoolean(property)); //$NON-NLS-1$ //$NON-NLS-2$ >+ // } >+ return property != null ? Boolean.parseBoolean(property) : Boolean >+ .parseBoolean(getDefault(key)); >+ } >+ >+ private static int getInt(String key) { >+ String property = getProperty(key); >+ int size = 0; >+ if (property != null) { >+ try { >+ size = Integer.parseInt(property); >+ // System.out.println("Tweak: " + key + "=" + size); //$NON-NLS-1$ //$NON-NLS-2$ >+ } >+ catch (NumberFormatException e) { >+ size = getDefaultInt(key, property, size); >+ } >+ } >+ else { >+ size = getDefaultInt(key, property, size); >+ } >+ return size; >+ } >+ >+ private static int getDefaultInt(String key, String property, int size) { >+ // ignored >+ try { >+ size = Integer.parseInt(getDefault(key)); >+ } >+ catch (NumberFormatException e1) { >+ handleIntParseException(key, property, e1); >+ size = 0; >+ } >+ return size; >+ } >+ >+ private static void handleIntParseException(String key, String property, >+ NumberFormatException e1) { >+ Exception n = new Exception( >+ NLS >+ .bind( >+ "Exception during parse of default value for key ''{0}'' value was ''{1}''. Using 0 instead", //$NON-NLS-1$ >+ key, property), e1); >+ n.printStackTrace(); >+ } > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 287096
:
144990
|
145676
|
145681
|
145821
|
145825
|
145829
|
146449
|
147495
|
147502
|
166062
|
166063