[364482] A race condition could occur in Server code
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java
index e05d4b9..81bcbbd 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2011 IBM Corporation and others.
+ * Copyright (c) 2003, 2012 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
@@ -83,6 +83,9 @@
// the list of modules that are to be published to the server
protected List<IModule> modules;
+
+ /** A lock that is used to synchronize access to modules. */
+ protected final Object modulesLock = new Object();
// the list of external modules
protected List<IModule> externalModules;
@@ -923,22 +926,28 @@
if (getModules().length < 0)
return false;
- // shallow search: check for root modules first
- boolean deployed = modules.contains(requestedModule);
+ boolean deployed = false;
- if(!deployed){
- // deep search: look into all the child modules
- Iterator<IModule> itr = modules.iterator();
- while(itr.hasNext() && !deployed){
- IModule[] m = new IModule[] {itr.next()};
- deployed = !visitModule(m, new IModuleVisitor(){
- public boolean visit(IModule[] modules2) {
- for (int i =0;i<=modules2.length-1;i++){
- if (modules2[i].equals(requestedModule))
- return false;
- }
- return true;
- }}, null);
+ synchronized (modulesLock){
+ // shallow search: check for root modules first
+ if (modules != null){
+ deployed = modules.contains(requestedModule);
+
+ if(!deployed){
+ // deep search: look into all the child modules
+ Iterator<IModule> itr = modules.iterator();
+ while(itr.hasNext() && !deployed){
+ IModule[] m = new IModule[] {itr.next()};
+ deployed = !visitModule(m, new IModuleVisitor(){
+ public boolean visit(IModule[] modules2) {
+ for (int i =0;i<=modules2.length-1;i++){
+ if (modules2[i].equals(requestedModule))
+ return false;
+ }
+ return true;
+ }}, null);
+ }
+ }
}
}
@@ -2372,7 +2381,9 @@
serverSyncState = wc.serverSyncState;
//restartNeeded = wc.restartNeeded;
serverType = wc.serverType;
- modules = wc.modules;
+ synchronized(modulesLock){
+ modules = wc.modules;
+ }
// can never modify the following properties via the working copy
//serverState = wc.serverState;
@@ -2438,13 +2449,26 @@
}
public void clearModuleCache() {
- modules = null;
+ synchronized (modulesLock){
+ modules = null;
+ }
}
/* (non-Javadoc)
* @see org.eclipse.wst.server.core.IServer#getModules()
*/
public IModule[] getModules() {
+ synchronized (modulesLock){
+ return getModulesWithoutLock();
+ }
+ }
+
+ /* (non-Javadoc)
+ * The implementation for getModules but this one does not lock the modules object. Caller is responsible for locking the modulesLock
+ * object when calling this method for thread safe implementation.
+ * @see org.eclipse.wst.server.core.IServer#getModules()
+ */
+ protected IModule[] getModulesWithoutLock() {
if (modules == null) {
// convert from attribute
List<String> list = getAttribute(MODULE_LIST, (List<String>) null);
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerWorkingCopy.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerWorkingCopy.java
index 33bd10e..40dd6bc 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerWorkingCopy.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerWorkingCopy.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2011 IBM Corporation and others.
+ * Copyright (c) 2003, 2012 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
@@ -552,51 +552,53 @@
wch.setDirty(true);
// trigger load of modules list
- getModules();
-
- if (add != null) {
- int size = add.length;
- for (int i = 0; i < size; i++) {
- if (!modules.contains(add[i])) {
- modules.add(add[i]);
- resetState(new IModule[] { add[i] }, monitor);
+ synchronized (modulesLock){
+ getModulesWithoutLock();
+ if (add != null) {
+ int size = add.length;
+ for (int i = 0; i < size; i++) {
+ if (!modules.contains(add[i])) {
+ modules.add(add[i]);
+ resetState(new IModule[] { add[i] }, monitor);
+ }
}
}
- }
-
- if (remove != null) {
- int size = remove.length;
- externalModules = getExternalModules();
- for (int i = 0; i < size; i++) {
- if (modules.contains(remove[i])) {
- modules.remove(remove[i]);
- resetState(new IModule[] { remove[i] }, monitor);
- }
- if (externalModules != null && externalModules.contains(remove[i])) {
- externalModules.remove(remove[i]);
- resetState(new IModule[] { remove[i] }, monitor);
+
+ if (remove != null) {
+ int size = remove.length;
+ externalModules = getExternalModules();
+ for (int i = 0; i < size; i++) {
+ if (modules.contains(remove[i])) {
+ modules.remove(remove[i]);
+ resetState(new IModule[] { remove[i] }, monitor);
+ }
+ if (externalModules != null && externalModules.contains(remove[i])) {
+ externalModules.remove(remove[i]);
+ resetState(new IModule[] { remove[i] }, monitor);
+ }
}
}
- }
-
- // convert to attribute
- List<String> list = new ArrayList<String>();
- Iterator iterator = modules.iterator();
- while (iterator.hasNext()) {
- IModule module = (IModule) iterator.next();
- StringBuffer sb = new StringBuffer(module.getName());
- sb.append("::");
- sb.append(module.getId());
- IModuleType mt = module.getModuleType();
- if (mt != null) {
+
+ // convert to attribute
+ List<String> list = new ArrayList<String>();
+ Iterator iterator = modules.iterator();
+ while (iterator.hasNext()) {
+ IModule module = (IModule) iterator.next();
+ StringBuffer sb = new StringBuffer(module.getName());
sb.append("::");
- sb.append(mt.getId());
- sb.append("::");
- sb.append(mt.getVersion());
+ sb.append(module.getId());
+ IModuleType mt = module.getModuleType();
+ if (mt != null) {
+ sb.append("::");
+ sb.append(mt.getId());
+ sb.append("::");
+ sb.append(mt.getVersion());
+ }
+ list.add(sb.toString());
}
- list.add(sb.toString());
+ setAttribute(MODULE_LIST, list);
}
- setAttribute(MODULE_LIST, list);
+
resetOptionalPublishOperations();
resetPreferredPublishOperations();
} catch (CoreException ce) {