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);
}