Merge pull request #309 from glyptodon/concurrency

GUAC-1427: Fix possible issues with concurrency.
This commit is contained in:
James Muehlner
2015-12-16 21:26:37 -08:00
2 changed files with 21 additions and 27 deletions

View File

@@ -22,10 +22,10 @@
package org.glyptodon.guacamole.servlet;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@@ -65,8 +65,8 @@ class GuacamoleHTTPTunnelMap {
/**
* Map of all tunnels that are using HTTP, indexed by tunnel UUID.
*/
private final Map<String, GuacamoleHTTPTunnel> tunnelMap =
Collections.synchronizedMap(new LinkedHashMap<String, GuacamoleHTTPTunnel>(16, 0.75f, true));
private final ConcurrentMap<String, GuacamoleHTTPTunnel> tunnelMap =
new ConcurrentHashMap<String, GuacamoleHTTPTunnel>();
/**
* Creates a new GuacamoleHTTPTunnelMap which automatically closes and
@@ -124,9 +124,12 @@ class GuacamoleHTTPTunnelMap {
// If tunnel is too old, close and remove it
if (age >= tunnelTimeout) {
// Remove old entry
logger.debug("HTTP tunnel \"{}\" has timed out.", entry.getKey());
entries.remove();
// Attempt to close tunnel
try {
tunnel.close();
}
@@ -136,14 +139,9 @@ class GuacamoleHTTPTunnelMap {
}
// Otherwise, this tunnel has been recently used, as have all
// other tunnels following this one within tunnelMap
else
break;
} // end for each tunnel
}
}
} // end timeout task run()
}

View File

@@ -22,10 +22,10 @@
package org.glyptodon.guacamole.net.basic.rest.auth;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@@ -57,8 +57,8 @@ public class BasicTokenSessionMap implements TokenSessionMap {
/**
* Keeps track of the authToken to GuacamoleSession mapping.
*/
private final Map<String, GuacamoleSession> sessionMap =
Collections.synchronizedMap(new LinkedHashMap<String, GuacamoleSession>(16, 0.75f, true));
private final ConcurrentMap<String, GuacamoleSession> sessionMap =
new ConcurrentHashMap<String, GuacamoleSession>();
/**
* Create a new BasicTokenGuacamoleSessionMap configured using the given
@@ -89,9 +89,7 @@ public class BasicTokenSessionMap implements TokenSessionMap {
/**
* Task which iterates through all active sessions, evicting those sessions
* which are beyond the session timeout. This is a fairly easy thing to do,
* since the session storage structure guarantees that sessions are always
* in descending order of age.
* which are beyond the session timeout.
*/
private class SessionEvictionTask implements Runnable {
@@ -114,11 +112,11 @@ public class BasicTokenSessionMap implements TokenSessionMap {
@Override
public void run() {
// Get current time
long now = System.currentTimeMillis();
// Get start time of session check time
long sessionCheckStart = System.currentTimeMillis();
logger.debug("Checking for expired sessions...");
// For each session, remove sesions which have expired
Iterator<Map.Entry<String, GuacamoleSession>> entries = sessionMap.entrySet().iterator();
while (entries.hasNext()) {
@@ -131,7 +129,7 @@ public class BasicTokenSessionMap implements TokenSessionMap {
continue;
// Get elapsed time since last access
long age = now - session.getLastAccessedTime();
long age = sessionCheckStart - session.getLastAccessedTime();
// If session is too old, evict it and check the next one
if (age >= sessionTimeout) {
@@ -140,13 +138,11 @@ public class BasicTokenSessionMap implements TokenSessionMap {
session.invalidate();
}
// Otherwise, no other sessions can possibly be old enough
else
break;
}
logger.debug("Session check complete.");
// Log completion and duration
logger.debug("Session check completed in {} ms.",
System.currentTimeMillis() - sessionCheckStart);
}