aboutsummaryrefslogtreecommitdiff
path: root/src/Ivy.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ivy.java')
-rwxr-xr-xsrc/Ivy.java150
1 files changed, 64 insertions, 86 deletions
diff --git a/src/Ivy.java b/src/Ivy.java
index 3486765..196c3b4 100755
--- a/src/Ivy.java
+++ b/src/Ivy.java
@@ -14,11 +14,14 @@
*
* CHANGELOG:
* 1.2.6:
+ * - added serial numbers for traceDebug
* - changed the semantic of -b a,b:port,c:otherport if no port is
* specified for a, it take the port from the next one. If none is
* specified, it takes DEFAULT_PORT
* - no more asynchronous sending of message ( async bind is ok though )
* because the tests are sooooo unsuccessful
+ * - use addElement/removeElement instead of add/remove is registering
+ * threads ( jdk1.1 backward compatibility )
* 1.2.5:
* - protection of newlines
* 1.2.4:
@@ -93,11 +96,11 @@ public class Ivy implements Runnable {
public static final String libVersion ="1.2.6";
private boolean debug;
- private static int clientSerial=0; /* an unique ID for each IvyClient */
private ServerSocket app;
private Vector watchers;
private volatile Thread serverThread; // to ensure quick communication of the end
private Hashtable clients = new Hashtable();
+ private Hashtable half = new Hashtable();
private Vector ivyApplicationListenerList = new Vector();
private Vector ivyBindListenerList = new Vector();
private Vector sendThreads = new Vector();
@@ -108,6 +111,8 @@ public class Ivy implements Runnable {
private boolean doSendToSelf = false ;
protected SelfIvyClient selfIvyClient ;
public final static int TIMEOUTLENGTH = 3000;
+ private static int serial=0;
+ private int myserial=serial++;
/**
* Readies the structures for the software bus connexion.
@@ -237,7 +242,7 @@ public class Ivy implements Runnable {
public synchronized void stop() {
if (stopped) return;
stopped=true;
- traceDebug("beginning stopping the bus");
+ traceDebug("beginning stopping");
try {
// stopping the serverThread
Thread t=serverThread;
@@ -255,7 +260,7 @@ public class Ivy implements Runnable {
} catch (IOException e) {
traceDebug("IOexception Stop ");
}
- traceDebug("the bus should have stopped so far");
+ traceDebug("end stopping");
}
/**
@@ -291,51 +296,21 @@ public class Ivy implements Runnable {
/**
* Performs a pattern matching according to everyone's regexps, and sends
- * the results to the relevant ivy agents sequentially
- *
- * @param message A String which will be compared to the regular
- * expressions of the different clients
- * @return the number of messages actually sent
- */
- public int sendMsg(String message) throws IvyException {
- return sendMsg(message,false);
- }
-
- /*
- * Performs a pattern matching according to everyone's regexps, and sends
- * the results to the relevant ivy agents, using as many threads as needed.
- *
- * disappeared in 1.2.6
- * @since 1.2.4
- * @param message A String which will be compared to the regular
- * expressions of the different clients
- * @return always returns -1
- public int sendAsyncMsg(String message,boolean async) throws IvyException {
- return sendMsg(message,true);
- }
- */
-
- /*
- * Performs a pattern matching according to everyone's regexps, and sends
* the results to the relevant ivy agents.
*
- * @since 1.2.4
* @param message A String which will be compared to the regular
* expressions of the different clients
- * @param async if true, the sending will be performed in a separate thread,
- * default is false
- * @return if async is true, always returns -1, else returns the number of messages actually sent
+ * @return returns the number of messages actually sent
*/
- protected int sendMsg(String message,boolean async) throws IvyException {
+ public int sendMsg(String message) throws IvyException {
int count = 0;
- if (async) throw new IvyException("Async sending not supported anymore");
if (doProtectNewlines)
message=IvyClient.encode(message);
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, async);
+ count += client.sendMsg(message);
}
if (doSendToSelf) count+=selfIvyClient.sendSelfMsg(message);
return count;
@@ -508,10 +483,6 @@ public class Ivy implements Runnable {
}
}
- /*
- * removes a client from the list
- */
- void removeClient(IvyClient c) { clients.remove(c.getClientKey()); }
/*
* invokes the application listeners when we are summoned to die
@@ -560,14 +531,6 @@ public class Ivy implements Runnable {
// Protected methods
//
/////////////////////////////////////////////////////////////////:
-
- synchronized void addClient(Socket socket,boolean peerCalling,int protocolVersion) throws IOException {
- if (stopped) return;
- IvyClient client = new IvyClient( this, socket,peerCalling,new Integer(clientSerial++),protocolVersion);
- clients.put(client.getClientKey(),client);
- traceDebug(getClientNames());
- }
-
private static String[] myTokenize(String s,String separator) {
int index=0, last=0, length=s.length();
Vector v = new Vector();
@@ -595,70 +558,87 @@ public class Ivy implements Runnable {
}
- /*
- * prevents two clients from connecting to each other at the same time
- * there might still be a lingering bug here, that we could avoid with the
- * SchizoToken.
- */
- boolean checkConnected( IvyClient clnt ) {
- if ( clnt.getAppPort() == 0 ) return false;
- for (Enumeration e=clients.elements();e.hasMoreElements();) {
- IvyClient client = (IvyClient)e.nextElement();
- if ( clnt != client && client.sameClient( clnt ) ) return true;
- }
- return false;
+ void addClient(IvyClient c) {
+ clients.put(c.getClientKey(),c);
+ traceDebug("added "+c+" in clients: "+getClientNames(clients));
+ }
+ void removeClient(IvyClient c) {
+ clients.remove(c.getClientKey());
+ traceDebug("removed "+c+" from clients: "+getClientNames(clients));
+ }
+ void addHalf(IvyClient c) {
+ half.put(c.getClientKey(),c);
+ traceDebug("added "+c+" in half: "+getClientNames(half));
+ }
+ void removeHalf(IvyClient c) {
+ half.remove(c.getClientKey());
+ traceDebug("removed "+c+" from half: "+getClientNames(half));
+ }
+
+ boolean shouldIleave(IvyClient ic) {
+ traceDebug("looking for "+ic+" in "+getClientNames(half)+" and "+getClientNames(clients));
+ IvyClient peer=searchPeer(ic);
+ if (peer==null) return false;
+ boolean shoulda=peer.compareTo(ic)>0;
+ traceDebug(ic+" "+ic.toStringExt()+((shoulda)?" must leave ":" must not leave"));
+ traceDebug(peer+" "+peer.toStringExt()+((!shoulda)?" must leave ":" must not leave"));
+ return shoulda;
+ }
+
+ 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;
+ return null;
}
/*
* the service socket thread reader main loop
*/
public void run() {
- traceDebug("Ivy service Thread started"); // THREADDEBUG
+ traceDebug("service thread started"); // THREADDEBUG
Thread thisThread=Thread.currentThread();
while(thisThread==serverThread){
try {
Socket socket = app.accept();
if ((thisThread!=serverThread)||stopped) break; // early disconnexion
- addClient(socket,true,0); // the peer called me TODO I can't know his protocol version
+ new IvyClient(this,socket,0); // the peer called me
} catch (InterruptedIOException ie) {
if (thisThread!=serverThread) break;
} catch( IOException e ) {
if (serverThread==thisThread) {
traceDebug("Error IvyServer exception: " + e.getMessage());
System.out.println("Ivy server socket reader caught an exception " + e.getMessage());
- System.out.println("this is probably a bug in your JVM !");
- // e.printStackTrace();
+ 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"); }
}
}
- traceDebug("Ivy service Thread stopped"); // THREADDEBUG
+ traceDebug("service thread stopped"); // THREADDEBUG
}
+ protected int getSerial() { return myserial ; }
+ private void traceDebug(String s){
+ if (debug) System.out.println("-->Ivy["+myserial+"]<-- "+s);
+ }
- private void traceDebug(String s){ if (debug) System.out.println("-->ivy<-- "+s); }
-
- synchronized void registerThread(Thread t) { sendThreads.add(t); }
- synchronized void unRegisterThread(Thread t) { sendThreads.remove(t); }
+ // stuff to guarantee that all the treads have left
+ synchronized void registerThread(Thread t) { sendThreads.addElement(t); }
+ synchronized void unRegisterThread(Thread t) { sendThreads.removeElement(t); }
synchronized Thread getOneThread() {
if (sendThreads.size()==0) return null;
return (Thread) sendThreads.firstElement();
}
- void waitForAll() {
- Thread t;
- traceDebug("DEVELOPMENT WAITFORALL sendThreads size : " + sendThreads.size());
- try { while ((t=getOneThread())!=null) { t.join(); } }
- catch (InterruptedException ie) { System.out.println("waitForAll Interrupted"); }
- traceDebug("DEVELOPMENT END WAITFORALL");
- }
-
- /* a small private method for debbugging purposes */
- private String getClientNames() {
- String s = appName+" clients are: ";
- for (Enumeration e=clients.elements();e.hasMoreElements();){
- s+=((IvyClient)e.nextElement()).getApplicationName()+" ";
+ // a small private method for debbugging purposes
+ private String getClientNames(Hashtable t) {
+ String s = "(";
+ for (Enumeration e=t.elements();e.hasMoreElements();){
+ s+=((IvyClient)e.nextElement()).getApplicationName()+",";
}
- return s;
+ return s+")";
}
public String domains(String toparse) {
@@ -681,9 +661,7 @@ public class Ivy implements Runnable {
}
- /*
- * unitary test. Normally, running java fr.dgac.ivy.Ivy should stop in 2.3 seconds :)
- */
+ // test. Normally, running java fr.dgac.ivy.Ivy should stop in 2.3 seconds :)
public static void main(String[] args) {
Ivy bus = new Ivy("Test Unitaire","TU ready",null);
try {