X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=lib%2Fjava%2Fdolda%2Fdolcon%2Fprotocol%2FConnection.java;h=03152bce6783aeec86c775bd369fa232043451cd;hb=1505a392760fb7941871183ea9e7c9be90ee2273;hp=20c06d63c45d7af60bc20c1cee3fd4357ee71f4f;hpb=4b9878719cd3f8ee3279da419119ccb2fecd4266;p=doldaconnect.git diff --git a/lib/java/dolda/dolcon/protocol/Connection.java b/lib/java/dolda/dolcon/protocol/Connection.java index 20c06d6..03152bc 100644 --- a/lib/java/dolda/dolcon/protocol/Connection.java +++ b/lib/java/dolda/dolcon/protocol/Connection.java @@ -14,13 +14,14 @@ public class Connection { private String aspec; private String state; private Set connls = new HashSet(); + private Set notls = new HashSet(); private Exception error; public interface ConnectListener { public void connected() throws Exception; public void error(Exception cause); } - + public Connection(String aspec) { this.aspec = aspec; state = "idle"; @@ -41,7 +42,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 +73,7 @@ public class Connection { } } } - }); + }; pending.offer(ccmd); reader = new Reader(); writer = new Writer(); @@ -112,7 +113,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 +141,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) { @@ -162,6 +163,18 @@ public class Connection { return(error); } + public void addNotifyListener(NotifyListener l) { + synchronized(notls) { + notls.add(l); + } + } + + public void removeNotifyListener(NotifyListener l) { + synchronized(notls) { + notls.remove(l); + } + } + public synchronized void addConnectListener(ConnectListener l) { if((state != "idle") && (state != "connecting")) throw(new IllegalStateException("Already connected")); @@ -170,13 +183,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; @@ -263,6 +312,12 @@ public class Connection { queue.notifyAll(); } resp.cmd.done(resp); + } else { + synchronized(notls) { + for(NotifyListener l : notls) { + l.notified(resp); + } + } } }