More case insensitive tests and read write lock for connections

This commit is contained in:
md_5 2013-05-25 16:50:04 +10:00
parent a51ffb1f4c
commit ac4bab2425
3 changed files with 66 additions and 12 deletions

View File

@ -31,6 +31,8 @@ import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.Level;
import java.util.logging.Logger;
import lombok.Getter;
@ -98,7 +100,8 @@ public class BungeeCord extends ProxyServer
/**
* Fully qualified connections.
*/
public TMap<String, UserConnection> connections = new CaseInsensitiveMap<>();
private final TMap<String, UserConnection> connections = new CaseInsensitiveMap<>();
private final ReadWriteLock connectionLock = new ReentrantReadWriteLock();
/**
* Tab list handler
*/
@ -278,11 +281,18 @@ public class BungeeCord extends ProxyServer
stopListeners();
getLogger().info( "Closing pending connections" );
connectionLock.readLock().lock();
try
{
getLogger().info( "Disconnecting " + connections.size() + " connections" );
for ( UserConnection user : connections.values() )
{
user.disconnect( getTranslation( "restart" ) );
}
} finally
{
connectionLock.readLock().unlock();
}
getLogger().info( "Closing IO threads" );
eventLoops.shutdownGracefully();
@ -309,11 +319,18 @@ public class BungeeCord extends ProxyServer
* @param packet the packet to send
*/
public void broadcast(DefinedPacket packet)
{
connectionLock.readLock().lock();
try
{
for ( UserConnection con : connections.values() )
{
con.sendPacket( packet );
}
} finally
{
connectionLock.readLock().unlock();
}
}
@Override
@ -356,8 +373,15 @@ public class BungeeCord extends ProxyServer
@Override
public ProxiedPlayer getPlayer(String name)
{
connectionLock.readLock().lock();
try
{
return connections.get( name );
} finally
{
connectionLock.readLock().unlock();
}
}
@Override
@ -435,4 +459,28 @@ public class BungeeCord extends ProxyServer
{
return ConsoleCommandSender.getInstance();
}
public void addConnection(UserConnection con)
{
connectionLock.writeLock().lock();
try
{
connections.put( con.getName(), con );
} finally
{
connectionLock.writeLock().unlock();
}
}
public void removeConnection(UserConnection con)
{
connectionLock.writeLock().lock();
try
{
connections.remove( con.getName() );
} finally
{
connectionLock.writeLock().unlock();
}
}
}

View File

@ -27,7 +27,7 @@ public class UpstreamBridge extends PacketHandler
this.bungee = bungee;
this.con = con;
BungeeCord.getInstance().connections.put( con.getName(), con );
BungeeCord.getInstance().addConnection( con );
bungee.getTabListHandler().onConnect( con );
con.sendPacket( BungeeCord.getInstance().registerChannels() );
@ -51,7 +51,7 @@ public class UpstreamBridge extends PacketHandler
PlayerDisconnectEvent event = new PlayerDisconnectEvent( con );
bungee.getPluginManager().callEvent( event );
bungee.getTabListHandler().onDisconnect( con );
BungeeCord.getInstance().connections.remove( con.getName() ); //TODO: Better way, why do we need to raw access?
BungeeCord.getInstance().removeConnection( con );
if ( con.getServer() != null )
{

View File

@ -13,8 +13,12 @@ public class CaseInsensitiveTest
CaseInsensitiveMap<Object> map = new CaseInsensitiveMap<>();
map.put( "FOO", obj );
Assert.assertTrue( map.contains( "foo" ) ); // Assert that it is case insensitive
Assert.assertTrue( map.entrySet().iterator().next().getKey().equals( "FOO" ) ); // Asert that case is preserved
Assert.assertTrue( map.contains( "foo" ) ); // Assert that contains is case insensitive
Assert.assertTrue( map.entrySet().iterator().next().getKey().equals( "FOO" ) ); // Assert that case is preserved
// Assert that remove is case insensitive
map.remove( "FoO" );
Assert.assertFalse( map.contains( "foo" ) );
}
@Test
@ -23,6 +27,8 @@ public class CaseInsensitiveTest
CaseInsensitiveSet set = new CaseInsensitiveSet();
set.add( "FOO" );
Assert.assertTrue( set.contains( "foo" ) );
Assert.assertTrue( set.contains( "foo" ) ); // Assert that contains is case insensitive
set.remove( "FoO" );
Assert.assertFalse( set.contains( "foo" ) ); // Assert that remove is case insensitive
}
}