- Rename "nodefer" to "immediate" (gets rid of double negative in "nodefer: false").
- Immediate close means that anything pending will be discarded.
- Plumb immediate all the way down to the handle watcher close call.
- When an EventStream is closed because no one is listening for events, close immediately.
- Don't call Dart_NewSendPort with ILLEGAL_PORT in sky embedder.
- Bump DEPS to include fixes for Dart_NewSendPort and profiler signal handler executing after shared object is unloaded.
- Fixes https://github.com/domokit/mojo/issues/79
R=zra@google.com
Review URL: https://codereview.chromium.org/1060193002
diff --git a/DEPS b/DEPS
index 8d8e9b2..602e9c0 100644
--- a/DEPS
+++ b/DEPS
@@ -25,7 +25,7 @@
'v8_revision': '230d131d173ab2d60291d303177bc04ec3f6e519',
'angle_revision': 'bdd419f9f5b006e913606e7363125942c8ae06bc',
'buildtools_revision': '3b302fef93f7cc58d9b8168466905237484b2772',
- 'dart_revision': '44854',
+ 'dart_revision': '44944',
'pdfium_revision': 'b0115665b0f33971f1b7077740d51e155583cec0',
'boringssl_revision': '642f1498d056dbba3e50ed5a232ab2f482626dec',
'lss_revision': 'e079768b7e3a94dcbe7d338496c0c3bde7151b6e',
diff --git a/mojo/dart/test/validation_test.dart b/mojo/dart/test/validation_test.dart
index e747a4a..d4ab222 100644
--- a/mojo/dart/test/validation_test.dart
+++ b/mojo/dart/test/validation_test.dart
@@ -37,7 +37,7 @@
method10(Map<String, int> param0) => _complete();
method11(StructG param0) => _complete();
- Future close({bool nodefer: false}) => _stub.close(nodefer: nodefer);
+ Future close({bool immediate: false}) => _stub.close(immediate: immediate);
}
parser.ValidationParseResult readAndParseTest(String test) {
@@ -65,7 +65,7 @@
assert(e is MojoCodecError);
// TODO(zra): Make the error messages conform?
// assert(e == expected);
- conformanceImpl.close(nodefer: true);
+ conformanceImpl.close(immediate: true);
pipe.endpoints[0].handle.close();
handles.forEach((h) => h.close());
});
diff --git a/mojo/public/dart/src/application.dart b/mojo/public/dart/src/application.dart
index 03d0843..f6ee473 100644
--- a/mojo/public/dart/src/application.dart
+++ b/mojo/public/dart/src/application.dart
@@ -41,9 +41,11 @@
@override
void requestQuit() => _application._requestQuitAndClose();
- Future close({bool nodefer: false}) {
- if (shell != null) shell.close();
- return _stub.close();
+ Future close({bool immediate: false}) {
+ if (shell != null) {
+ shell.close(immediate: immediate);
+ }
+ return _stub.close(immediate: immediate);
}
}
@@ -104,11 +106,11 @@
});
}
- Future close() {
+ Future close({bool immediate: false}) {
assert(_applicationImpl != null);
- _applicationConnections.forEach((c) => c.close());
+ _applicationConnections.forEach((c) => c.close(immediate: immediate));
_applicationConnections.clear();
- return _applicationImpl.close();
+ return _applicationImpl.close(immediate: immediate);
}
// This method closes all the application connections. Used during apptesting.
diff --git a/mojo/public/dart/src/application_connection.dart b/mojo/public/dart/src/application_connection.dart
index 8c354ea..2e80fc1 100644
--- a/mojo/public/dart/src/application_connection.dart
+++ b/mojo/public/dart/src/application_connection.dart
@@ -21,7 +21,7 @@
_stub.onError = f;
}
- Future close({bool nodefer: false}) => _stub.close(nodefer: nodefer);
+ Future close({bool immediate: false}) => _stub.close(immediate: immediate);
void connectToService(
String interfaceName, core.MojoMessagePipeEndpoint pipe) {
@@ -101,7 +101,7 @@
});
}
- Future close({bool nodefer: false}) {
+ Future close({bool immediate: false}) {
var rspCloseFuture;
var lspCloseFuture;
if (remoteServiceProvider != null) {
@@ -111,7 +111,7 @@
rspCloseFuture = new Future.value(null);
}
if (_localServiceProvider != null) {
- lspCloseFuture = _localServiceProvider.close(nodefer: nodefer);
+ lspCloseFuture = _localServiceProvider.close(immediate: immediate);
_localServiceProvider = null;
} else {
lspCloseFuture = new Future.value(null);
diff --git a/mojo/public/dart/src/event_stream.dart b/mojo/public/dart/src/event_stream.dart
index 712d025..febfc9d 100644
--- a/mojo/public/dart/src/event_stream.dart
+++ b/mojo/public/dart/src/event_stream.dart
@@ -37,10 +37,10 @@
}
}
- Future close() {
+ Future close({bool immediate: false}) {
if (_handle != null) {
if (_isListening) {
- return _handleWatcherClose();
+ return _handleWatcherClose(immediate: immediate);
} else {
_localClose();
return new Future.value(null);
@@ -92,10 +92,10 @@
void enableWriteEvents() => enableSignals(MojoHandleSignals.WRITABLE);
void enableAllEvents() => enableSignals(MojoHandleSignals.READWRITE);
- Future _handleWatcherClose() {
+ Future _handleWatcherClose({bool immediate: false}) {
assert(_handle != null);
assert(MojoHandle._removeUnclosedHandle(_handle));
- return MojoHandleWatcher.close(_handle.h, wait: true).then((r) {
+ return MojoHandleWatcher.close(_handle.h, wait: !immediate).then((r) {
if (_receivePort != null) {
_receivePort.close();
_receivePort = null;
@@ -116,7 +116,8 @@
void _onSubscriptionStateChange() {
if (!_controller.hasListener) {
- close();
+ // No one is listening, close it immediately.
+ close(immediate: true);
}
}
@@ -210,9 +211,9 @@
}
_isInHandler = false;
if (signalsReceived.isPeerClosed) {
- // nodefer is true here because there is no need to wait to close until
- // outstanding messages are sent. The other side is gone.
- close(nodefer: true).then((_) {
+ // immediate is true here because there is no need to wait to close
+ // until outstanding messages are sent. The other side is gone.
+ close(immediate: true).then((_) {
if (onError != null) {
onError();
}
@@ -222,13 +223,13 @@
return subscription;
}
- Future close({bool nodefer: false}) {
+ Future close({bool immediate: false}) {
var result;
_isOpen = false;
_endpoint = null;
subscription = null;
if (_eventStream != null) {
- result = _eventStream.close().then((_) {
+ result = _eventStream.close(immediate: immediate).then((_) {
_eventStream = null;
});
}
diff --git a/mojo/public/dart/src/proxy.dart b/mojo/public/dart/src/proxy.dart
index a84ca3e..863e734 100644
--- a/mojo/public/dart/src/proxy.dart
+++ b/mojo/public/dart/src/proxy.dart
@@ -47,12 +47,12 @@
}
@override
- Future close({bool nodefer: false}) {
+ Future close({bool immediate: false}) {
for (var completer in _completerMap.values) {
completer.completeError(new ProxyCloseException('Proxy closed'));
}
_completerMap.clear();
- return super.close(nodefer: nodefer);
+ return super.close(immediate: immediate);
}
void sendMessage(Struct message, int name) {
diff --git a/mojo/public/dart/src/stub.dart b/mojo/public/dart/src/stub.dart
index 9008f55..c932584 100644
--- a/mojo/public/dart/src/stub.dart
+++ b/mojo/public/dart/src/stub.dart
@@ -52,9 +52,11 @@
// This was the final response future for which we needed to send
// a response. It is safe to close.
super.close().then((_) {
- _isClosing = false;
- _closeCompleter.complete(null);
- _closeCompleter = null;
+ if (_isClosing) {
+ _isClosing = false;
+ _closeCompleter.complete(null);
+ _closeCompleter = null;
+ }
});
}
}
@@ -63,9 +65,11 @@
// We are closing, there is no response to send for this message, and
// there are no outstanding response futures. Do the close now.
super.close().then((_) {
- _isClosing = false;
- _closeCompleter.complete(null);
- _closeCompleter = null;
+ if (_isClosing) {
+ _isClosing = false;
+ _closeCompleter.complete(null);
+ _closeCompleter = null;
+ }
});
}
}
@@ -74,13 +78,13 @@
throw 'Unexpected write signal in client.';
}
- // NB: |nodefer| should only be true when calling close() while handling an
+ // NB: |immediate| should only be true when calling close() while handling an
// exception thrown from handleRead(), e.g. when we receive a malformed
// message, or when we have received the PEER_CLOSED event.
@override
- Future close({bool nodefer: false}) {
+ Future close({bool immediate: false}) {
if (isOpen &&
- !nodefer &&
+ !immediate &&
(isInHandler || (_outstandingResponseFutures > 0))) {
// Either close() is being called from within handleRead() or
// handleWrite(), or close() is being called while there are outstanding
@@ -90,7 +94,7 @@
_closeCompleter = new Completer();
return _closeCompleter.future;
} else {
- return super.close(nodefer: nodefer).then((_) {
+ return super.close(immediate: immediate).then((_) {
if (_isClosing) {
_isClosing = false;
_closeCompleter.complete(null);
diff --git a/mojo/public/tools/bindings/generators/dart_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/dart_templates/interface_definition.tmpl
index 30463b2..99e2ab3 100644
--- a/mojo/public/tools/bindings/generators/dart_templates/interface_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/dart_templates/interface_definition.tmpl
@@ -158,7 +158,7 @@
core.MojoMessagePipeEndpoint endpoint) =>
new {{interface|name}}Proxy.fromEndpoint(endpoint);
- Future close({bool nodefer: false}) => impl.close(nodefer: nodefer);
+ Future close({bool immediate: false}) => impl.close(immediate: immediate);
String toString() {
return "{{interface|name}}Proxy($impl)";
diff --git a/sky/engine/bindings/mojo_natives.cc b/sky/engine/bindings/mojo_natives.cc
index 25faf76..c67f71a 100644
--- a/sky/engine/bindings/mojo_natives.cc
+++ b/sky/engine/bindings/mojo_natives.cc
@@ -716,7 +716,7 @@
CHECK_INTEGER_ARGUMENT(arguments, 1, &client_handle, InvalidArgument);
Dart_Handle send_port_handle = Dart_GetNativeArgument(arguments, 2);
- Dart_Port send_port_id = 0;
+ Dart_Port send_port_id = ILLEGAL_PORT;
if (!Dart_IsNull(send_port_handle)) {
Dart_Handle result = Dart_SendPortGetId(send_port_handle, &send_port_id);
if (Dart_IsError(result)) {
@@ -755,7 +755,9 @@
Dart_Handle list = Dart_NewList(3);
Dart_ListSetAt(list, 0, Dart_NewInteger(cd.handle));
- Dart_ListSetAt(list, 1, Dart_NewSendPort(cd.port));
+ if (cd.port != ILLEGAL_PORT) {
+ Dart_ListSetAt(list, 1, Dart_NewSendPort(cd.port));
+ }
Dart_ListSetAt(list, 2, Dart_NewInteger(cd.data));
Dart_SetReturnValue(arguments, list);
}