diff --git a/guacamole-common/src/main/java/org/glyptodon/guacamole/net/SynchronizedGuacamoleTunnel.java b/guacamole-common/src/main/java/org/glyptodon/guacamole/net/AbstractGuacamoleTunnel.java similarity index 60% rename from guacamole-common/src/main/java/org/glyptodon/guacamole/net/SynchronizedGuacamoleTunnel.java rename to guacamole-common/src/main/java/org/glyptodon/guacamole/net/AbstractGuacamoleTunnel.java index be4271df6..d8da19477 100644 --- a/guacamole-common/src/main/java/org/glyptodon/guacamole/net/SynchronizedGuacamoleTunnel.java +++ b/guacamole-common/src/main/java/org/glyptodon/guacamole/net/AbstractGuacamoleTunnel.java @@ -23,32 +23,19 @@ package org.glyptodon.guacamole.net; -import java.util.UUID; import java.util.concurrent.locks.ReentrantLock; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.io.GuacamoleReader; import org.glyptodon.guacamole.io.GuacamoleWriter; /** - * GuacamoleTunnel implementation which synchronizes access to the underlying - * reader and write with reentrant locks. + * Base GuacamoleTunnel implementation which synchronizes access to the + * underlying reader and writer with reentrant locks. Implementations need only + * provide the tunnel's UUID and socket. * * @author Michael Jumper */ -public class SynchronizedGuacamoleTunnel implements GuacamoleTunnel { - - /** - * The UUID associated with this tunnel. Every tunnel must have a - * corresponding UUID such that tunnel read/write requests can be - * directed to the proper tunnel. - */ - private final UUID uuid; - - /** - * The GuacamoleSocket that tunnel should use for communication on - * behalf of the connecting user. - */ - private final GuacamoleSocket socket; +public abstract class AbstractGuacamoleTunnel implements GuacamoleTunnel { /** * Lock acquired when a read operation is in progress. @@ -62,42 +49,67 @@ public class SynchronizedGuacamoleTunnel implements GuacamoleTunnel { /** * Creates a new GuacamoleTunnel which synchronizes access to the - * Guacamole instruction stream associated with the given GuacamoleSocket. - * - * @param socket The GuacamoleSocket to provide synchronized access for. + * Guacamole instruction stream associated with the underlying + * GuacamoleSocket. */ - public SynchronizedGuacamoleTunnel(GuacamoleSocket socket) { - - this.socket = socket; - uuid = UUID.randomUUID(); - + public AbstractGuacamoleTunnel() { readerLock = new ReentrantLock(); writerLock = new ReentrantLock(); - } + /** + * Acquires exclusive read access to the Guacamole instruction stream + * and returns a GuacamoleReader for reading from that stream. + * + * @return A GuacamoleReader for reading from the Guacamole instruction + * stream. + */ @Override public GuacamoleReader acquireReader() { readerLock.lock(); - return socket.getReader(); + return getSocket().getReader(); } + /** + * Relinquishes exclusive read access to the Guacamole instruction + * stream. This function should be called whenever a thread finishes using + * a GuacamoleTunnel's GuacamoleReader. + */ @Override public void releaseReader() { readerLock.unlock(); } + /** + * Returns whether there are threads waiting for read access to the + * Guacamole instruction stream. + * + * @return true if threads are waiting for read access the Guacamole + * instruction stream, false otherwise. + */ @Override public boolean hasQueuedReaderThreads() { return readerLock.hasQueuedThreads(); } + /** + * Acquires exclusive write access to the Guacamole instruction stream + * and returns a GuacamoleWriter for writing to that stream. + * + * @return A GuacamoleWriter for writing to the Guacamole instruction + * stream. + */ @Override public GuacamoleWriter acquireWriter() { writerLock.lock(); - return socket.getWriter(); + return getSocket().getWriter(); } + /** + * Relinquishes exclusive write access to the Guacamole instruction + * stream. This function should be called whenever a thread finishes using + * a GuacamoleTunnel's GuacamoleWriter. + */ @Override public void releaseWriter() { writerLock.unlock(); @@ -108,24 +120,14 @@ public class SynchronizedGuacamoleTunnel implements GuacamoleTunnel { return writerLock.hasQueuedThreads(); } - @Override - public UUID getUUID() { - return uuid; - } - - @Override - public GuacamoleSocket getSocket() { - return socket; - } - @Override public void close() throws GuacamoleException { - socket.close(); + getSocket().close(); } @Override public boolean isOpen() { - return socket.isOpen(); + return getSocket().isOpen(); } } diff --git a/guacamole-common/src/main/java/org/glyptodon/guacamole/net/SimpleGuacamoleTunnel.java b/guacamole-common/src/main/java/org/glyptodon/guacamole/net/SimpleGuacamoleTunnel.java new file mode 100644 index 000000000..f0c28cb4e --- /dev/null +++ b/guacamole-common/src/main/java/org/glyptodon/guacamole/net/SimpleGuacamoleTunnel.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2015 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.glyptodon.guacamole.net; + + +import java.util.UUID; + +/** + * GuacamoleTunnel implementation which uses a provided socket. The UUID of + * the tunnel will be randomly generated. + * + * @author Michael Jumper + */ +public class SimpleGuacamoleTunnel extends AbstractGuacamoleTunnel { + + /** + * The UUID associated with this tunnel. Every tunnel must have a + * corresponding UUID such that tunnel read/write requests can be + * directed to the proper tunnel. + */ + private final UUID uuid = UUID.randomUUID(); + + /** + * The GuacamoleSocket that tunnel should use for communication on + * behalf of the connecting user. + */ + private final GuacamoleSocket socket; + + /** + * Creates a new GuacamoleTunnel which synchronizes access to the + * Guacamole instruction stream associated with the given GuacamoleSocket. + * + * @param socket The GuacamoleSocket to provide synchronized access for. + */ + public SimpleGuacamoleTunnel(GuacamoleSocket socket) { + this.socket = socket; + } + + @Override + public UUID getUUID() { + return uuid; + } + + @Override + public GuacamoleSocket getSocket() { + return socket; + } + +} diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleConnection.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleConnection.java index 9aeb0c81c..a1ae0e3f0 100644 --- a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleConnection.java +++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleConnection.java @@ -31,7 +31,7 @@ import org.glyptodon.guacamole.net.GuacamoleSocket; import org.glyptodon.guacamole.net.GuacamoleTunnel; import org.glyptodon.guacamole.net.InetGuacamoleSocket; import org.glyptodon.guacamole.net.SSLGuacamoleSocket; -import org.glyptodon.guacamole.net.SynchronizedGuacamoleTunnel; +import org.glyptodon.guacamole.net.SimpleGuacamoleTunnel; import org.glyptodon.guacamole.net.auth.AbstractConnection; import org.glyptodon.guacamole.net.auth.ConnectionRecord; import org.glyptodon.guacamole.protocol.ConfiguredGuacamoleSocket; @@ -111,7 +111,7 @@ public class SimpleConnection extends AbstractConnection { config, info ); - return new SynchronizedGuacamoleTunnel(socket); + return new SimpleGuacamoleTunnel(socket); }