2
0

Just dispose on close and scope executors to a window, clean up on window hide.

This commit is contained in:
Maarten Billemont 2015-01-03 14:25:20 -05:00
parent 80f507b4cc
commit d1649f3c33
6 changed files with 33 additions and 11 deletions

View File

@ -116,9 +116,6 @@ public class GUI implements UnlockFrame.SignInCallback {
} }
protected PasswordFrame newPasswordFrame(final User user) { protected PasswordFrame newPasswordFrame(final User user) {
PasswordFrame frame = new PasswordFrame( user ); return new PasswordFrame( user );
frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
return frame;
} }
} }

View File

@ -68,6 +68,8 @@ public class ModelUser extends User {
@Override @Override
public void reset() { public void reset() {
super.reset();
masterPassword = null; masterPassword = null;
} }

View File

@ -217,7 +217,7 @@ public class PasswordFrame extends JFrame implements DocumentListener {
site.setSiteCounter( siteCounter ); site.setSiteCounter( siteCounter );
} }
ListenableFuture<String> passwordFuture = Res.execute( new Callable<String>() { ListenableFuture<String> passwordFuture = Res.execute( this, new Callable<String>() {
@Override @Override
public String call() public String call()
throws Exception { throws Exception {

View File

@ -8,9 +8,11 @@ import com.google.common.io.Resources;
import com.google.common.util.concurrent.*; import com.google.common.util.concurrent.*;
import com.lyndir.lhunath.opal.system.logging.Logger; import com.lyndir.lhunath.opal.system.logging.Logger;
import java.awt.*; import java.awt.*;
import java.awt.event.*;
import java.awt.image.ImageObserver; import java.awt.image.ImageObserver;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.WeakHashMap;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -22,8 +24,8 @@ import javax.swing.*;
*/ */
public abstract class Res { public abstract class Res {
private static final ExecutorService executor = Executors.newSingleThreadExecutor(); private static final WeakHashMap<Window, ExecutorService> executorByWindow = new WeakHashMap<>();
private static final Logger logger = Logger.get( Res.class ); private static final Logger logger = Logger.get( Res.class );
private static Font sourceCodeProRegular; private static Font sourceCodeProRegular;
private static Font sourceCodeProBlack; private static Font sourceCodeProBlack;
@ -32,8 +34,8 @@ public abstract class Res {
private static Font exoRegular; private static Font exoRegular;
private static Font exoThin; private static Font exoThin;
public static Future<?> execute(final Runnable job) { public static Future<?> execute(final Window host, final Runnable job) {
return executor.submit( new Runnable() { return getExecutor( host ).submit( new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
@ -46,7 +48,8 @@ public abstract class Res {
} ); } );
} }
public static <V> ListenableFuture<V> execute(final Callable<V> job) { public static <V> ListenableFuture<V> execute(final Window host, final Callable<V> job) {
ExecutorService executor = getExecutor( host );
return JdkFutureAdapters.listenInPoolThread( executor.submit( new Callable<V>() { return JdkFutureAdapters.listenInPoolThread( executor.submit( new Callable<V>() {
@Override @Override
public V call() public V call()
@ -62,6 +65,25 @@ public abstract class Res {
} ), executor ); } ), executor );
} }
private static ExecutorService getExecutor(final Window host) {
ExecutorService executor = executorByWindow.get( host );
if (executor == null) {
executorByWindow.put( host, executor = Executors.newSingleThreadExecutor() );
host.addWindowListener( new WindowAdapter() {
@Override
public void windowClosing(final WindowEvent e) {
ExecutorService executor = executorByWindow.remove( host );
if (executor != null)
executor.shutdownNow();
}
} );
}
return executor;
}
public static Icon iconAdd() { public static Icon iconAdd() {
return new RetinaIcon( Resources.getResource( "media/icon_add@2x.png" ) ); return new RetinaIcon( Resources.getResource( "media/icon_add@2x.png" ) );
} }

View File

@ -134,7 +134,7 @@ public class UnlockFrame extends JFrame {
signInButton.setEnabled( false ); signInButton.setEnabled( false );
signInButton.setText( "Signing In..." ); signInButton.setText( "Signing In..." );
Res.execute( new Runnable() { Res.execute( this, new Runnable() {
@Override @Override
public void run() { public void run() {
final boolean success = signInCallback.signedIn( user ); final boolean success = signInCallback.signedIn( user );

View File

@ -101,6 +101,7 @@
<p>Another strategy is by "encoding" something you already know. This can seem like a good way to make memorable passwords, but recalling the "encoding" you used two years later can be tricky. This also makes it much easier for attackers that know you to find your password.</p> <p>Another strategy is by "encoding" something you already know. This can seem like a good way to make memorable passwords, but recalling the "encoding" you used two years later can be tricky. This also makes it much easier for attackers that know you to find your password.</p>
<p>Master Password itself generates very random passwords that look semi-legible, for instance <code>Togu3]ToxiBuzb</code>. Such passwords have been found to be very memorable while also being very high in entropy (hard to guess).</p> <p>Master Password itself generates very random passwords that look semi-legible, for instance <code>Togu3]ToxiBuzb</code>. Such passwords have been found to be very memorable while also being very high in entropy (hard to guess).</p>
<p>A strategy that's gaining traction lately is that of combining words into a sentence. Some claim it's best for the sentence to make no grammatical sense, others dispute these claims. It's a fact, though, that if your attacker doesn't expect such a password, they're nearly impossible to defeat.</p> <p>A strategy that's gaining traction lately is that of combining words into a sentence. Some claim it's best for the sentence to make no grammatical sense, others dispute these claims. It's a fact, though, that if your attacker doesn't expect such a password, they're nearly impossible to defeat.</p>
<p><iframe width="420" height="315" src="//www.youtube.com/embed/MSyIhapMdI8?start=109" frameborder="0" allowfullscreen></iframe></p>
<p>Let's sum these strategies up in a table, note that this type of comparison is very subjective.</p> <p>Let's sum these strategies up in a table, note that this type of comparison is very subjective.</p>
<table> <table>
<caption>Time to crack a master password</caption> <caption>Time to crack a master password</caption>