1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-07 00:05:53 +02:00

[218309] ConcurrentModificationException during workbench startup

This commit is contained in:
Martin Oberhuber 2008-10-30 19:09:26 +00:00
parent 4d6b86fe3b
commit 953aeeb8ec
3 changed files with 133 additions and 107 deletions

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<component id="org.eclipse.rse.core" version="2">
<resource path="src/org/eclipse/rse/core/subsystems/ISubSystemConfiguration.java" type="org.eclipse.rse.core.subsystems.ISubSystemConfiguration">
<filter id="406052990">
<message_arguments>
<message_argument value="org.eclipse.rse.core.subsystems.ISubSystemConfiguration"/>
<message_argument value="getFilterPoolManagerList()"/>
</message_arguments>
</filter>
<filter id="406052990">
<message_arguments>
<message_argument value="org.eclipse.rse.core.subsystems.ISubSystemConfiguration"/>
<message_argument value="getSubSystemList()"/>
</message_arguments>
</filter>
</resource>
</component>

View file

@ -21,10 +21,13 @@
* Martin Oberhuber (Wind River) - [cleanup] Add API "since" Javadoc tags * Martin Oberhuber (Wind River) - [cleanup] Add API "since" Javadoc tags
* David Dykstal (IBM) - [168976][api] move ISystemNewConnectionWizardPage from core to UI * David Dykstal (IBM) - [168976][api] move ISystemNewConnectionWizardPage from core to UI
* Martin Oberhuber (Wind River) - [226574][api] Add ISubSystemConfiguration#supportsEncoding() * Martin Oberhuber (Wind River) - [226574][api] Add ISubSystemConfiguration#supportsEncoding()
* Martin Oberhuber (Wind River) - [218309] ConcurrentModificationException during workbench startup
********************************************************************************/ ********************************************************************************/
package org.eclipse.rse.core.subsystems; package org.eclipse.rse.core.subsystems;
import java.util.List;
import org.eclipse.rse.core.IRSESystemType; import org.eclipse.rse.core.IRSESystemType;
import org.eclipse.rse.core.filters.ISystemFilter; import org.eclipse.rse.core.filters.ISystemFilter;
import org.eclipse.rse.core.filters.ISystemFilterPool; import org.eclipse.rse.core.filters.ISystemFilterPool;
@ -696,18 +699,30 @@ public interface ISubSystemConfiguration extends ISystemFilterPoolManagerProvide
public void saveSubSystem(ISubSystem subsys) throws Exception; public void saveSubSystem(ISubSystem subsys) throws Exception;
/** /**
* <i><b>Private</b>. Do not call or use.</i><br> * Return the internal list of subsystems instantiated for this
* @generated This field/method will be replaced during code generation * configuration. Internal use only, do not call or use. Use
* @return The list of SubSystemList references * {@link #getSubSystems(boolean)} with a <code>false</code> argument
* instead.
*
* @noreference This method is not intended to be referenced by clients.
* @return The internal list of SubSystem instances for this configuration.
* Any operations on this list (such as iterating, adding or
* removing members) must always be synchronized against the list,
* in order to protect against concurrent modification.
*/ */
java.util.List getSubSystemList(); List getSubSystemList();
/** /**
* <i><b>Private</b>. Do not call or use.</i><br> * Return the internal list of filter pool managers associated with this
* @generated This field/method will be replaced during code generation * configuration. Internal use only, do not call or use.
* @return The list of FilterPoolManagerList references *
* @noreference This method is not intended to be referenced by clients.
* @return The internal list of filter pool Managers associated with this
* configuration. Any operations on this list (such as iterating,
* adding or removing members) must always be synchronized against
* the list, in order to protect against concurrent modification.
*/ */
java.util.List getFilterPoolManagerList(); List getFilterPoolManagerList();
public ISystemFilterPool getDefaultFilterPool(ISystemProfile profile, String oldProfileName); public ISystemFilterPool getDefaultFilterPool(ISystemProfile profile, String oldProfileName);

View file

@ -36,6 +36,7 @@
* David Dykstal (IBM) - [168976][api] move ISystemNewConnectionWizardPage from core to UI * David Dykstal (IBM) - [168976][api] move ISystemNewConnectionWizardPage from core to UI
* Martin Oberhuber (Wind River) - [226574][api] Add ISubSystemConfiguration#supportsEncoding() * Martin Oberhuber (Wind River) - [226574][api] Add ISubSystemConfiguration#supportsEncoding()
* David Dykstal (IBM) - [236516] Bug in user code causes failure in RSE initialization * David Dykstal (IBM) - [236516] Bug in user code causes failure in RSE initialization
* Martin Oberhuber (Wind River) - [218309] ConcurrentModificationException during workbench startup
********************************************************************************/ ********************************************************************************/
package org.eclipse.rse.core.subsystems; package org.eclipse.rse.core.subsystems;
@ -44,7 +45,6 @@ import java.util.ArrayList;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Vector;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor;
@ -89,12 +89,11 @@ import org.eclipse.rse.ui.SystemBasePlugin;
import org.eclipse.rse.ui.SystemPreferencesManager; import org.eclipse.rse.ui.SystemPreferencesManager;
import org.eclipse.rse.ui.messages.SystemMessageDialog; import org.eclipse.rse.ui.messages.SystemMessageDialog;
/** /**
* Abstract base class for subsystem configuration extension points. * Abstract base class for subsystem configuration extension points.
* Child classes must implement the methods: * Child classes must implement the methods:
* <ul> * <ul>
* <li>#createSubSystemInternal(SystemConnection conn) * <li>#createSubSystemInternal(SystemConnection conn)
* </ul> * </ul>
* Child classes can optionally override: * Child classes can optionally override:
* <ul> * <ul>
@ -111,17 +110,18 @@ import org.eclipse.rse.ui.messages.SystemMessageDialog;
* <li>SubSystemConfiguration#getSubSystemActions() if they wish to supply actions for the right-click menu when * <li>SubSystemConfiguration#getSubSystemActions() if they wish to supply actions for the right-click menu when
* the user right clicks on a subsystem object created by this subsystem configuration. * the user right clicks on a subsystem object created by this subsystem configuration.
* <li>CreateDefaultFilterPool() to create any default filter pool when a new profile is created. * <li>CreateDefaultFilterPool() to create any default filter pool when a new profile is created.
* <li>#initializeSubSystem(SubSystem ss, configurarators[]) * <li>#initializeSubSystem(SubSystem ss, configurarators[])
* </ul> * </ul>
* <p> * <p>
* A subsystem configuration will maintain in memory a list of all subsystem objects it has. This * A subsystem configuration will maintain in memory a list of all subsystem
* list should be initialize from disk at restore time, and maintained as the subsystems are * objects it has. This list should be initialized from disk at restore time,
* created and deleted throughout the session. At save time, each subsystem in the list * and maintained as the subsystems are created and deleted throughout the
* is asked to save itself. The getSubSystems method should return this list. * session. At save time, each subsystem in the list is asked to save itself.
* The getSubSystems method should return this list.
* <p> * <p>
* To help with maintaining this list, this base class contains a Vector instance variable * To help with maintaining this list, this base class contains a List instance
* named subsystems. It is returned by the getSubSystems method in this base class. For this * variable named subsystems. It is returned by the getSubSystems method in this
* to be accurate you though, you should: * base class. For this to be accurate you though, you should:
* <ul> * <ul>
* <li>Not implement createSubSystem directly, but rather let this class handle it. Instead * <li>Not implement createSubSystem directly, but rather let this class handle it. Instead
* implement the method createSubSystemInternal. This is called by createSubSystem in this * implement the method createSubSystemInternal. This is called by createSubSystem in this
@ -155,8 +155,25 @@ public abstract class SubSystemConfiguration implements ISubSystemConfiguration
protected static IHost currentlyProcessingConnection; protected static IHost currentlyProcessingConnection;
protected static SubSystemConfiguration currentlyProcessingSubSystemConfiguration; protected static SubSystemConfiguration currentlyProcessingSubSystemConfiguration;
protected java.util.List subSystemList = null; /**
protected java.util.List filterPoolManagerList = null; * Internal list of subsystems. Must always be accessed in synchronized
* blocks to protect against concurrent modification. For API compliance,
* clients should always call {@link #getSubSystemList()} instead of
* accessing this field directly.
*
* @noreference This field is not intended to be referenced by clients.
*/
protected List subSystemList = new ArrayList();
/**
* Internal list of filter pool managers. Must always be accessed in
* synchronized blocks. For API compliance, clients should always call
* {@link #getFilterPoolManagerList()} instead of accessing this field
* directly.
*
* @noreference This field is not intended to be referenced by clients.
*/
protected List filterPoolManagerList = new ArrayList();
// protected boolean _isDirty; // protected boolean _isDirty;
@ -805,23 +822,20 @@ public abstract class SubSystemConfiguration implements ISubSystemConfiguration
allSubSystemsRestored = true; allSubSystemsRestored = true;
subsystems = null; // force re-gen subsystems = null; // force re-gen
} }
if ((subsystems == null) || (subsystems.length != getSubSystemList().size())) // compute cache in local variable in order to avoid modification by other Thread
{ ISubSystem[] result = subsystems;
List alist = null; List subSysList = getSubSystemList();
if (SystemProfileManager.getDefault().getSize() > 0) // 42913 synchronized (subSysList) {
alist = getSubSystemList(); if ((result == null) || (result.length != subSysList.size()))
if (alist == null)
return new ISubSystem[0];
Iterator i = alist.iterator();
subsystems = new ISubSystem[alist.size()];
int idx = 0;
while (i.hasNext())
{ {
ISubSystem subsys = (ISubSystem) i.next(); // TODO Huh? I do not understand this...
subsystems[idx++] = subsys; if (SystemProfileManager.getDefault().getSize() <= 0) // 42913
return EMPTY_SUBSYSTEM_ARRAY;
result = (ISubSystem[]) subSysList.toArray(new ISubSystem[subSysList.size()]);
subsystems = result;
} }
} }
return subsystems; return result;
} }
/** /**
@ -879,19 +893,17 @@ public abstract class SubSystemConfiguration implements ISubSystemConfiguration
*/ */
protected ISubSystem[] internalGetSubSystems(IHost conn) protected ISubSystem[] internalGetSubSystems(IHost conn)
{ {
java.util.List mofList = getSubSystemList(); List subSysList = getSubSystemList();
Iterator i = mofList.iterator(); synchronized (subSysList) {
Vector v = new Vector(); List result = new ArrayList();
while (i.hasNext()) for (Iterator i = subSysList.iterator(); i.hasNext();) {
{ ISubSystem subsys = (ISubSystem) i.next();
ISubSystem subsys = (ISubSystem) i.next(); // TODO why == and not equals() here?
if (subsys.getHost() == conn) if (subsys.getHost() == conn)
v.addElement(subsys); result.add(subsys);
}
return (ISubSystem[]) result.toArray(new ISubSystem[result.size()]);
} }
ISubSystem[] array = new ISubSystem[v.size()];
for (int idx = 0; idx < v.size(); idx++)
array[idx] = (ISubSystem) v.elementAt(idx);
return array;
} }
/** /**
* Returns a list of subsystem objects existing for all the connections in the * Returns a list of subsystem objects existing for all the connections in the
@ -900,16 +912,15 @@ public abstract class SubSystemConfiguration implements ISubSystemConfiguration
public ISubSystem[] getSubSystems(ISystemProfile profile) public ISubSystem[] getSubSystems(ISystemProfile profile)
{ {
ISubSystem[] allSubSystems = getSubSystems(true); ISubSystem[] allSubSystems = getSubSystems(true);
Vector v = new Vector(); List l = new ArrayList();
for (int idx = 0; idx < allSubSystems.length; idx++) for (int idx = 0; idx < allSubSystems.length; idx++)
{ {
ISubSystem ss = allSubSystems[idx]; ISubSystem ss = allSubSystems[idx];
// TODO why == and not equals() here?
if (ss.getSystemProfile() == profile) if (ss.getSystemProfile() == profile)
v.addElement(ss); l.add(ss);
} }
ISubSystem[] subsystems = new ISubSystem[v.size()]; ISubSystem[] subsystems = (ISubSystem[]) l.toArray(new ISubSystem[l.size()]);
for (int idx = 0; idx < v.size(); idx++)
subsystems[idx] = (ISubSystem) v.elementAt(idx);
return subsystems; return subsystems;
} }
/** /**
@ -919,18 +930,16 @@ public abstract class SubSystemConfiguration implements ISubSystemConfiguration
public ISubSystem[] getSubSystems(ISystemFilterPool pool) public ISubSystem[] getSubSystems(ISystemFilterPool pool)
{ {
ISubSystem[] allSubSystems = getSubSystems(false); // // false=> lazy get; don't restore from disk if not already ISubSystem[] allSubSystems = getSubSystems(false); // // false=> lazy get; don't restore from disk if not already
Vector v = new Vector(); List l = new ArrayList();
for (int idx = 0; idx < allSubSystems.length; idx++) for (int idx = 0; idx < allSubSystems.length; idx++)
{ {
ISystemFilterPoolReferenceManager mgr = subsystems[idx].getSystemFilterPoolReferenceManager(); ISystemFilterPoolReferenceManager mgr = allSubSystems[idx].getSystemFilterPoolReferenceManager();
if ((mgr != null) && (mgr.isSystemFilterPoolReferenced(pool))) if ((mgr != null) && (mgr.isSystemFilterPoolReferenced(pool)))
{ {
v.addElement(allSubSystems[idx]); l.add(allSubSystems[idx]);
} }
} }
ISubSystem[] subsystems = new ISubSystem[v.size()]; ISubSystem[] subsystems = (ISubSystem[]) l.toArray(new ISubSystem[l.size()]);
for (int idx = 0; idx < v.size(); idx++)
subsystems[idx] = (ISubSystem) v.elementAt(idx);
return subsystems; return subsystems;
} }
@ -940,7 +949,10 @@ public abstract class SubSystemConfiguration implements ISubSystemConfiguration
*/ */
protected void addSubSystem(ISubSystem subsys) protected void addSubSystem(ISubSystem subsys)
{ {
getSubSystemList().add(subsys); List subSysList = getSubSystemList();
synchronized (subSysList) {
subSysList.add(subsys);
}
} }
/** /**
@ -949,15 +961,10 @@ public abstract class SubSystemConfiguration implements ISubSystemConfiguration
*/ */
protected void removeSubSystem(ISubSystem subsys) protected void removeSubSystem(ISubSystem subsys)
{ {
getSubSystemList().remove(subsys); List subSysList = getSubSystemList();
/* FIXME synchronized (subSysList) {
// now in EMF, the profiles are "owned" by the Resource, and only referenced by the profile manager, subSysList.remove(subsys);
// so I don't think just removing it from the manager is enough... it must also be removed from its }
// resource. Phil.
Resource res = subsys.eResource();
if (res != null)
res.getContents().remove(subsys);
*/
} }
/** /**
@ -1580,13 +1587,11 @@ public abstract class SubSystemConfiguration implements ISubSystemConfiguration
*/ */
public ISystemFilterPoolManager[] getFilterPoolManagers() public ISystemFilterPoolManager[] getFilterPoolManagers()
{ {
if ((filterPoolManagers == null) || (filterPoolManagers.length != getFilterPoolManagerList().size())) List fpManagers = getFilterPoolManagerList();
{ synchronized (fpManagers) {
filterPoolManagers = new ISystemFilterPoolManager[getFilterPoolManagerList().size()]; if ((filterPoolManagers == null) || (filterPoolManagers.length != fpManagers.size())) {
Iterator i = getFilterPoolManagerList().iterator(); filterPoolManagers = (ISystemFilterPoolManager[]) fpManagers.toArray(new ISystemFilterPoolManager[fpManagers.size()]);
int idx = 0; }
while (i.hasNext())
filterPoolManagers[idx++] = (ISystemFilterPoolManager) i.next();
} }
return filterPoolManagers; return filterPoolManagers;
} }
@ -1771,8 +1776,11 @@ public abstract class SubSystemConfiguration implements ISubSystemConfiguration
*/ */
protected void addFilterPoolManager(ISystemProfile profile, ISystemFilterPoolManager mgr) protected void addFilterPoolManager(ISystemProfile profile, ISystemFilterPoolManager mgr)
{ {
filterPoolManagersPerProfile.put(profile, mgr); List fpManagers = getFilterPoolManagerList();
getFilterPoolManagerList().add(mgr); // MOF generated list synchronized (fpManagers) {
filterPoolManagersPerProfile.put(profile, mgr);
fpManagers.add(mgr);
}
invalidateFilterCache(); // force regen of any cached lists invalidateFilterCache(); // force regen of any cached lists
} }
/** /**
@ -1827,10 +1835,13 @@ public abstract class SubSystemConfiguration implements ISubSystemConfiguration
if (mgr != null) if (mgr != null)
{ {
mgr.deleteAllSystemFilterPools(); // blow 'em all away, and de-reference anybody referencing any of them mgr.deleteAllSystemFilterPools(); // blow 'em all away, and de-reference anybody referencing any of them
filterPoolManagersPerProfile.remove(profile); List fpManagers = getFilterPoolManagerList();
synchronized (fpManagers) {
filterPoolManagersPerProfile.remove(profile);
fpManagers.remove(mgr);
}
invalidateFilterCache();
} }
getFilterPoolManagerList().remove(mgr);
invalidateFilterCache();
} }
/** /**
* Rename the filter pool manager associated with the given profile * Rename the filter pool manager associated with the given profile
@ -2248,7 +2259,7 @@ public abstract class SubSystemConfiguration implements ISubSystemConfiguration
*/ */
public ISubSystem[] testForActiveReferences(ISystemProfile profile) public ISubSystem[] testForActiveReferences(ISystemProfile profile)
{ {
Vector v = new Vector(); List l = new ArrayList();
ISystemProfileManager profileMgr = SystemProfileManager.getDefault(); ISystemProfileManager profileMgr = SystemProfileManager.getDefault();
ISystemFilterPoolManager sfpm = getFilterPoolManager(profile); ISystemFilterPoolManager sfpm = getFilterPoolManager(profile);
String profileName = profile.getName(); String profileName = profile.getName();
@ -2272,7 +2283,7 @@ public abstract class SubSystemConfiguration implements ISubSystemConfiguration
String ssProfileName = subsystem.getSystemProfileName(); String ssProfileName = subsystem.getSystemProfileName();
if ((!ssProfileName.equals(profileName)) && (profileMgr.isSystemProfileActive(ssProfileName))) if ((!ssProfileName.equals(profileName)) && (profileMgr.isSystemProfileActive(ssProfileName)))
{ {
v.addElement(subsystem); l.add(subsystem);
} }
} }
} }
@ -2282,11 +2293,9 @@ public abstract class SubSystemConfiguration implements ISubSystemConfiguration
} }
ISubSystem[] referencingSubSystems = null; ISubSystem[] referencingSubSystems = null;
if (v.size() > 0) if (l.size() > 0)
{ {
referencingSubSystems = new ISubSystem[v.size()]; referencingSubSystems = (ISubSystem[]) l.toArray(new ISubSystem[l.size()]);
for (int idx = 0; idx < referencingSubSystems.length; idx++)
referencingSubSystems[idx] = (ISubSystem) v.elementAt(idx);
} }
return referencingSubSystems; return referencingSubSystems;
@ -2709,28 +2718,13 @@ public abstract class SubSystemConfiguration implements ISubSystemConfiguration
return proxy.toString(); return proxy.toString();
} }
/** public List getSubSystemList()
* @generated This field/method will be replaced during code generation
*/
public java.util.List getSubSystemList()
{ {
if (subSystemList == null)
{
subSystemList = new ArrayList();
//FIXME new EObjectResolvingeList(SubSystem.class, this, SubsystemsPackage.SUB_SYSTEM_FACTORY__SUB_SYSTEM_LIST);
}
return subSystemList; return subSystemList;
} }
/** public List getFilterPoolManagerList()
* @generated This field/method will be replaced during code generation
*/
public java.util.List getFilterPoolManagerList()
{ {
if (filterPoolManagerList == null)
{
filterPoolManagerList = new ArrayList();
}
return filterPoolManagerList; return filterPoolManagerList;
} }