[FELIX-4363] The CommandSession get/set methods are not thread safe
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1552136 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/CommandProcessorImpl.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/CommandProcessorImpl.java
index b48ec1c..65eebcf 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/CommandProcessorImpl.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/CommandProcessorImpl.java
@@ -42,7 +42,7 @@
public class CommandProcessorImpl implements CommandProcessor
{
- protected final Set<Converter> converters = new HashSet<Converter>();
+ protected final Set<Converter> converters = new CopyOnWriteArraySet<Converter>();
protected final Set<CommandSessionListener> listeners = new CopyOnWriteArraySet<CommandSessionListener>();
protected final Map<String, Object> commands = new LinkedHashMap<String, Object>();
protected final Map<String, Object> constants = new HashMap<String, Object>();
@@ -56,16 +56,22 @@
public CommandSession createSession(InputStream in, PrintStream out, PrintStream err)
{
- CommandSessionImpl session = new CommandSessionImpl(this, in, out, err);
- sessions.put(session, null);
- return session;
+ synchronized (sessions)
+ {
+ CommandSessionImpl session = new CommandSessionImpl(this, in, out, err);
+ sessions.put(session, null);
+ return session;
+ }
}
public void stop()
{
- for (CommandSession session : sessions.keySet())
+ synchronized (sessions)
{
- session.close();
+ for (CommandSession session : sessions.keySet())
+ {
+ session.close();
+ }
}
}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/CommandSessionImpl.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/CommandSessionImpl.java
index 447e735..3f6d435 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/CommandSessionImpl.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/CommandSessionImpl.java
@@ -27,11 +27,14 @@
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Formatter;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import org.apache.felix.service.command.CommandSession;
import org.apache.felix.service.command.Converter;
@@ -50,7 +53,7 @@
PrintStream err;
private final CommandProcessorImpl processor;
- protected final Map<String, Object> variables = new HashMap<String, Object>();
+ protected final Map<String, Object> variables = new ConcurrentHashMap<String, Object>();
private boolean closed;
protected CommandSessionImpl(CommandProcessorImpl shell, InputStream in, PrintStream out, PrintStream err)
@@ -107,7 +110,7 @@
// there is no API to list all variables, so overload name == null
if (name == null || VARIABLES.equals(name))
{
- return variables.keySet();
+ return Collections.unmodifiableSet(variables.keySet());
}
if (COMMANDS.equals(name))
@@ -115,30 +118,34 @@
return processor.getCommands();
}
- if( processor.constants.containsKey(name) )
+ Object val = processor.constants.get(name);
+ if( val != null )
{
- return processor.constants.get(name);
+ return val;
}
- if (variables.containsKey("#" + name))
+ val = variables.get("#" + name);
+ if (val instanceof Function)
{
- Object f = variables.get("#" + name);
- if (f instanceof Function)
+ try
{
- try
- {
- f = ((Function) f).execute(this, null);
- }
- catch (Exception e)
- {
- // Ignore
- }
+ val = ((Function) val).execute(this, null);
}
- return f;
+ catch (Exception e)
+ {
+ // Ignore
+ }
+ return val;
}
- if (variables.containsKey(name))
+ else if( val != null )
{
- return variables.get(name);
+ return val;
+ }
+
+ val = variables.get(name);
+ if( val != null )
+ {
+ return val;
}
return processor.getCommand(name, variables.get("SCOPE"));