diff options
author | Koushik Dutta <koushd@gmail.com> | 2014-12-21 17:10:01 -0800 |
---|---|---|
committer | Koushik Dutta <koushd@gmail.com> | 2014-12-21 17:10:01 -0800 |
commit | 5840fd01717e0782f1f3c809579067b7d0556448 (patch) | |
tree | 2f26430542301ac4577e422f45cf32888d236efd /AndroidAsync | |
parent | 8aabbd1fb850e4a8cea54c45c8de9dc715c5c70a (diff) | |
download | AndroidAsync-5840fd01717e0782f1f3c809579067b7d0556448.tar.gz AndroidAsync-5840fd01717e0782f1f3c809579067b7d0556448.tar.bz2 AndroidAsync-5840fd01717e0782f1f3c809579067b7d0556448.zip |
Fix up various race and reuse issues around spdy.
Diffstat (limited to 'AndroidAsync')
-rw-r--r-- | AndroidAsync/src/com/koushikdutta/async/http/AsyncSSLSocketMiddleware.java | 2 | ||||
-rw-r--r-- | AndroidAsync/src/com/koushikdutta/async/http/spdy/SpdyMiddleware.java | 36 |
2 files changed, 26 insertions, 12 deletions
diff --git a/AndroidAsync/src/com/koushikdutta/async/http/AsyncSSLSocketMiddleware.java b/AndroidAsync/src/com/koushikdutta/async/http/AsyncSSLSocketMiddleware.java index d557a31..0a0199a 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/AsyncSSLSocketMiddleware.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/AsyncSSLSocketMiddleware.java @@ -68,7 +68,7 @@ public class AsyncSSLSocketMiddleware extends AsyncSocketMiddleware { return sslEngine; } - protected AsyncSSLSocketWrapper.HandshakeCallback createHandshakeCallback(GetSocketData data, final ConnectCallback callback) { + protected AsyncSSLSocketWrapper.HandshakeCallback createHandshakeCallback(final GetSocketData data, final ConnectCallback callback) { return new AsyncSSLSocketWrapper.HandshakeCallback() { @Override public void onHandshakeCompleted(Exception e, AsyncSSLSocket socket) { diff --git a/AndroidAsync/src/com/koushikdutta/async/http/spdy/SpdyMiddleware.java b/AndroidAsync/src/com/koushikdutta/async/http/spdy/SpdyMiddleware.java index 5150069..ff520d2 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/spdy/SpdyMiddleware.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/spdy/SpdyMiddleware.java @@ -120,9 +120,14 @@ public class SpdyMiddleware extends AsyncSSLSocketMiddleware { Field useSni; Method nativeGetNpnNegotiatedProtocol; Method nativeGetAlpnNegotiatedProtocol; - Hashtable<String, MultiFuture<AsyncSpdyConnection>> connections = new Hashtable<String, MultiFuture<AsyncSpdyConnection>>(); + Hashtable<String, SpdyConnectionWaiter> connections = new Hashtable<String, SpdyConnectionWaiter>(); boolean spdyEnabled; + private static class SpdyConnectionWaiter { + AsyncSpdyConnection conn; + MultiFuture<AsyncSpdyConnection> future = new MultiFuture<AsyncSpdyConnection>(); + } + public boolean getSpdyEnabled() { return spdyEnabled; } @@ -162,12 +167,12 @@ public class SpdyMiddleware extends AsyncSSLSocketMiddleware { private static class NoSpdyException extends Exception { } - private static NoSpdyException NO_SPDY = new NoSpdyException(); + private static final NoSpdyException NO_SPDY = new NoSpdyException(); private void noSpdy(String key) { - MultiFuture<AsyncSpdyConnection> conn = connections.remove(key); + SpdyConnectionWaiter conn = connections.remove(key); if (conn != null) - conn.setComplete(NO_SPDY); + conn.future.setComplete(NO_SPDY); } @Override @@ -208,7 +213,9 @@ public class SpdyMiddleware extends AsyncSSLSocketMiddleware { } hasReceivedSettings = true; - connections.get(key).setComplete(this); + SpdyConnectionWaiter waiter = connections.get(key); + waiter.conn = this; + waiter.future.setComplete(this); data.request.logv("using new spdy connection for host: " + data.request.getUri().getHost()); newSocket(data, this, callback); } @@ -292,17 +299,24 @@ public class SpdyMiddleware extends AsyncSSLSocketMiddleware { return super.getSocket(data); // can we use an existing connection to satisfy this, or do we need a new one? - String host = uri.getHost(); - MultiFuture<AsyncSpdyConnection> conn = connections.get(host); + String key = uri.getHost(); + SpdyConnectionWaiter conn = connections.get(key); + if (conn != null && conn.conn != null && !conn.conn.socket.isOpen()) { + connections.remove(key); + conn = null; + } + if (conn == null) { - conn = new MultiFuture<AsyncSpdyConnection>(); - connections.put(host, conn); - return super.getSocket(data); + Cancellable superSocket = super.getSocket(data);; + // see if we reuse a socket synchronously, otherwise a new connection is being created + if (!superSocket.isDone()) + connections.put(key, new SpdyConnectionWaiter()); + return superSocket; } final SimpleCancellable ret = new SimpleCancellable(); data.request.logv("using existing spdy connection for host: " + data.request.getUri().getHost()); - conn.setCallback(new FutureCallback<AsyncSpdyConnection>() { + conn.future.setCallback(new FutureCallback<AsyncSpdyConnection>() { @Override public void onCompleted(Exception e, AsyncSpdyConnection conn) { if (e instanceof NoSpdyException) { |