aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/After.java59
-rwxr-xr-xsrc/Ivy.java119
-rwxr-xr-xsrc/IvyClient.java32
-rw-r--r--src/IvyDaemon.java12
-rwxr-xr-xsrc/IvyException.java3
-rwxr-xr-xsrc/IvyWatcher.java14
-rw-r--r--src/Makefile1
-rw-r--r--src/Probe.java7
-rw-r--r--src/SelfIvyClient.java2
-rw-r--r--src/Waiter.java4
-rw-r--r--src/WaiterClient.java10
11 files changed, 196 insertions, 67 deletions
diff --git a/src/After.java b/src/After.java
new file mode 100644
index 0000000..298830d
--- /dev/null
+++ b/src/After.java
@@ -0,0 +1,59 @@
+/**
+ * an utility waiting for a message to come, then exiting.
+ *
+ * @author Yannick Jestin
+ * @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
+ *
+ * (c) CENA
+ *
+ * Changelog:
+ * 1.2.8: new in the ivy package
+ * TODO / BUG: sur un die, quitter avec un -1
+ */
+package fr.dgac.ivy.tools ;
+import fr.dgac.ivy.* ;
+import gnu.getopt.Getopt;
+
+public class After implements IvyMessageListener {
+
+ public final static int DEFAULTTIMEOUT = 0 ;
+
+ public static final String helpmsg = "usage: java fr.dgac.ivy.After [options] regexp\n\t-b BUS\tspecifies the Ivy bus domain\n\t-t\ttime out in seconds, defaults to "+DEFAULTTIMEOUT+"\n\t-h\thelp\n\n\t regexp is a Perl5 compatible regular expression";
+
+ public static void main(String[] args) throws IvyException {
+ Getopt opt = new Getopt("After",args,"b:t:");
+ int c;
+ String domain=Ivy.getDomain(null);
+ String name="AFTER";
+ int timeout = DEFAULTTIMEOUT;
+ while ((c = opt.getopt()) != -1) switch (c) {
+ case 'b': domain=opt.getOptarg(); break;
+ case 't': timeout=Integer.parseInt(opt.getOptarg()); break;
+ case 'h':
+ default: System.out.println(helpmsg); System.exit(0);
+ }
+ if (opt.getOptind()!=args.length-1) { System.out.println(helpmsg); System.exit(0); }
+ String regexp=args[opt.getOptind()];
+ Ivy bus=new Ivy(name,name+" ready",null);
+ bus.bindMsgOnce(regexp,new After(bus));
+ bus.start(domain);
+ if (timeout>0) {
+ System.out.println("waiting "+timeout+"s for "+regexp);
+ try { Thread.sleep(timeout*1000); } catch (InterruptedException ie) { }
+ System.out.println(regexp+" not received, bailing out");
+ bus.stop();
+ System.exit(-1);
+ } else {
+ System.out.println("waiting forever for "+regexp);
+ }
+ }
+
+ private Ivy bus;
+ public After(Ivy b) { bus=b; }
+
+ public void receive(IvyClient ic,String[] args) {
+ bus.stop();
+ System.exit(0);
+ }
+
+}
diff --git a/src/Ivy.java b/src/Ivy.java
index 2fc6307..0b5168a 100755
--- a/src/Ivy.java
+++ b/src/Ivy.java
@@ -14,6 +14,9 @@
*
* CHANGELOG:
* 1.2.8:
+ * - domainaddr goes protected in Domain ( gij compatibility )
+ * - checks if (Client)e.nextElement() each time we want to ...
+ * Multithreaded Enumerations ..., should fix [YJnul05]
* - added getDomainArgs(String,String[]) as a facility to parse the
* command line in search of a -b domain
* - added getWBUId(), un function returning a string ID to perform
@@ -120,7 +123,7 @@ public class Ivy implements Runnable {
protected boolean doProtectNewlines = false ;
private boolean doSendToSelf = false ;
protected SelfIvyClient selfIvyClient ;
- public final static int TIMEOUTLENGTH = 3000;
+ public final static int TIMEOUTLENGTH = 1000;
private static int serial=0;
private int myserial=serial++;
static long current = System.currentTimeMillis();
@@ -136,7 +139,7 @@ public class Ivy implements Runnable {
* @param appcb A callback handling the notification of connexions and
* disconnections, may be null
*/
- public Ivy( String name, String message, IvyApplicationListener appcb) {
+ public Ivy(String name, String message, IvyApplicationListener appcb) {
appName = name;
ready_message = message;
debug = (System.getProperty("IVY_DEBUG")!=null);
@@ -174,18 +177,31 @@ public class Ivy implements Runnable {
IvyClient ic;
if (name==null) throw new IvyException("null name given to waitForClient");
// first check if client with the same name is on the bus
- for (Enumeration e=clients.elements();e.hasMoreElements();) {
- ic = (IvyClient)e.nextElement();
- if (name.compareTo(ic.getApplicationName())==0) return ic;
- }
+ if ((ic=alreadyThere(clients,name))!=null) return ic;
// if not enter the waiting loop
- WaiterClient w = new WaiterClient(name,timeout);
+ WaiterClient w = new WaiterClient(name,timeout,clients);
int i = addApplicationListener(w);
ic=w.waitForClient();
removeApplicationListener(i);
return ic;
}
+ /*
+ * since 1.2.8
+ */
+ static protected IvyClient alreadyThere(Hashtable c,String name) {
+ IvyClient ic;
+ for (Enumeration e=c.elements();e.hasMoreElements();) {
+ try {
+ ic = (IvyClient)e.nextElement();
+ } catch (ArrayIndexOutOfBoundsException _ ) {
+ return null; // with gij, it ... can happen
+ }
+ if ((ic!=null)&&(name.compareTo(ic.getApplicationName())==0)) return ic;
+ }
+ return null;
+ }
+
/**
* connects the Ivy bus to a domain or list of domains.
*
@@ -199,8 +215,10 @@ public class Ivy implements Runnable {
* broadcast. Beware of routing problems ! You can also use a comma
* separated list of domains.
*
+ * 1.2.8: goes synchronized. I don't know if it's really useful
+ *
*/
- public void start(String domainbus) throws IvyException {
+ public synchronized void start(String domainbus) throws IvyException {
if (!stopped) throw new IvyException("cannot start a bus that's already started");
stopped=false;
if (domainbus==null) domainbus=getDomain(null);
@@ -250,7 +268,7 @@ public class Ivy implements Runnable {
/**
* disconnects from the Ivy bus
*/
- public synchronized void stop() {
+ public void stop() {
if (stopped) return;
stopped=true;
traceDebug("beginning stopping");
@@ -259,6 +277,8 @@ public class Ivy implements Runnable {
Thread t=serverThread;
serverThread=null;
if (t!=null) t.interrupt(); // The serverThread might be stopped even before having been created
+ // System.out.println("IZZZ joining "+t);
+ try { t.join(); } catch ( InterruptedException _ ) { }
// TODO BUG avec gcj+kaffe, le close() reste pendu et ne rend pas la main
app.close();
// stopping the IvyWatchers
@@ -266,9 +286,12 @@ public class Ivy implements Runnable {
watchers.clear();
// stopping the remaining IvyClients
for (Enumeration e=clients.elements();e.hasMoreElements();) {
- IvyClient c = (IvyClient)e.nextElement();
- if (c!=null) c.close(true);
- removeClient(c);
+ try {
+ IvyClient c = (IvyClient)e.nextElement();
+ if (c!=null) { c.close(true);removeClient(c); }
+ } catch (ArrayIndexOutOfBoundsException _ ) {
+ continue;
+ }
}
} catch (IOException e) {
traceDebug("IOexception Stop ");
@@ -322,8 +345,12 @@ public class Ivy implements Runnable {
else if ( (message.indexOf(IvyClient.newLineChar)!=-1)||(message.indexOf(IvyClient.endArgChar)!=-1))
throw new IvyException("newline character not allowed in Ivy messages");
for ( Enumeration e=clients.elements();e.hasMoreElements();) {
- IvyClient client = (IvyClient)e.nextElement();
- count += client.sendMsg(message);
+ try {
+ IvyClient client = (IvyClient)e.nextElement();
+ if (client!=null) count += client.sendMsg(message);
+ } catch (ArrayIndexOutOfBoundsException _ ) {
+ continue; // gij problem
+ }
}
if (doSendToSelf) count+=selfIvyClient.sendSelfMsg(message);
return count;
@@ -393,8 +420,12 @@ public class Ivy implements Runnable {
int key=selfIvyClient.bindMsg(sregexp,callback,async);
// notifies the other clients this new regexp
for (Enumeration e=clients.elements();e.hasMoreElements();) {
- IvyClient c = (IvyClient)e.nextElement();
- c.sendRegexp(key,sregexp);
+ try {
+ IvyClient c = (IvyClient)e.nextElement();
+ if (c!=null) c.sendRegexp(key,sregexp);
+ } catch (ArrayIndexOutOfBoundsException _ ) {
+ continue; // gij problem
+ }
}
return key;
}
@@ -425,8 +456,15 @@ public class Ivy implements Runnable {
*/
public void unBindMsg(int id) throws IvyException {
selfIvyClient.unBindMsg(id);
- for (Enumeration e=clients.elements();e.hasMoreElements();)
- ((IvyClient)e.nextElement()).delRegexp(id );
+ for (Enumeration e=clients.elements();e.hasMoreElements();) {
+ try {
+ IvyClient ic=(IvyClient)e.nextElement();
+ if (ic!=null) ic.delRegexp(id );
+ } catch (ArrayIndexOutOfBoundsException _ ) {
+ continue;
+ }
+
+ }
}
/**
@@ -553,12 +591,17 @@ public class Ivy implements Runnable {
}
/**
- * gives the names of IvyClient(s)
+ * gives the IvyClient() at a given instant
*/
public Vector getIvyClients() {
Vector v=new Vector();
for (Enumeration e=clients.elements();e.hasMoreElements();) {
- v.addElement(e.nextElement());
+ try {
+ IvyClient ic=(IvyClient)e.nextElement();
+ if (ic!=null) v.addElement(ic);
+ } catch (ArrayIndexOutOfBoundsException _) {
+ continue;
+ }
}
return v;
}
@@ -570,9 +613,15 @@ public class Ivy implements Runnable {
*/
public Vector getIvyClientsByName(String name) {
Vector v=new Vector();
+ String icname;
for (Enumeration e=clients.elements();e.hasMoreElements();) {
- IvyClient ic = (IvyClient)e.nextElement();
- if ( ((ic.getApplicationName()).compareTo(name))==0 ) v.addElement(ic);
+ try {
+ IvyClient ic = (IvyClient)e.nextElement();
+ if ( (ic==null)||((icname=ic.getApplicationName())==null) ) break;
+ if (icname.compareTo(name)==0) v.addElement(ic);
+ } catch (ArrayIndexOutOfBoundsException _ ) {
+ continue;
+ }
}
return v;
}
@@ -647,14 +696,17 @@ public class Ivy implements Runnable {
synchronized (clients) { clients.put(c.getClientKey(),c); }
traceDebug("added "+c+" in clients: "+getClientNames(clients));
}
+
void removeClient(IvyClient c) {
synchronized (clients) {clients.remove(c.getClientKey());}
traceDebug("removed "+c+" from clients: "+getClientNames(clients));
}
+
void addHalf(IvyClient c) {
synchronized(half){half.put(c.getClientKey(),c);}
traceDebug("added "+c+" in half: "+getClientNames(half));
}
+
void removeHalf(IvyClient c) {
synchronized(half){half.remove(c.getClientKey());}
traceDebug("removed "+c+" from half: "+getClientNames(half));
@@ -672,10 +724,16 @@ public class Ivy implements Runnable {
private IvyClient searchPeer(IvyClient ic) {
IvyClient peer;
- for (Enumeration e=half.elements();e.hasMoreElements();)
- if ((peer=(IvyClient)e.nextElement()).equals(ic)) return peer;
- for (Enumeration e=clients.elements();e.hasMoreElements();)
- if ((peer=(IvyClient)e.nextElement()).equals(ic)) return peer;
+ for (Enumeration e=half.elements();e.hasMoreElements();) {
+ peer=(IvyClient)e.nextElement();
+ if ((peer!=null)&&(peer.equals(ic))) return peer;
+ }
+ synchronized (clients) {
+ for (Enumeration e=clients.elements();e.hasMoreElements();){
+ peer=(IvyClient)e.nextElement();
+ if ((peer!=null)&&(peer.equals(ic))) return peer;
+ }
+ }
return null;
}
@@ -689,8 +747,9 @@ public class Ivy implements Runnable {
try {
Socket socket = app.accept();
if ((thisThread!=serverThread)||stopped) break; // early disconnexion
- new IvyClient(this,socket,0); // the peer called me
+ new IvyClient(this,socket,0,true); // the peer called me
} catch (InterruptedIOException ie) {
+ // traceDebug("server socket was interrupted. good");
if (thisThread!=serverThread) break;
} catch( IOException e ) {
if (serverThread==thisThread) {
@@ -698,7 +757,9 @@ public class Ivy implements Runnable {
System.out.println("Ivy server socket reader caught an exception " + e.getMessage());
System.out.println("this is probably a bug in your JVM ! (e.g. blackdown jdk1.1.8 linux)");
System.exit(0);
- } else { traceDebug("my server socket has been closed"); }
+ } else {
+ traceDebug("my server socket has been closed");
+ }
}
}
traceDebug("service thread stopped"); // THREADDEBUG
@@ -738,7 +799,7 @@ public class Ivy implements Runnable {
class Domain {
- private String domainaddr;
+ String domainaddr;
int port;
public Domain(String domainaddr,int port) {this.domainaddr=domainaddr;this.port=port;}
public String toString() {return domainaddr+":"+port;}
diff --git a/src/IvyClient.java b/src/IvyClient.java
index 0a06c55..4f46ca8 100755
--- a/src/IvyClient.java
+++ b/src/IvyClient.java
@@ -112,26 +112,21 @@ public class IvyClient implements Runnable {
IvyClient() { }
- IvyClient(Ivy bus, Socket socket,int remotePort) throws IOException {
+ IvyClient(Ivy bus, Socket socket,int remotePort,boolean incoming) throws IOException {
synchronized(csMutex) { clientKey=new Integer(clientSerial++); }
this.bus = bus;
this.remotePort = remotePort;
+ this.incoming = incoming;
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = socket.getOutputStream();
incoming=(remotePort==0);
traceDebug(((incoming)?"incoming":"outgoing")+" connection on "+socket);
this.socket = socket;
- if (!incoming) { // outgoing connexion
+ if (!incoming) {
synchronized(bus) {
bus.addHalf(this); // register a half connexion
- if (bus.shouldIleave(this)) {
- traceDebug(toStringExt()+" should leave ...");
- close(false);
- bus.removeHalf(this);
- return;
- }
sendSchizo();
- // the registering will take place at the reception of the regexps...
+ // the registering (handShake) will take place at the reception of the regexps...
}
}
remoteHostname = socket.getInetAddress().getHostName();
@@ -154,7 +149,7 @@ public class IvyClient implements Runnable {
sendString( EndRegexp,0,"");
}
- synchronized private void handShake() {
+ synchronized private void handShake() throws IvyException {
synchronized(bus) {
bus.removeHalf(this);
bus.addClient(this);
@@ -217,14 +212,16 @@ public class IvyClient implements Runnable {
traceDebug("closing connexion to "+appName);
if (notify) sendBye("hasta la vista");
stopListening();
- socket.close();
+ socket.close(); // TODO is it necessary ? trying to fix a deadlock
}
/**
* asks the remote client to leave the bus.
* @param message the message that will be carried
*/
- public void sendDie(String message) { sendString(Die,0,message); }
+ public void sendDie(String message) {
+ sendString(Die,0,message);
+ }
/**
* checks the "validity" of a regular expression.
@@ -420,6 +417,7 @@ public class IvyClient implements Runnable {
}
private boolean newParseMsg(String s) throws IvyException {
+ if (s==null) throw new IvyException("null string to parse in protocol");
byte[] b = s.getBytes();
int from=0,to=0,msgType;
Integer msgId;
@@ -530,16 +528,8 @@ public class IvyClient implements Runnable {
if (incoming) {
// incoming connexion, I wait for his token to send him mine ...
synchronized(bus) {
- bus.addHalf(this);
try {
- // there is another connexion. Should I leave ?
- // Assymetric processing to prevent concurrent disconnexions
- if (bus.shouldIleave(this)) {
- traceDebug(toStringExt()+" should leave ...");
- close(false);
- bus.removeHalf(this);
- return false;
- }
+ bus.addHalf(this);
sendSchizo();
handShake();
} catch (IOException ioe) {
diff --git a/src/IvyDaemon.java b/src/IvyDaemon.java
index 363337b..910a52d 100644
--- a/src/IvyDaemon.java
+++ b/src/IvyDaemon.java
@@ -11,6 +11,8 @@
* (c) CENA
*
* changelog:
+ * 1.2.8
+ * - goes into tools subpackage
* 1.2.3
* - adds the traceDebug
* - uses the clientThread paradigm to programm the thread sync
@@ -22,7 +24,8 @@
* 1.0.12
* - class goes public access !
*/
-package fr.dgac.ivy ;
+package fr.dgac.ivy.tools ;
+import fr.dgac.ivy.* ;
import java.io.*;
import java.net.*;
import java.util.Properties ;
@@ -40,12 +43,13 @@ public class IvyDaemon implements Runnable {
public static int DEFAULT_SERVICE_PORT = 3456 ;
public static final String DEFAULTNAME = "IvyDaemon";
public static final String helpmsg = "usage: java fr.dgac.ivy.IvyDaemon [options]\n\t-b BUS\tspecifies the Ivy bus domain\n\t-p\tport number, default "+DEFAULT_SERVICE_PORT+"\n\t-n ivyname (default "+DEFAULTNAME+")\n\t-q\tquiet, no tty output\n\t-d\tdebug\n\t-h\thelp\nListens on the TCP port, and sends each line read on the Ivy bus. It is useful to launch one Ivy Daemon and let scripts send their message on the bus.\n";
+
+ private static String name = DEFAULTNAME;
public static void main(String[] args) throws IvyException, IOException {
Ivy bus;
Getopt opt = new Getopt("IvyDaemon",args,"n:b:dqp:h");
int c;
int servicePort = DEFAULT_SERVICE_PORT;
- String name = DEFAULTNAME;
boolean quiet = false;
String domain=Ivy.getDomain(null);
while ((c = opt.getopt()) != -1) switch (c) {
@@ -135,8 +139,8 @@ public class IvyDaemon implements Runnable {
}
}
- private void traceDebug(String s){
- if (debug) System.out.println("-->IvyDaemon "+bus.appName+"<-- "+s);
+ private static void traceDebug(String s){
+ if (debug) System.out.println("-->IvyDaemon "+name+"<-- "+s);
}
}
diff --git a/src/IvyException.java b/src/IvyException.java
index de739ad..bd052b6 100755
--- a/src/IvyException.java
+++ b/src/IvyException.java
@@ -8,9 +8,12 @@ package fr.dgac.ivy;
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
*
* changelog:
+ * 1.2.8:
+ * added a serialVersionUID to be compatible with jdk1.5
* 1.0.12 changed default access constructor to public access
*/
public class IvyException extends Exception {
+ static final long serialVersionUID=1L;
public IvyException(String s) { super(s); }
}
diff --git a/src/IvyWatcher.java b/src/IvyWatcher.java
index 93d5a8f..b37fa6b 100755
--- a/src/IvyWatcher.java
+++ b/src/IvyWatcher.java
@@ -65,11 +65,8 @@ package fr.dgac.ivy ;
import java.lang.Thread;
import java.net.*;
import java.io.*;
-import java.util.StringTokenizer;
import org.apache.regexp.*;
import java.util.Hashtable;
-import java.util.Vector;
-import java.util.Enumeration;
class IvyWatcher implements Runnable {
private static boolean debug = (System.getProperty("IVY_DEBUG")!=null);
@@ -156,7 +153,12 @@ class IvyWatcher implements Runnable {
+":"+packet.getPort()+", port:"+remotePort+", protocol version:"+version);
if (!alreadyBroadcasted(remotehost.toString(),remotePort)) {
traceDebug("no known agent originating from " + remotehost + ":" + remotePort);
- new IvyClient(bus,new Socket(remotehost,remotePort),remotePort);
+ try {
+ Socket s = new Socket(remotehost,remotePort);
+ new IvyClient(bus,s,remotePort,false);
+ } catch ( java.net.ConnectException jnc ) {
+ traceDebug("cannot connect to "+remotehostname+":"+remotePort+", he probably stopped his bus");
+ }
} else {
traceDebug("there is already a request originating from " + remotehost + ":" + remotePort);
}
@@ -240,8 +242,10 @@ class IvyWatcher implements Runnable {
* went local instead of static ! fixed a nasty bug in 1.2.8
* checks if there is already a broadcast received from the same address
* on the same port
+ *
+ * regoes static ...
*/
- private Hashtable alreadySocks=new Hashtable();
+ private static Hashtable alreadySocks=new Hashtable();
private synchronized boolean alreadyBroadcasted(String s,int port) {
// System.out.println("DEBUUUUUUUG " + s+ ":" + port);
if (s==null) return false;
diff --git a/src/Makefile b/src/Makefile
index f6cdfe0..e6ee810 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -6,6 +6,7 @@ include ../java.mk
DOCS = ../doc/html/api
GNUPATH = /usr/share/java/gnu-getopt.jar:/usr/share/java/regexp.jar # debian SID
+ GNUPATH = ../bundle # on my MAC
#GNUPATH = /usr/lib/jdk1.1/lib/classes.zip:/usr/share/java/gnu.getopt.jar:/usr/share/java/regexp.jar # debian woody
#GNUPATH = ${HOME}/java/Jars/gnu.getopt.jar:${HOME}/java/Jars/regexp.jar # Others
#RTPATH = /usr/local/jdk1.5.0/jre/lib/rt.jar # for jikes on my box
diff --git a/src/Probe.java b/src/Probe.java
index be56d35..7f5e7b5 100644
--- a/src/Probe.java
+++ b/src/Probe.java
@@ -7,6 +7,8 @@
* (c) CENA
*
* Changelog:
+ * 1.2.8
+ * - added a fr.dgac.ivy.tools subsection
* 1.2.7
* - added a .where function
* - added a .bound function
@@ -40,12 +42,13 @@
* - processes .help, .die , .quit and .bye commands
* - it is possible to rename the JPROBE on the bus with the -n switch, it can
* circumvent name collisions during tests
- * e.g: java fr.dgac.ivy.Probe -n JPROBE2
+ * e.g: java fr.dgac.ivy.tools.Probe -n JPROBE2
* 1.0.10
* exits on end of user input
* handles multiple domains - it was a IvyWatcher problem -
*/
-package fr.dgac.ivy ;
+package fr.dgac.ivy.tools ;
+import fr.dgac.ivy.* ;
import java.io.*;
import java.util.*;
import gnu.getopt.Getopt;
diff --git a/src/SelfIvyClient.java b/src/SelfIvyClient.java
index 43bfccb..f4a1cd2 100644
--- a/src/SelfIvyClient.java
+++ b/src/SelfIvyClient.java
@@ -112,7 +112,7 @@ class SelfIvyClient extends IvyClient {
boolean threaded=b.booleanValue();
if (!threaded) {
// runs the callback in the same thread
- callback.receive(client, tab);
+ callback.receive(client, tab); // TODO tab can be faulty ?!
} else {
// starts a new Thread for each callback ... ( Async API )
new Runner(callback,client,tab);
diff --git a/src/Waiter.java b/src/Waiter.java
index df1f427..ae5d7bc 100644
--- a/src/Waiter.java
+++ b/src/Waiter.java
@@ -3,11 +3,11 @@
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
*
* CHANGELOG:
- * 1.2.4:
+ * 1.2.8:
+ * no more import of java.util.*
*/
package fr.dgac.ivy ;
-import java.util.*;
class Waiter implements Runnable, IvyMessageListener {
private static final int INCREMENT = 100;
diff --git a/src/WaiterClient.java b/src/WaiterClient.java
index f9e1d06..34fd188 100644
--- a/src/WaiterClient.java
+++ b/src/WaiterClient.java
@@ -3,11 +3,12 @@
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
*
* CHANGELOG:
- * 1.2.4:
+ * 1.2.8:
+ * added a test during the waiting loop
*/
package fr.dgac.ivy ;
-import java.util.*;
+import java.util.Hashtable;
class WaiterClient extends IvyApplicationAdapter implements Runnable {
private static final int INCREMENT = 100;
@@ -16,9 +17,11 @@ class WaiterClient extends IvyApplicationAdapter implements Runnable {
private boolean forever=false;
private Thread t;
String name;
+ Hashtable clients;
- WaiterClient(String n,int timeout) {
+ WaiterClient(String n,int timeout,Hashtable clients) {
this.timeout=timeout;
+ this.clients=clients;
name=n;
if (timeout<=0) forever=true;
t=new Thread(this);
@@ -43,6 +46,7 @@ class WaiterClient extends IvyApplicationAdapter implements Runnable {
} catch (InterruptedException ie) {
break;
}
+ if ((received=Ivy.alreadyThere(clients,name))!=null) break;
}
// System.out.println("DEV WaiterClient stop");
}