From ac8c6c0d9bb921166697e9b13009f9ff83ba9716 Mon Sep 17 00:00:00 2001 From: jestin Date: Thu, 26 Apr 2012 15:26:33 +0000 Subject: Goes to a set of synchronized collections (Map, HashMap, ...) to try and avoid multithreaded issues ... --- src/Ivy.java | 95 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 33 deletions(-) (limited to 'src/Ivy.java') diff --git a/src/Ivy.java b/src/Ivy.java index 2196321..b727c2a 100755 --- a/src/Ivy.java +++ b/src/Ivy.java @@ -15,6 +15,8 @@ * * * CHANGELOG: + * 1.2.16 + * - now uses the synchronized wrappers of the Java API for all collections * 1.2.15 * - allows the fine tuning of the IvyClient socket buffersize using * IVY_BUFFERSIZE property @@ -125,9 +127,14 @@ package fr.dgac.ivy; import java.net.*; import java.io.*; -import java.util.*; import gnu.getopt.Getopt; import java.util.regex.*; +import java.util.Vector; +import java.util.Collections; +import java.util.Map; +import java.util.HashMap; +import java.util.Properties; +import java.util.StringTokenizer; public class Ivy implements Runnable { @@ -157,7 +164,7 @@ public class Ivy implements Runnable { * the library version, useful for development purposes only, when java is * invoked with -DIVY_DEBUG */ - public static final String LIBVERSION ="1.2.15"; + public static final String LIBVERSION ="1.2.16"; public static final int TIMEOUTLENGTH = 1000; private String appName; @@ -171,8 +178,8 @@ public class Ivy implements Runnable { private ServerSocket app; private Vector watchers = new Vector(); private volatile Thread serverThread; // to ensure quick communication of the end - private Hashtable clients = new Hashtable(); - private Hashtable half = new Hashtable(); + private Map clients = Collections.synchronizedMap(new HashMap()); + private Map half = Collections.synchronizedMap(new HashMap()); private Vector ivyApplicationListenerList = new Vector(); private Vector ivyBindListenerList = new Vector(); private Vector sendThreads = new Vector(); @@ -265,9 +272,11 @@ public class Ivy implements Runnable { /* * since 1.2.8 */ - protected static IvyClient alreadyThere(final Hashtable c , final String name) { - for (IvyClient ic : c.values()) { - if ((ic != null)&&(name.compareTo(ic.getApplicationName()) == 0)) return ic; + protected static IvyClient alreadyThere(final Map c , final String name) { + synchronized (c) { + for (IvyClient ic : c.values()) { + if ((ic != null)&&(name.compareTo(ic.getApplicationName()) == 0)) return ic; + } } return null; } @@ -405,10 +414,12 @@ public class Ivy implements Runnable { for (IvyWatcher iw: watchers) iw.doStop(); watchers.clear(); // stopping the remaining IvyClients - for (IvyClient c : clients.values()) { - if (c != null) { - c.close(true); - removeClient(c); + synchronized (clients) { + for (IvyClient c : clients.values()) { + if (c != null) { + c.close(true); + removeClient(c); + } } } } catch (IOException e) { @@ -476,7 +487,9 @@ public class Ivy implements Runnable { if (doProtectNewlines) msg = IvyClient.encode(message); else if ( (msg.indexOf(IvyClient.newLineChar) != -1)||(msg.indexOf(IvyClient.endArgChar) != -1)) throw new IvyException("newline character not allowed in Ivy messages"); - for ( IvyClient client : clients.values()) if (client != null) count += client.sendMsg(msg); + synchronized (clients) { + for ( IvyClient client : clients.values()) if (client != null) count += client.sendMsg(msg); + } if (doSendToSelf) count+=selfIvyClient.sendSelfMsg(msg); traceDebug("end sending "+message+" to "+count+" clients"); } @@ -554,7 +567,9 @@ public class Ivy implements Runnable { // adds the regexp to our collection in selfIvyClient int key = selfIvyClient.bindMsg(sregexp , callback , type); // notifies the other clients this new regexp - for (IvyClient c : clients.values() ) if (c != null) c.sendRegexp(key , sregexp); + synchronized (clients) { + for (IvyClient c : clients.values() ) if (c != null) c.sendRegexp(key , sregexp); + } return key; } @@ -586,7 +601,9 @@ public class Ivy implements Runnable { */ public final void unBindMsg(final int id) throws IvyException { selfIvyClient.unBindMsg(id); - for (IvyClient ic : clients.values() ) if (ic != null) ic.delRegexp(id ); + synchronized (clients) { + for (IvyClient ic : clients.values() ) if (ic != null) ic.delRegexp(id ); + } } /** @@ -751,7 +768,9 @@ public class Ivy implements Runnable { */ public final Vector getIvyClients() { Vector v = new Vector(); - for (IvyClient ic : clients.values() ) if (ic != null) v.addElement(ic); + synchronized (clients) { + for (IvyClient ic : clients.values() ) if (ic != null) v.addElement(ic); + } return v; } @@ -764,9 +783,11 @@ public class Ivy implements Runnable { public final Vector getIvyClientsByName(final String name) { Vector v = new Vector(); String icname; - for (IvyClient ic : clients.values() ) { - if ( (ic == null)||((icname = ic.getApplicationName()) == null) ) break; - if (icname.compareTo(name) == 0) v.addElement(ic); + synchronized (clients) { + for (IvyClient ic : clients.values() ) { + if ( (ic == null)||((icname = ic.getApplicationName()) == null) ) break; + if (icname.compareTo(name) == 0) v.addElement(ic); + } } return v; } @@ -842,7 +863,9 @@ public class Ivy implements Runnable { protected synchronized void removeClient(IvyClient c) { synchronized(lock) { - clients.remove(c.getClientKey()); + synchronized (clients) { + clients.remove(c.getClientKey()); + } traceDebug("removed " + c + " from clients: " + getClientNames(clients)); } } @@ -854,7 +877,9 @@ public class Ivy implements Runnable { // TODO check if it's not already here ! IvyClient peer = searchPeer(c); if ((peer == null) || peer.distanceTo(c)>0 ){ - clients.put(c.getClientKey() , c); + synchronized (clients) { + clients.put(c.getClientKey() , c); + } setStarting(false); traceDebug("added " + c + " in clients: " + getClientNames(clients)); } else { @@ -869,15 +894,19 @@ public class Ivy implements Runnable { } protected synchronized void addHalf(IvyClient c) { - synchronized(lock){ half.put(c.getClientKey() , c); } + //synchronized(lock){ + synchronized (half) { half.put(c.getClientKey() , c); } + //} traceDebug("added " + c + " in half: " + getClientNames(half)); } protected synchronized void removeHalf(IvyClient c) { - synchronized(lock) { + //synchronized(lock) { if (half == null||c == null) return; - half.remove(c.getClientKey()); - } + synchronized (half) { + half.remove(c.getClientKey()); + } + //} traceDebug("removed " + c + " from half: " + getClientNames(half)); } @@ -894,13 +923,11 @@ public class Ivy implements Runnable { */ private synchronized IvyClient searchPeer(IvyClient ic) { - synchronized(lock) { - //for (Enumeration e = half.elements(); e.hasMoreElements(); ) { -// peer = e.nextElement(); -// if ((peer != null)&&(peer.equals(ic))) return peer; - // } - for (IvyClient peer : clients.values()) if ((peer != null)&&(peer.equals(ic))) return peer; - } + //synchronized(lock) { + synchronized (clients) { + for (IvyClient peer : clients.values()) if ((peer != null)&&(peer.equals(ic))) return peer; + } + //} return null; } @@ -970,10 +997,12 @@ public class Ivy implements Runnable { } // a small private method for debbugging purposes - private String getClientNames(Hashtable t) { + private String getClientNames(Map t) { StringBuffer s = new StringBuffer(); s.append("("); - for (IvyClient ic : t.values() ) if (ic != null) s.append(ic.getApplicationName() + ","); + synchronized (t) { + for (IvyClient ic : t.values() ) if (ic != null) s.append(ic.getApplicationName() + ","); + } s.append(")"); return s.toString(); } -- cgit v1.1