aboutsummaryrefslogtreecommitdiff
path: root/src/IvyWatcher.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/IvyWatcher.java')
-rwxr-xr-xsrc/IvyWatcher.java113
1 files changed, 67 insertions, 46 deletions
diff --git a/src/IvyWatcher.java b/src/IvyWatcher.java
index 3281079..5a47da3 100755
--- a/src/IvyWatcher.java
+++ b/src/IvyWatcher.java
@@ -2,7 +2,7 @@
* IvyWatcher, A private Class for the Ivy rendezvous
*
* @author Yannick Jestin
- * @author François-Régis Colin
+ * @author Francois-Regis Colin
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
*
* (C) CENA
@@ -14,6 +14,13 @@
* thing.
*
* CHANGELOG:
+ * 1.2.14
+ * - tries to fix a lock on accept() by becoming a Thread instead of
+ * runnalbe (see tests/test2)
+ * - removed unread field (domainaddr, e.g.)
+ * - throws RuntimeException instead of System.exit(), allows code reuse
+ * - switch from gnu regexp (deprecated) to the built in java regexp
+ * - add generic types to declarations
* 1.2.13:
* - TCP_NO_DELAY to disable Nagle's algorithm
* - private static ?! pour already present ...
@@ -73,17 +80,14 @@ package fr.dgac.ivy ;
import java.lang.Thread;
import java.net.*;
import java.io.*;
-import org.apache.regexp.*;
import java.util.Hashtable;
+import java.util.regex.*;
-class IvyWatcher implements Runnable {
+class IvyWatcher extends Thread {
private static boolean debug = (System.getProperty("IVY_DEBUG")!=null);
- private boolean isMulticastAddress = false;
private boolean alreadyIgnored = false;
private Ivy bus; /* master bus controler */
private DatagramSocket broadcast; /* supervision socket */
- private InetAddress localhost,loopback;
- private String domainaddr;
private int port;
private volatile Thread listenThread = null;
private InetAddress group;
@@ -91,6 +95,8 @@ class IvyWatcher implements Runnable {
private int myserial=serial++;
private String busWatcherId = null;
+ private static Pattern recoucou, numbersPoint, exp;
+
/**
* creates an Ivy watcher
* @param bus the bus
@@ -98,7 +104,6 @@ class IvyWatcher implements Runnable {
*/
IvyWatcher(Ivy bus,String domainaddr,int port) throws IvyException {
this.bus = bus;
- this.domainaddr=domainaddr;
this.port=port;
busWatcherId=bus.getWatcherId();
listenThread = new Thread(this);
@@ -106,13 +111,8 @@ class IvyWatcher implements Runnable {
try {
group = InetAddress.getByName(domainaddr);
broadcast = new MulticastSocket(port);
- if (group.isMulticastAddress()) {
- isMulticastAddress = true;
- ((MulticastSocket)broadcast).joinGroup(group);
- }
+ if (group.isMulticastAddress()) ((MulticastSocket)broadcast).joinGroup(group);
broadcast.setSoTimeout(Ivy.TIMEOUTLENGTH);
- localhost=InetAddress.getLocalHost();
- loopback=InetAddress.getByName(null);
} catch ( UnknownHostException uhe ) {
} catch ( IOException e ) {
throw new IvyException("IvyWatcher I/O error" + e );
@@ -134,35 +134,35 @@ class IvyWatcher implements Runnable {
byte buf[] = new byte[256];
DatagramPacket packet=new DatagramPacket(buf,buf.length);
broadcast.receive(packet);
+ bus.setStarting(true); // someone's coming
if (listenThread!=thisThread) break; // I was summoned to leave during the receive
String msg = new String(buf,0,packet.getLength());
String remotehostname=null;
try {
remotehost = packet.getAddress();
remotehostname = remotehost.getHostName();
- RE re = new RE("([0-9]*) ([0-9]*)");
- if (!(re.match(msg))) {
- System.err.println("Ignoring bad format broadcast from "+
- remotehostname+":"+packet.getPort());
+ Matcher m = recoucou.matcher(msg);
+ if (!m.matches()) {
+ System.err.println("Ignoring bad format broadcast from "+ remotehostname+":"+packet.getPort());
continue;
}
- int version = Integer.parseInt(re.getParen(1));
+ int version = Integer.parseInt(m.group(1));
if ( version < Ivy.PROTOCOLMINIMUM ) {
System.err.println("Ignoring bad format broadcast from "+
remotehostname+":"+packet.getPort()
+" protocol version "+remotehost+" we need "+Ivy.PROTOCOLMINIMUM+" minimum");
continue;
}
- remotePort = Integer.parseInt(re.getParen(2));
- if (bus.applicationPort==remotePort) { // if (same port number)
- RE reId = new RE("([0-9]*) ([0-9]*) ([^ ]*) (.*)");
- if (reId.match(msg)&&(busWatcherId!=null)) {
- traceDebug("there's an appId: "+reId.getParen(3));
- String otherId=reId.getParen(3);
- String otherName=reId.getParen(4);
+ remotePort = Integer.parseInt(m.group(2));
+ if (bus.getAppPort()==remotePort) { // if (same port number)
+ if (busWatcherId!=null) {
+ traceDebug("there's an appId: "+m.group(3));
+ String otherId=m.group(3);
+ String otherName=m.group(4);
if (busWatcherId.compareTo(otherId)==0) {
// same port #, same bus Id, It's me, I'm outta here
traceDebug("ignoring my own broadcast");
+ bus.setStarting(false);
continue;
} else {
// same port #, different bus Id, it's another agent
@@ -199,9 +199,6 @@ class IvyWatcher implements Runnable {
} else {
traceDebug("there is already a request originating from " + remotehost + ":" + remotePort);
}
- } catch (RESyntaxException ree) {
- ree.printStackTrace();
- System.exit(-1);
} catch (NumberFormatException nfe) {
System.err.println("Ignoring bad format broadcast from "+remotehostname);
continue;
@@ -225,15 +222,23 @@ class IvyWatcher implements Runnable {
traceDebug("Thread stopped"); // THREADDEBUG
}
+ @Override public void interrupt(){
+ super.interrupt();
+ broadcast.close();
+ }
+
/**
* stops the thread waiting on the broadcast socket
*/
- synchronized void stop() {
+ synchronized void doStop() {
traceDebug("begining stopping");
+ bus.setStarting(true);
Thread t = listenThread;
listenThread=null;
+ interrupt();
broadcast.close();
if (t!=null) { t.interrupt(); } // it might not even have been created
+ bus.setStarting(false);
traceDebug("stopped");
}
@@ -242,8 +247,10 @@ class IvyWatcher implements Runnable {
// domain.
DatagramPacket packet;
String data;
- public PacketSender(String data) {
+ Ivy bus;
+ public PacketSender(String data, Ivy b) {
this.data=data;
+ bus = b;
packet=new DatagramPacket(data.getBytes(),data.length(),group,port);
new Thread((PacketSender.this)).start();
}
@@ -263,15 +270,17 @@ class IvyWatcher implements Runnable {
e.printStackTrace();
}
}
+ try { Thread.sleep(100); } catch (InterruptedException ie ){ }
+ bus.setStarting(false); // one of the senders has finished its work, plus extra time
traceDebug("PacketSender thread stopped"); // THREADDEBUG
}
}
- synchronized void start() throws IvyException {
- // String hello = Ivy.PROTOCOLVERSION + " " + bus.applicationPort + "\n";
- String hello = Ivy.PROTOCOLVERSION + " " + bus.applicationPort + " "+busWatcherId+" "+bus.selfIvyClient.getApplicationName()+"\n";
+ synchronized void doStart() throws IvyException {
+ // String hello = Ivy.PROTOCOLVERSION + " " + bus.getAppPort() + "\n";
+ String hello = Ivy.PROTOCOLVERSION + " " + bus.getAppPort() + " "+busWatcherId+" "+bus.getSelfIvyClient().getApplicationName()+"\n";
if (broadcast==null) throw new IvyException("IvyWatcher PacketSender null broadcast address");
- new PacketSender(hello); // notifies our arrival on each domain: protocol version + port
+ new PacketSender(hello,bus); // notifies our arrival on each domain: protocol version + port
listenThread.start();
}
@@ -284,13 +293,13 @@ class IvyWatcher implements Runnable {
* regoes static ...
*/
//private static Hashtable alreadySocks=new Hashtable();
- private Hashtable alreadySocks=new Hashtable();
+ private Hashtable<String,Integer> alreadySocks=new Hashtable<String,Integer>();
private synchronized boolean alreadyBroadcasted(String s,int port) {
// System.out.println("DEBUUUUUUUG " + s+ ":" + port);
if (s==null) return false;
- Integer i = (Integer)alreadySocks.get(s);
- if (((i!=null)&&(i.compareTo(new Integer(port)))==0)) return true;
- alreadySocks.put(s,new Integer(port));
+ Integer i = alreadySocks.get(s);
+ if (((i!=null)&&(i.compareTo(port))==0)) return true;
+ alreadySocks.put(s,port);
return false;
}
@@ -322,22 +331,22 @@ class IvyWatcher implements Runnable {
int sep_index = net.lastIndexOf( ":" );
if ( sep_index != -1 ) { net = net.substring(0,sep_index); }
try {
- RE numbersPoint = new RE("([0-9]|\\.)+");
- if (!numbersPoint.match(net)) {
+ Matcher m = numbersPoint.matcher(net);
+ if (!m.matches()) {
// traceDebug("should only have numbers and point ? I won't add anything... " + net);
return "127.255.255.255";
// return net;
}
net += ".255.255.255";
- RE exp = new RE( "^(\\d+\\.\\d+\\.\\d+\\.\\d+).*");
- if (!exp.match(net)) {
+ Matcher mm= exp.matcher(net);
+ if (!mm.matches()) {
System.out.println("Bad broascat addr " + net);
throw new IvyException("bad broadcast addr");
}
- net=exp.getParen(1);
- } catch ( RESyntaxException e ){
- System.out.println(e);
- System.exit(0);
+ net=mm.group(1);
+ } catch ( PatternSyntaxException e ){
+ e.printStackTrace();
+ throw new RuntimeException();
}
//System.out.println("next domain: "+net);
return net;
@@ -354,5 +363,17 @@ class IvyWatcher implements Runnable {
private void traceDebug(String s){
if (debug) System.out.println("-->IvyWatcher["+myserial+","+bus.getSerial()+"]<-- "+s);
}
+
+ static {
+ try {
+ numbersPoint = Pattern.compile("([0-9]|\\.)+");
+ recoucou = Pattern.compile("([0-9]+) ([0-9]+) ([^ ]*) (.*)",Pattern.DOTALL);
+ exp = Pattern.compile( "^(\\d+\\.\\d+\\.\\d+\\.\\d+).*");
+ } catch (PatternSyntaxException res) {
+ res.printStackTrace();
+ System.out.println("Regular Expression bug in Ivy source code ... bailing out");
+ throw new RuntimeException();
+ }
+ }
} // class IvyWatcher