Index: sdk/lib/io/http_impl.dart |
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart |
index bea663db3a098c333b542b439f08d77d9e0d1b6a..5d1d53598e03a37bcf3a8731819c1c62738df1f8 100644 |
--- a/sdk/lib/io/http_impl.dart |
+++ b/sdk/lib/io/http_impl.dart |
@@ -1522,6 +1522,7 @@ class _ConnectionTarget { |
final bool isSecure; |
final Set<_HttpClientConnection> _idle = new HashSet(); |
final Set<_HttpClientConnection> _active = new HashSet(); |
+ final Queue _pending = new ListQueue(); |
int _connecting = 0; |
_ConnectionTarget(this.key, this.host, this.port, this.isSecure); |
@@ -1530,7 +1531,7 @@ class _ConnectionTarget { |
bool get hasIdle => _idle.isNotEmpty; |
- bool get hasActive => _active.isNotEmpty && _connecting > 0; |
+ bool get hasActive => _active.isNotEmpty || _connecting > 0; |
_HttpClientConnection takeIdle() { |
assert(hasIdle); |
@@ -1541,6 +1542,12 @@ class _ConnectionTarget { |
return connection; |
} |
+ _checkPending() { |
+ if (_pending.isNotEmpty) { |
+ _pending.removeFirst()(); |
+ } |
+ } |
+ |
void addNewActive(_HttpClientConnection connection) { |
_active.add(connection); |
} |
@@ -1549,12 +1556,15 @@ class _ConnectionTarget { |
assert(_active.contains(connection)); |
_active.remove(connection); |
_idle.add(connection); |
+ connection.startTimer(); |
+ _checkPending(); |
} |
void connectionClosed(_HttpClientConnection connection) { |
assert(!_active.contains(connection) || !_idle.contains(connection)); |
_active.remove(connection); |
_idle.remove(connection); |
+ _checkPending(); |
} |
void close(bool force) { |
@@ -1577,6 +1587,15 @@ class _ConnectionTarget { |
client._updateTimers(); |
return new Future.value(new _ConnectionInfo(connection, proxy)); |
} |
+ if (client.maxConnectionsPerHost != null && |
+ _active.length + _connecting >= client.maxConnectionsPerHost) { |
+ var completer = new Completer(); |
+ _pending.add(() { |
+ connect(uriHost, uriPort, proxy, client) |
+ .then(completer.complete, onError: completer.completeError); |
+ }); |
+ return completer.future; |
+ } |
var currentBadCertificateCallback = client._badCertificateCallback; |
bool callback(X509Certificate certificate) => |
currentBadCertificateCallback == null ? false : |
@@ -1604,6 +1623,10 @@ class _ConnectionTarget { |
addNewActive(connection); |
return new _ConnectionInfo(connection, proxy); |
} |
+ }, onError: (error) { |
+ _connecting--; |
+ _checkPending(); |
+ throw error; |
}); |
} |
} |
@@ -1625,6 +1648,8 @@ class _HttpClient implements HttpClient { |
Duration get idleTimeout => _idleTimeout; |
+ int maxConnectionsPerHost; |
+ |
String userAgent = _getHttpVersion(); |
void set idleTimeout(Duration timeout) { |
@@ -1794,7 +1819,6 @@ class _HttpClient implements HttpClient { |
// Return a live connection to the idle pool. |
void _returnConnection(_HttpClientConnection connection) { |
_connectionTargets[connection.key].returnConnection(connection); |
- connection.startTimer(); |
_updateTimers(); |
} |