GUAC-1132: Refactor much of SynchronizedGuacamoleTunnel into AbstractGuacamaoleTunnel. Rename to SimpleGuacamoleTunnel.

This commit is contained in:
Michael Jumper
2015-03-17 15:42:07 -07:00
parent a345ee7385
commit d55de3e869
3 changed files with 113 additions and 42 deletions

View File

@@ -23,32 +23,19 @@
package org.glyptodon.guacamole.net; package org.glyptodon.guacamole.net;
import java.util.UUID;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.io.GuacamoleReader; import org.glyptodon.guacamole.io.GuacamoleReader;
import org.glyptodon.guacamole.io.GuacamoleWriter; import org.glyptodon.guacamole.io.GuacamoleWriter;
/** /**
* GuacamoleTunnel implementation which synchronizes access to the underlying * Base GuacamoleTunnel implementation which synchronizes access to the
* reader and write with reentrant locks. * underlying reader and writer with reentrant locks. Implementations need only
* provide the tunnel's UUID and socket.
* *
* @author Michael Jumper * @author Michael Jumper
*/ */
public class SynchronizedGuacamoleTunnel implements GuacamoleTunnel { public abstract class AbstractGuacamoleTunnel 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;
/** /**
* Lock acquired when a read operation is in progress. * 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 * Creates a new GuacamoleTunnel which synchronizes access to the
* Guacamole instruction stream associated with the given GuacamoleSocket. * Guacamole instruction stream associated with the underlying
* * GuacamoleSocket.
* @param socket The GuacamoleSocket to provide synchronized access for.
*/ */
public SynchronizedGuacamoleTunnel(GuacamoleSocket socket) { public AbstractGuacamoleTunnel() {
this.socket = socket;
uuid = UUID.randomUUID();
readerLock = new ReentrantLock(); readerLock = new ReentrantLock();
writerLock = 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 @Override
public GuacamoleReader acquireReader() { public GuacamoleReader acquireReader() {
readerLock.lock(); 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 @Override
public void releaseReader() { public void releaseReader() {
readerLock.unlock(); 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 @Override
public boolean hasQueuedReaderThreads() { public boolean hasQueuedReaderThreads() {
return readerLock.hasQueuedThreads(); 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 @Override
public GuacamoleWriter acquireWriter() { public GuacamoleWriter acquireWriter() {
writerLock.lock(); 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 @Override
public void releaseWriter() { public void releaseWriter() {
writerLock.unlock(); writerLock.unlock();
@@ -108,24 +120,14 @@ public class SynchronizedGuacamoleTunnel implements GuacamoleTunnel {
return writerLock.hasQueuedThreads(); return writerLock.hasQueuedThreads();
} }
@Override
public UUID getUUID() {
return uuid;
}
@Override
public GuacamoleSocket getSocket() {
return socket;
}
@Override @Override
public void close() throws GuacamoleException { public void close() throws GuacamoleException {
socket.close(); getSocket().close();
} }
@Override @Override
public boolean isOpen() { public boolean isOpen() {
return socket.isOpen(); return getSocket().isOpen();
} }
} }

View File

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

View File

@@ -31,7 +31,7 @@ import org.glyptodon.guacamole.net.GuacamoleSocket;
import org.glyptodon.guacamole.net.GuacamoleTunnel; import org.glyptodon.guacamole.net.GuacamoleTunnel;
import org.glyptodon.guacamole.net.InetGuacamoleSocket; import org.glyptodon.guacamole.net.InetGuacamoleSocket;
import org.glyptodon.guacamole.net.SSLGuacamoleSocket; 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.AbstractConnection;
import org.glyptodon.guacamole.net.auth.ConnectionRecord; import org.glyptodon.guacamole.net.auth.ConnectionRecord;
import org.glyptodon.guacamole.protocol.ConfiguredGuacamoleSocket; import org.glyptodon.guacamole.protocol.ConfiguredGuacamoleSocket;
@@ -111,7 +111,7 @@ public class SimpleConnection extends AbstractConnection {
config, info config, info
); );
return new SynchronizedGuacamoleTunnel(socket); return new SimpleGuacamoleTunnel(socket);
} }