Author: bdonlan
Date: 2005-05-22 01:05:33 -0400 (Sun, 22 May 2005)
New Revision: 705

Modified:
   trunk/clients/Javer2/src/haver/Callback.java
   trunk/clients/Javer2/src/haver/Client.java
   trunk/clients/Javer2/src/javer2/Main.java
Log:
src/haver/Callback.java:
    * onReceivedList(): new
src/haver/Client.java:
    * class Flag: mutable boolean for ioLoop() termination
    * CallbackDist.iterator(): new; copy set to avoid concurrency issues
    * CallbackDist.(various): use iterator()
    * CallbackDist.onConnect(): greet server here instead of ioLoop()
    * CallbackDist.onReceivedList(): new
    * ioLoop():
      - Don't greet the server here
      - Take a Flag to terminate loop
    * SyncMonitor: Reenter ioLoop() if a blocking call is done within the
      IO thread
    * requestList(): new
    * handle_LIST(): new
    * ListMonitor: new
    * syncList(): new
src/javer2/Main.java:
    * join():
      - Take an arbitrary string to join parts
      - Correctly handle a zero-length parts array
    * onAccept(): Test code for haver.Client.syncList()


Modified: trunk/clients/Javer2/src/haver/Callback.java
===================================================================
--- trunk/clients/Javer2/src/haver/Callback.java        2005-05-22 05:01:49 UTC 
(rev 704)
+++ trunk/clients/Javer2/src/haver/Callback.java        2005-05-22 05:05:33 UTC 
(rev 705)
@@ -61,4 +61,14 @@
      * @throws java.io.IOException 
      */
     public void onAccept(Client source, String name) throws IOException {}
+    
+    /**
+     * Called when the server responds to a listing request
+     * @param source haver.Client instance associated with this event
+     * @param channel Channel that was listed
+     * @param namespace Namespace of objects listed
+     * @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 {}
 }

Modified: trunk/clients/Javer2/src/haver/Client.java
===================================================================
--- trunk/clients/Javer2/src/haver/Client.java  2005-05-22 05:01:49 UTC (rev 
704)
+++ trunk/clients/Javer2/src/haver/Client.java  2005-05-22 05:05:33 UTC (rev 
705)
@@ -31,6 +31,10 @@
     String host;
     int port;
     
+    class Flag {
+        public boolean ok = true;
+    }
+    
     /** Creates a new instance of Client */
     public Client() {
         dist = new CallbackDist(listening);
@@ -121,6 +125,11 @@
             listeners = l;
         }
         
+        protected Iterator iterator() {
+            // Prevent concurrency issues
+            return new HashSet(listeners).iterator();
+        }
+        
         public void onDisconnected(Client source, IOException e) throws 
IOException {
             try {reader.close();} catch (Throwable t) {}
             try {writer.close();} catch (Throwable t) {}
@@ -130,7 +139,7 @@
             theSocket = null;
             io = null;
             
-            Iterator i = listeners.iterator();
+            Iterator i = iterator();
             while (i.hasNext()) {
                 Callback c = (Callback)i.next();
                 c.onDisconnected(source, e);
@@ -139,7 +148,7 @@
         }
 
         public void onConnectFailed(Client source, IOException e) throws 
IOException {
-            Iterator i = listeners.iterator();
+            Iterator i = iterator();
             while (i.hasNext()) {
                 Callback c = (Callback)i.next();
                 c.onConnectFailed(source, e);
@@ -147,7 +156,10 @@
         }
 
         public void onConnect(Client source) throws IOException {
-            Iterator i = listeners.iterator();
+            // Konnichiha, saaba-san!
+            sendLine(greeting);
+            
+            Iterator i = iterator();
             while (i.hasNext()) {
                 Callback c = (Callback)i.next();
                 c.onConnect(source);
@@ -155,7 +167,7 @@
         }
 
         public void onOutgoingLine(Client source, String[] args) throws 
IOException {
-            Iterator i = listeners.iterator();
+            Iterator i = iterator();
             while (i.hasNext()) {
                 Callback c = (Callback)i.next();
                 c.onOutgoingLine(source, args);
@@ -163,7 +175,7 @@
         }
 
         public void onIncomingLine(Client source, String[] args) throws 
IOException {
-            Iterator i = listeners.iterator();
+            Iterator i = iterator();
             while (i.hasNext()) {
                 Callback c = (Callback)i.next();
                 c.onIncomingLine(source, args);
@@ -171,7 +183,7 @@
         }
 
         public void onNeedIdent(Client source) throws IOException {
-            Iterator i = listeners.iterator();
+            Iterator i = iterator();
             while (i.hasNext()) {
                 Callback c = (Callback)i.next();
                 c.onNeedIdent(source);
@@ -179,13 +191,21 @@
         }
 
         public void onAccept(Client source, String name) throws IOException {
-            Iterator i = listeners.iterator();
+            Iterator i = iterator();
             while (i.hasNext()) {
                 Callback c = (Callback)i.next();
                 c.onAccept(source, name);
             }
         }
-        
+
+        public void onReceivedList(Client source, String channel, String 
namespace, String[] list) throws IOException {
+            Iterator i = iterator();
+            while (i.hasNext()) {
+                Callback c = (Callback)i.next();
+                c.onReceivedList(source, channel, namespace, list);
+            }
+        }
+      
     }
     
     protected void gotLine(String[] args) throws IOException {
@@ -216,7 +236,7 @@
                     (new InputStreamReader
                     (theSocket.getInputStream()));
             dist.onConnect(this);
-            ioLoop();
+            ioLoop(new Flag());
         } catch (IOException e) {
             try {
                 dist.onDisconnected(this, e);
@@ -235,10 +255,8 @@
         }
     }
     
-    protected void ioLoop() throws IOException {
-        // Konnichiha, saaba-san!
-        sendLine(greeting);
-        while (io != null) {
+    protected void ioLoop(Flag f) throws IOException {
+        while (io != null && f.ok) {
             String l = reader.readLine();
             if (l == null) {
                 dist.onDisconnected(this, null);
@@ -276,15 +294,38 @@
     
     protected class SyncMonitor extends Callback {
         public IOException fail = null;
+        public Flag flag = new Flag();
         
+        protected void done() {
+            flag.ok = false;
+            notifyAll();
+        }
+        
         public synchronized void onDisconnected(Client source, IOException e) {
             fail = new IOException("Disconnected unexpectedly");
-            notifyAll();
+            done();
         }
         public synchronized void onConnectFailed(Client source, IOException e) 
{
             fail = e;
-            notifyAll();
+            done();
         }
+        
+        public void block() throws IOException {
+            if (Thread.currentThread() == io) {
+                if (flag != null) {
+                    ioLoop(flag);
+                } 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
+                }
+            }
+        }
     }
     
     protected class ConnectMonitor extends SyncMonitor {
@@ -410,4 +451,57 @@
     protected void handle_ACCEPT(String[] args) throws IOException {
         dist.onAccept(this, args[1]);
     }
+    
+    public void requestList(String channel, String namespace) throws 
IOException {
+        String[] cmd = {"LIST", channel, namespace};
+        sendLine(cmd);
+    }
+    
+    protected void handle_LIST(String[] args) throws IOException {
+        String[] list = new String[args.length - 3];
+        System.arraycopy(args, 3, list, 0, args.length - 3);
+        String channel = args[1];
+        String namespace = args[2];
+        
+        dist.onReceivedList(this, channel, namespace, list);
+    }
+    
+    protected class ListMonitor extends SyncMonitor {
+        String[] list = null;
+        String channel;
+        String namespace;
+        
+        public ListMonitor(String channel, String namespace) {
+            this.channel = channel;
+            this.namespace = namespace;
+        }
+
+        public synchronized void onReceivedList(Client source, String channel, 
String namespace, String[] list) {
+            if (channel.equals(this.channel) &&
+                namespace.equals(this.namespace))
+            {
+                this.list = list;
+                done();
+            }
+        }
+    }
+    
+    public String[] syncList(String channel, String namespace) throws 
IOException {
+        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();
+            }
+        }
+    }
 }

Modified: trunk/clients/Javer2/src/javer2/Main.java
===================================================================
--- trunk/clients/Javer2/src/javer2/Main.java   2005-05-22 05:01:49 UTC (rev 
704)
+++ trunk/clients/Javer2/src/javer2/Main.java   2005-05-22 05:05:33 UTC (rev 
705)
@@ -17,8 +17,8 @@
     /** Creates a new instance of Main */
     public Main() throws Throwable {
         c = new Client();
+        c.addNotify(this);
         c.syncConnect("localhost", 15455, "bd_");
-        c.addNotify(this);
         System.out.println("out");
     }
     
@@ -30,13 +30,15 @@
         new Main();
     }
 
-    public String join(String[] parts) {
+    public String join(String joinBy, String[] parts) {
+        if (parts.length == 0) return "";
+        
         StringBuffer b = new StringBuffer();
         for (int i = 0; i < parts.length; i++) {
-            b.append('\t');
+            b.append(joinBy);
             b.append(parts[i]);
         }
-        return b.toString().substring(1);
+        return b.toString().substring(joinBy.length());
     }
     
     public void onDisconnected(Client source, java.io.IOException e) throws 
java.io.IOException {
@@ -46,6 +48,7 @@
 
     public void onConnect(Client source) throws java.io.IOException {
         System.out.println("connected");
+
         super.onConnect(source);
     }
 
@@ -61,6 +64,8 @@
     
     public void onAccept(Client source, String nick) throws 
java.io.IOException {
         System.out.println("Accepted: " + nick);
+        String[] channels = source.syncList("&lobby", "channel");
+        System.out.println("channels: " + join(", ", channels));
         super.onAccept(source, nick);
     }
     


Reply via email to