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 177601 Details for
Bug 307587
NatureManager is NOT threadsafe causing incorrect responses to isNatureEnabled() (and others)
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]
Proposal v02
307587_20100827.txt (text/plain), 10.46 KB, created by
Szymon Brandys
on 2010-08-27 05:49:13 EDT
(
hide
)
Description:
Proposal v02
Filename:
MIME Type:
Creator:
Szymon Brandys
Created:
2010-08-27 05:49:13 EDT
Size:
10.46 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.core.resources >Index: src/org/eclipse/core/internal/resources/NatureManager.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/NatureManager.java,v >retrieving revision 1.30 >diff -u -r1.30 NatureManager.java >--- src/org/eclipse/core/internal/resources/NatureManager.java 3 Dec 2007 04:54:22 -0000 1.30 >+++ src/org/eclipse/core/internal/resources/NatureManager.java 27 Aug 2010 09:48:40 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2007 IBM Corporation and others. >+ * Copyright (c) 2000, 2010 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -25,14 +25,14 @@ > */ > public class NatureManager implements ILifecycleListener, IManager { > //maps String (nature ID) -> descriptor objects >- protected Map descriptors; >+ private Map descriptors; > > //maps IProject -> String[] of enabled natures for that project >- protected Map natureEnablements; >+ private Map natureEnablements; > > //maps String (builder ID) -> String (nature ID) >- protected Map buildersToNatures = null; >- //colour constants used in cycle detection algorithm >+ private Map buildersToNatures = null; >+ //color constants used in cycle detection algorithm > private static final byte WHITE = 0; > private static final byte GREY = 1; > private static final byte BLACK = 2; >@@ -43,10 +43,10 @@ > > /** > * Computes the list of natures that are enabled for the given project. >- * Enablement computation is subtlely different from nature set >+ * Enablement computation is subtlety different from nature set > * validation, because it must find and remove all inconsistencies. > */ >- protected String[] computeNatureEnablements(Project project) { >+ private String[] computeNatureEnablements(Project project) { > final ProjectDescription description = project.internalGetDescription(); > if (description == null) > return new String[0];//project deleted concurrently >@@ -136,7 +136,7 @@ > /** > * Configures the nature with the given ID for the given project. > */ >- protected void configureNature(final Project project, final String natureID, final MultiStatus errors) { >+ private void configureNature(final Project project, final String natureID, final MultiStatus errors) { > ISafeRunnable code = new ISafeRunnable() { > public void run() throws Exception { > IProjectNature nature = createNature(project, natureID); >@@ -240,7 +240,7 @@ > /** > * Deconfigures the nature with the given ID for the given project. > */ >- protected void deconfigureNature(final Project project, final String natureID, final MultiStatus status) { >+ private void deconfigureNature(final Project project, final String natureID, final MultiStatus status) { > final ProjectInfo info = (ProjectInfo) project.getResourceInfo(false, true); > IProjectNature existingNature = info.getNature(natureID); > if (existingNature == null) { >@@ -275,8 +275,8 @@ > /** > * Marks all nature descriptors that are involved in cycles > */ >- protected void detectCycles() { >- Collection values = descriptors.values(); >+ private void detectCycles(Map tempDescriptors) { >+ Collection values = tempDescriptors.values(); > ProjectNatureDescriptor[] natures = (ProjectNatureDescriptor[]) values.toArray(new ProjectNatureDescriptor[values.size()]); > for (int i = 0; i < natures.length; i++) > if (natures[i].colour == WHITE) >@@ -286,7 +286,7 @@ > /** > * Returns a status indicating failure to configure natures. > */ >- protected IStatus failure(String reason) { >+ private IStatus failure(String reason) { > return new ResourceStatus(IResourceStatus.INVALID_NATURE_SET, reason); > } > >@@ -296,21 +296,26 @@ > */ > public String findNatureForBuilder(String builderID) { > if (buildersToNatures == null) { >- buildersToNatures = new HashMap(10); >- IProjectNatureDescriptor[] descs = getNatureDescriptors(); >- for (int i = 0; i < descs.length; i++) { >- String natureId = descs[i].getNatureId(); >- String[] builders = ((ProjectNatureDescriptor) descs[i]).getBuilderIds(); >- for (int j = 0; j < builders.length; j++) { >- //FIXME: how to handle multiple natures specifying same builder >- buildersToNatures.put(builders[j], natureId); >+ synchronized (this) { >+ if (buildersToNatures == null) { >+ Map tempNatureForBuilders = new HashMap(10); >+ IProjectNatureDescriptor[] descs = getNatureDescriptors(); >+ for (int i = 0; i < descs.length; i++) { >+ String natureId = descs[i].getNatureId(); >+ String[] builders = ((ProjectNatureDescriptor) descs[i]).getBuilderIds(); >+ for (int j = 0; j < builders.length; j++) { >+ //FIXME: how to handle multiple natures specifying same builder >+ tempNatureForBuilders.put(builders[j], natureId); >+ } >+ } >+ buildersToNatures = tempNatureForBuilders; > } > } > } > return (String) buildersToNatures.get(builderID); > } > >- protected void flushEnablements(IProject project) { >+ private synchronized void flushEnablements(IProject project) { > if (natureEnablements != null) { > natureEnablements.remove(project); > if (natureEnablements.size() == 0) { >@@ -323,7 +328,7 @@ > * Returns the cached array of enabled natures for this project, > * or null if there is nothing in the cache. > */ >- protected String[] getEnabledNatures(Project project) { >+ protected synchronized String[] getEnabledNatures(Project project) { > String[] enabled; > if (natureEnablements != null) { > enabled = (String[]) natureEnablements.get(project); >@@ -340,7 +345,7 @@ > * dependencies starting at root i. Returns false otherwise. > * Marks all descriptors that are involved in the cycle as invalid. > */ >- protected boolean hasCycles(ProjectNatureDescriptor desc) { >+ private boolean hasCycles(ProjectNatureDescriptor desc) { > if (desc.colour == BLACK) { > //this subgraph has already been traversed, so we know the answer > return desc.hasCycle; >@@ -373,7 +378,7 @@ > /** > * Returns true if the given project has linked resources, and false otherwise. > */ >- protected boolean hasLinks(IProject project) { >+ private boolean hasLinks(IProject project) { > try { > IResource[] children = project.members(); > for (int i = 0; i < children.length; i++) >@@ -391,7 +396,7 @@ > * memberships. Returns the name of one such overlap, or null if > * there is no set overlap. > */ >- protected String hasSetOverlap(IProjectNatureDescriptor one, IProjectNatureDescriptor two) { >+ private String hasSetOverlap(IProjectNatureDescriptor one, IProjectNatureDescriptor two) { > if (one == null || two == null) { > return null; > } >@@ -411,7 +416,7 @@ > /** > * Perform depth-first insertion of the given nature ID into the result list. > */ >- protected void insert(ArrayList list, Set seen, String id) { >+ private void insert(ArrayList list, Set seen, String id) { > if (seen.contains(id)) > return; > seen.add(id); >@@ -443,31 +448,36 @@ > * Only initialize the descriptor cache when we know it is actually needed. > * Running programs may never need to refer to this cache. > */ >- protected void lazyInitialize() { >+ private void lazyInitialize() { > if (descriptors != null) > return; >- IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(ResourcesPlugin.PI_RESOURCES, ResourcesPlugin.PT_NATURES); >- IExtension[] extensions = point.getExtensions(); >- descriptors = new HashMap(extensions.length * 2 + 1); >- for (int i = 0, imax = extensions.length; i < imax; i++) { >- IProjectNatureDescriptor desc = null; >- try { >- desc = new ProjectNatureDescriptor(extensions[i]); >- } catch (CoreException e) { >- Policy.log(e.getStatus()); >+ synchronized (this) { >+ if (descriptors != null) >+ return; >+ IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(ResourcesPlugin.PI_RESOURCES, ResourcesPlugin.PT_NATURES); >+ IExtension[] extensions = point.getExtensions(); >+ Map tempDescriptors = new HashMap(extensions.length * 2 + 1); >+ for (int i = 0, imax = extensions.length; i < imax; i++) { >+ IProjectNatureDescriptor desc = null; >+ try { >+ desc = new ProjectNatureDescriptor(extensions[i]); >+ } catch (CoreException e) { >+ Policy.log(e.getStatus()); >+ } >+ if (desc != null) >+ tempDescriptors.put(desc.getNatureId(), desc); > } >- if (desc != null) >- descriptors.put(desc.getNatureId(), desc); >+ //do cycle detection now so it only has to be done once >+ //cycle detection on a graph subset is a pain >+ detectCycles(tempDescriptors); >+ descriptors = tempDescriptors; > } >- //do cycle detection now so it only has to be done once >- //cycle detection on a graph subset is a pain >- detectCycles(); > } > > /** > * Sets the cached array of enabled natures for this project. > */ >- protected void setEnabledNatures(IProject project, String[] enablements) { >+ private void setEnabledNatures(IProject project, String[] enablements) { > if (natureEnablements == null) > natureEnablements = Collections.synchronizedMap(new HashMap(20)); > natureEnablements.put(project, enablements); >@@ -513,7 +523,7 @@ > * @return An OK status if all additions are valid, and an error status > * if any of the additions introduce new inconsistencies. > */ >- protected IStatus validateAdditions(HashSet newNatures, HashSet additions, IProject project) { >+ private IStatus validateAdditions(HashSet newNatures, HashSet additions, IProject project) { > Boolean hasLinks = null;//three states: true, false, null (not yet computed) > //perform checks in order from least expensive to most expensive > for (Iterator added = additions.iterator(); added.hasNext();) { >@@ -585,7 +595,7 @@ > * @return An OK status if all removals are valid, and a not OK status > * if any of the deletions introduce new inconsistencies. > */ >- protected IStatus validateRemovals(HashSet newNatures, HashSet deletions) { >+ private IStatus validateRemovals(HashSet newNatures, HashSet deletions) { > //iterate over new nature set, and ensure that none of their prerequisites are being deleted > for (Iterator it = newNatures.iterator(); it.hasNext();) { > String currentID = (String) it.next();
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 307587
:
177513
|
177601
|
177612
|
177643
|
185251
|
185303
|
188503
|
188516
|
189502
|
189520