From dc931b33bf8fa61c8eb4d7297e42379543274745 Mon Sep 17 00:00:00 2001 From: jestin Date: Thu, 29 Jul 2004 17:33:08 +0000 Subject: bugfixes majeurs, voir le changelog 1.2.6 --- src/Ivy.java | 150 +++++++++++++++++++++++++---------------------------------- 1 file changed, 64 insertions(+), 86 deletions(-) (limited to 'src/Ivy.java') 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 { -- cgit v1.1