Index: sdk/lib/io/http_impl.dart |
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart |
index fc69108579c0a95e86f0ba3ef153916f4f40b47f..5c4387e42cf93aee79508b36836eaab4b7ea2dc1 100644 |
--- a/sdk/lib/io/http_impl.dart |
+++ b/sdk/lib/io/http_impl.dart |
@@ -27,6 +27,7 @@ class _CloseQueue { |
return; |
} |
+ connection._state |= _HttpConnectionBase.CLOSING; |
_q.add(connection); |
// If output stream is not closed for writing close it now and |
@@ -49,6 +50,7 @@ class _CloseQueue { |
// information for anything. For both server and client |
// connections the inbound message have been read to |
// completion when the socket enters the close queue. |
+ closeIfDone(); |
}; |
} else { |
connection._socket.onClosed = () { assert(false); }; |
@@ -718,17 +720,21 @@ class _HttpOutputStream extends _BaseOutputStream implements OutputStream { |
abstract class _HttpConnectionBase { |
static const int IDLE = 0; |
static const int ACTIVE = 1; |
- static const int REQUEST_DONE = 2; |
- static const int RESPONSE_DONE = 4; |
+ static const int CLOSING = 2; |
+ static const int REQUEST_DONE = 4; |
+ static const int RESPONSE_DONE = 8; |
static const int ALL_DONE = REQUEST_DONE | RESPONSE_DONE; |
- static const int READ_CLOSED = 8; |
- static const int WRITE_CLOSED = 16; |
+ static const int READ_CLOSED = 16; |
+ static const int WRITE_CLOSED = 32; |
static const int FULLY_CLOSED = READ_CLOSED | WRITE_CLOSED; |
_HttpConnectionBase() : hashCode = _nextHashCode { |
_nextHashCode = (_nextHashCode + 1) & 0xFFFFFFF; |
} |
+ bool get _isIdle => (_state & ACTIVE) == 0; |
+ bool get _isActive => (_state & ACTIVE) == ACTIVE; |
+ bool get _isClosing => (_state & CLOSING) == CLOSING; |
bool get _isRequestDone => (_state & REQUEST_DONE) == REQUEST_DONE; |
bool get _isResponseDone => (_state & RESPONSE_DONE) == RESPONSE_DONE; |
bool get _isAllDone => (_state & ALL_DONE) == ALL_DONE; |
@@ -832,6 +838,7 @@ class _HttpConnection extends _HttpConnectionBase { |
void _onClosed() { |
_state |= _HttpConnectionBase.READ_CLOSED; |
+ _checkDone(); |
} |
void _onError(e) { |
@@ -884,6 +891,9 @@ class _HttpConnection extends _HttpConnectionBase { |
} else { |
_state = _HttpConnectionBase.IDLE; |
} |
+ } else if (_state == _HttpConnectionBase.READ_CLOSED) { |
+ // If entering READ_CLOSED state while idle close the connection. |
+ _server._closeQueue.add(this); |
} |
} |
@@ -1024,6 +1034,21 @@ class _HttpServer implements HttpServer { |
return _sessionManagerInstance; |
} |
+ HttpConnectionsInfo connectionsInfo() { |
+ HttpConnectionsInfo result = new HttpConnectionsInfo(); |
+ result.total = _connections.length; |
+ _connections.forEach((_HttpConnection conn) { |
+ if (conn._isActive) { |
+ result.active++; |
+ } else if (conn._isIdle) { |
+ result.idle++; |
+ } else { |
+ assert(result._isClosing); |
+ result.closing++; |
+ } |
+ }); |
+ return result; |
+ } |
ServerSocket _server; // The server listen socket. |
bool _closeServer = false; |
@@ -1435,6 +1460,7 @@ class _HttpClientConnection |
void _onClosed() { |
_state |= _HttpConnectionBase.READ_CLOSED; |
+ _checkSocketDone(); |
} |
void _onError(e) { |