From 6bc193f2ce2a87a667e2a83aac01135520fdee26 Mon Sep 17 00:00:00 2001 From: Fredrik Tolf Date: Sun, 27 Jan 2008 22:17:14 +0100 Subject: [PATCH] Java: Added ecmd to the connection manager. --- lib/java/dolda/dolcon/protocol/Command.java | 16 +++++---- lib/java/dolda/dolcon/protocol/Connection.java | 46 +++++++++++++++++++++++--- 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/lib/java/dolda/dolcon/protocol/Command.java b/lib/java/dolda/dolcon/protocol/Command.java index 98f8881..57db964 100644 --- a/lib/java/dolda/dolcon/protocol/Command.java +++ b/lib/java/dolda/dolcon/protocol/Command.java @@ -7,9 +7,13 @@ public class Command { Set listeners = new HashSet(); Response resp; - public interface Listener { - public void done(Response resp) throws Exception; - public void error(Exception cause); + public abstract class Listener { + public Listener() { + addlst(this); + } + + public abstract void done(Response resp) throws Exception; + public abstract void error(Exception cause); } public Command(List tokens) { @@ -20,17 +24,17 @@ public class Command { this(Arrays.asList(tokens)); } - public void addListener(Listener l) { + private synchronized void addlst(Listener l) { listeners.add(l); } - public void done(Response resp) throws Exception { + public synchronized void done(Response resp) throws Exception { this.resp = resp; for(Listener l : listeners) l.done(resp); } - public void error(Exception cause) { + public synchronized void error(Exception cause) { for(Listener l : listeners) l.error(cause); } diff --git a/lib/java/dolda/dolcon/protocol/Connection.java b/lib/java/dolda/dolcon/protocol/Connection.java index 20c06d6..31bb172 100644 --- a/lib/java/dolda/dolcon/protocol/Connection.java +++ b/lib/java/dolda/dolcon/protocol/Connection.java @@ -41,7 +41,7 @@ public class Connection { } pending = new LinkedList(); Command ccmd = new Command(".connect"); - ccmd.addListener(new Command.Listener() { + ccmd.new Listener() { public void done(Response resp) throws Exception { try { checkver(resp); @@ -72,7 +72,7 @@ public class Connection { } } } - }); + }; pending.offer(ccmd); reader = new Reader(); writer = new Writer(); @@ -112,7 +112,7 @@ public class Connection { throw(new RuntimeException("Cannot call synchronous method with dispatch thread!")); } - public void syncConnect() throws ConnectException, ClosedException, InterruptedException { + public void syncConnect() throws ConnectException, InterruptedException { checkthread(); final boolean[] donep = new boolean[] {false}; final Exception[] errp = new Exception[] {null}; @@ -140,7 +140,7 @@ public class Connection { } } if(errp[0] != null) - throw(new ClosedException(errp[0])); + throw(new ConnectException("DC connection has been closed", errp[0])); } public void expectVersion(int reqver) { @@ -170,13 +170,49 @@ public class Connection { } } - private void qcmd(Command cmd) { + public void qcmd(Command cmd) { synchronized(queue) { queue.offer(cmd); queue.notifyAll(); } } + public void qcmd(String... tokens) { + qcmd(new Command(tokens)); + } + + public Response ecmd(Command cmd) throws ClosedException, InterruptedException { + checkthread(); + final boolean[] donep = new boolean[] {false}; + final Response[] resp = new Response[] {null}; + final Exception[] errp = new Exception[] {null}; + Object l = cmd.new Listener() { + public synchronized void done(Response rsp) { + resp[0] = rsp; + donep[0] = true; + notifyAll(); + } + + public synchronized void error(Exception e) { + errp[0] = e; + donep[0] = true; + notifyAll(); + } + }; + synchronized(l) { + while(!donep[0]) { + l.wait(); + } + } + if(errp[0] != null) + throw(new ClosedException(errp[0])); + return(resp[0]); + } + + public Response ecmd(String... tokens) throws ClosedException, InterruptedException { + return(ecmd(new Command(tokens))); + } + static private class StopCondition extends Error { final boolean normal; -- 2.11.0