aboutsummaryrefslogtreecommitdiffstats
path: root/AndroidAsync
diff options
context:
space:
mode:
authorKoushik Dutta <koushd@gmail.com>2014-12-21 17:10:01 -0800
committerKoushik Dutta <koushd@gmail.com>2014-12-21 17:10:01 -0800
commit5840fd01717e0782f1f3c809579067b7d0556448 (patch)
tree2f26430542301ac4577e422f45cf32888d236efd /AndroidAsync
parent8aabbd1fb850e4a8cea54c45c8de9dc715c5c70a (diff)
downloadAndroidAsync-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.java2
-rw-r--r--AndroidAsync/src/com/koushikdutta/async/http/spdy/SpdyMiddleware.java36
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) {