Author: bdonlan
Date: 2005-05-23 16:58:15 -0400 (Mon, 23 May 2005)
New Revision: 712

Modified:
   trunk/clients/Javer2/src/haver/Callback.java
   trunk/clients/Javer2/src/haver/Client.java
   trunk/clients/Javer2/src/javer2/CMod.java
Log:
* src/haver/Callback.java:
  - throws Throwable for all events
* src/haver/Client.java:
  - sendLine: synchronized
  - killConnection: new
  - *Monitor, sync*: New infastructure for synchronous monitoring. Hopefully
    more robust.


Modified: trunk/clients/Javer2/src/haver/Callback.java
===================================================================
--- trunk/clients/Javer2/src/haver/Callback.java        2005-05-23 03:10:36 UTC 
(rev 711)
+++ trunk/clients/Javer2/src/haver/Callback.java        2005-05-23 20:58:15 UTC 
(rev 712)
@@ -18,14 +18,14 @@
      * @param source haver.Client instance associated with this event
      * @throws java.io.IOException 
      */
-    public void onConnect(Client source) throws IOException {}
+    public void onConnect(Client source) throws Throwable {}
     /**
      * Called when a connection attempt fails.
      * @param source haver.Client instance associated with this event
      * @param e IOException which caused the connection failure
      * @throws java.io.IOException 
      */
-    public void onConnectFailed(Client source, java.io.IOException e) throws 
IOException {}
+    public void onConnectFailed(Client source, java.io.IOException e) throws 
Throwable {}
     /**
      * Called when an established connection is lost
      * @param source haver.Client instance associated with this event
@@ -33,34 +33,34 @@
      * not have an associated exception (e.g., connection broken)
      * @throws java.io.IOException 
      */
-    public void onDisconnected(Client source, java.io.IOException e) throws 
IOException {}
+    public void onDisconnected(Client source, java.io.IOException e) throws 
Throwable {}
     /**
      * Called when a message is received from the server
      * @param source haver.Client instance associated with this event
      * @param args Arguments of the message
      * @throws java.io.IOException 
      */
-    public void onIncomingLine(Client source, String[] args) throws 
IOException {}
+    public void onIncomingLine(Client source, String[] args) throws Throwable 
{}
     /**
      * Called when a message is sent to the server
      * @param source haver.Client instance associated with this event
      * @param args Arguments of the message
      * @throws java.io.IOException 
      */
-    public void onOutgoingLine(Client source, String[] args) throws 
IOException {}    
+    public void onOutgoingLine(Client source, String[] args) throws Throwable 
{}    
     /**
      * Called when the server requires identification
      * @param source haver.Client instance associated with this event
      * @throws java.io.IOException 
      */
-    public void onNeedIdent(Client source) throws IOException {}
+    public void onNeedIdent(Client source) throws Throwable {}
     /**
      * Called when the name given by the client has been accepted
      * @param source haver.Client instance associated with this event
      * @param name Name that was accepted by the server
      * @throws java.io.IOException 
      */
-    public void onAccept(Client source, String name) throws IOException {}
+    public void onAccept(Client source, String name) throws Throwable {}
     
     /**
      * Called when the server responds to a listing request
@@ -70,15 +70,15 @@
      * @param list List of objects held by the channel
      * @throws java.io.IOException 
      */
-    public void onReceivedList(Client source, String channel, String 
namespace, String[] list) throws IOException {}
+    public void onReceivedList(Client source, String channel, String 
namespace, String[] list) throws Throwable {}
     
-    public void onPublicMessage(Client source, String channel, String from, 
String type, String[] args) throws IOException {}
+    public void onPublicMessage(Client source, String channel, String from, 
String type, String[] args) throws Throwable {}
     
-    public void onPrivateMessage(Client source, String from, String type, 
String[] args) throws IOException {}
+    public void onPrivateMessage(Client source, String from, String type, 
String[] args) throws Throwable {}
     
-    public void onJoin(Client source, String channel, String who) throws 
IOException {}
+    public void onJoin(Client source, String channel, String who) throws 
Throwable {}
     
-    public void onPart(Client source, String channel, String who) throws 
IOException {}
+    public void onPart(Client source, String channel, String who) throws 
Throwable {}
     
-    public void onQuit(Client source, String who, String type, String detail) 
throws IOException {}
+    public void onQuit(Client source, String who, String type, String detail) 
throws Throwable {}
 }

Modified: trunk/clients/Javer2/src/haver/Client.java
===================================================================
--- trunk/clients/Javer2/src/haver/Client.java  2005-05-23 03:10:36 UTC (rev 
711)
+++ trunk/clients/Javer2/src/haver/Client.java  2005-05-23 20:58:15 UTC (rev 
712)
@@ -388,7 +388,7 @@
      * @param args Arguments of the line to send
      * @throws java.io.IOException 
      */
-    protected void sendLine(String[] args) throws IOException {
+    protected synchronized void sendLine(String[] args) throws IOException {
         if (writer != null) {
             String l = encodeLine(args);
             System.out.print("C: " + l);
@@ -397,6 +397,16 @@
         }
     }
     
+    protected synchronized void killConnection() {
+        // Kill the connection. Don't ask questions, just do it.
+        try {
+            writer.flush();
+        } catch (Throwable t) {}
+        try {
+            theSocket.close();
+        } catch (Throwable t) {}
+    }
+    
     /**
      * Main IO loop
      * @param f Termination flag; ioLoop will return when f.ok is false
@@ -447,53 +457,63 @@
         /**
          * The exception which caused the operation to fail, or null if none
          */
-        public IOException fail = null;
+        private IOException fail = null;
         /**
          * Flag for ioLoop() termination
          */
-        public Flag flag = new Flag();
+        private Flag flag = new Flag();
         
         /**
+         * Return value
+         */
+        private Object ret = null;
+        
+        public SyncMonitor() {
+            addNotify(this);
+        }
+        
+        /**
          * Signal completion of the synchronous event
          */
-        protected synchronized void done() {
+        protected synchronized void done(Object ret) {
+            if (!flag.ok)
+                throw new IllegalStateException("Already finished!");
+            removeNotify(this);
             flag.ok = false;
+            this.ret = ret;
             notifyAll();
         }
         
         public synchronized void onDisconnected(Client source, IOException e) {
-            fail = new IOException("Disconnected unexpectedly");
-            done();
+            if (e == null)
+                e = new IOException("Disconnected unexpectedly");
+            fail = e;
+            done(null);
         }
+        
         public synchronized void onConnectFailed(Client source, IOException e) 
{
             fail = e;
-            done();
+            done(null);
         }
         
         /**
          * Wait until the synchronous event completes
          * @throws java.io.IOException 
          */
-        public synchronized void block() throws IOException {
-            while (flag.ok) {
-                if (Thread.currentThread() == io) {
-                    if (flag != null) {
-                        ioLoop(flag);
-                        if (flag.ok) {
-                            throw new IOException("Unexpectedly disconnected");
-                        }
-                    } else {
-                        removeNotify(this);
-                        throw new IllegalStateException("Blocking in IO thread 
without flag");
-                    }
-                } else {
-                    try {
-                        wait();
-                    } catch (InterruptedException e) {
-                        // return, hopefully there's an abort flag elsewhere
-                    }
+        public synchronized Object block() throws IOException, 
InterruptedException {
+            if (Thread.currentThread() == io) {
+                ioLoop(flag);
+            } else {
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                    removeNotify(this);
+                    throw e;
                 }
             }
+            if (fail != null)
+                throw fail;
+            return ret;
         }
     }
     
@@ -519,8 +539,7 @@
         }
 
         public synchronized void onAccept(Client source, String name) {
-            done = true;
-            notifyAll();
+            done(null);
         }
     }
     
@@ -532,29 +551,10 @@
      * @throws java.io.IOException Thrown if an IO exception occurs at any 
point during the connect, or if the
      * connection is lost.
      */
-    public void syncConnect(String host, int port, String name) throws 
IOException {
+    public void syncConnect(String host, int port, String name) throws 
IOException, InterruptedException {
         ConnectMonitor m = new ConnectMonitor(name);
-        
-        addNotify(m);
         connect(host, port);
-        
-        synchronized (m) {
-            while (true) {
-                if (m.fail != null) {
-                    removeNotify(m);
-                    throw m.fail;
-                }
-                if (m.done) {
-                    removeNotify(m);
-                    return;
-                }
-                try {
-                    m.wait();
-                } catch (InterruptedException e) {
-                    // XXX: abort?
-                }
-            }
-        }
+        m.block();
     }
     
     /**
@@ -672,7 +672,6 @@
      * Event listener for syncList()
      */
     protected class ListMonitor extends SyncMonitor {
-        String[] list = null;
         String channel;
         String namespace;
         
@@ -685,8 +684,7 @@
             if (channel.equals(this.channel) &&
                 namespace.equals(this.namespace))
             {
-                this.list = list;
-                done();
+                done(list);
             }
         }
     }
@@ -700,23 +698,10 @@
      * @return An array containing the elements of the given namespace, in the 
specified
      * channel
      */
-    public String[] syncList(String channel, String namespace) throws 
IOException {
+    public String[] syncList(String channel, String namespace) throws 
IOException, InterruptedException {
         ListMonitor m = new ListMonitor(channel, namespace);
-        synchronized (m) {
-            addNotify(m);
-            requestList(channel, namespace);
-            while (true) {
-                if (m.fail != null) {
-                    removeNotify(m);
-                    throw m.fail;
-                }
-                if (m.list != null) {
-                    removeNotify(m);
-                    return m.list;
-                }
-                m.block();
-            }
-        }
+        requestList(channel, namespace);
+        return (String[])m.block();
     }
     
     protected void handle_IN(String[] args) throws IOException {
@@ -809,14 +794,13 @@
         
         public void onJoin(Client from, String channel, String who) {
             if (channel.equals(this.channel) && who.equals(name)) {
-                this.done();
+                this.done(null);
             }
         }
     }
     
-    public void syncJoin(String channel) throws IOException {
+    public void syncJoin(String channel) throws IOException, 
InterruptedException {
         JoinMonitor m = new JoinMonitor(channel);
-        addNotify(m);
         sendJoin(channel);
         m.block();
     }
@@ -835,16 +819,19 @@
         
         public void onPart(Client from, String channel, String who) {
             if (channel.equals(this.channel) && who.equals(name)) {
-                this.done();
+                this.done(null);
             }
         }
     }
     
-    public void syncPart(String channel) throws IOException {
+    public void syncPart(String channel) throws IOException, 
InterruptedException {
         PartMonitor m = new PartMonitor(channel);
-        addNotify(m);
         sendPart(channel);
         m.block();
     }
     
+    public synchronized void disconnect() {
+        killConnection();
+    }
+    
 }

Modified: trunk/clients/Javer2/src/javer2/CMod.java
===================================================================
--- trunk/clients/Javer2/src/javer2/CMod.java   2005-05-23 03:10:36 UTC (rev 
711)
+++ trunk/clients/Javer2/src/javer2/CMod.java   2005-05-23 20:58:15 UTC (rev 
712)
@@ -248,7 +248,8 @@
         reset();
     }
 
-    public void onAccept(Client source, String name) throws IOException {
+    public void onAccept(Client source, String name) throws IOException, 
InterruptedException {
         c.syncJoin(channel);
+        logMessage("joined");
     }
 }


Reply via email to