Version 2.14.0-188.5.beta
* Cherry-pick 5f8a9d33d2f81c8ff7714c03c473b1291823403b to beta
* Cherry-pick fb32ffd97f365bc4c286b506d9be272a794345f5 to beta
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 00d1c06..cadd093 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -154,12 +154,15 @@
}
bool _keepAnnotation(Expression annotation) {
- final constant = (annotation as ConstantExpression).constant;
- if (constant is InstanceConstant) {
- final cls = constant.classNode;
- return (cls == externalNameClass) ||
- (cls == pragmaClass) ||
- (protobufHandler != null && protobufHandler.usesAnnotationClass(cls));
+ if (annotation is ConstantExpression) {
+ final constant = annotation.constant;
+ if (constant is InstanceConstant) {
+ final cls = constant.classNode;
+ return (cls == externalNameClass) ||
+ (cls == pragmaClass) ||
+ (protobufHandler != null &&
+ protobufHandler.usesAnnotationClass(cls));
+ }
}
return false;
}
diff --git a/runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc b/runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc
index 87e9d66..8564aa6 100644
--- a/runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc
@@ -314,6 +314,15 @@
#endif // defined(TARGET_OS_LINUX)
+// Restore default SIGPIPE handler, which is only needed on mac
+// since that is the only platform we explicitly ignore it.
+// See Platform::Initialize() in platform_macos.cc.
+DART_EXPORT void RestoreSIGPIPEHandler() {
+#if defined(HOST_OS_MACOS)
+ signal(SIGPIPE, SIG_DFL);
+#endif
+}
+
DART_EXPORT void IGH_MsanUnpoison(void* start, intptr_t length) {
MSAN_UNPOISON(start, length);
}
@@ -418,7 +427,7 @@
#define FATAL(error) Fatal(__FILE__, __LINE__, error)
-void SleepOnAnyOS(intptr_t seconds) {
+DART_EXPORT void SleepOnAnyOS(intptr_t seconds) {
#if defined(HOST_OS_WINDOWS)
Sleep(1000 * seconds);
#else
diff --git a/runtime/bin/socket_macos.cc b/runtime/bin/socket_macos.cc
index 8c6be8b..f9e00c2 100644
--- a/runtime/bin/socket_macos.cc
+++ b/runtime/bin/socket_macos.cc
@@ -44,6 +44,11 @@
FDUtils::SaveErrorAndClose(fd);
return -1;
}
+ // Don't raise SIGPIPE when attempting to write to a connection which has
+ // already closed.
+ int optval = 1;
+ VOID_NO_RETRY_EXPECTED(
+ setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)));
return fd;
}
diff --git a/tests/standalone/io/socket_sigpipe_test.dart b/tests/standalone/io/socket_sigpipe_test.dart
new file mode 100644
index 0000000..ec6f5c8
--- /dev/null
+++ b/tests/standalone/io/socket_sigpipe_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Tests that SIGPIPE won't terminate websocket client dart app.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:ffi';
+import 'dart:io';
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+import 'package:ffi/ffi.dart';
+import 'package:path/path.dart' as p;
+
+import '../../../tests/ffi/dylib_utils.dart';
+
+class Isolate extends Opaque {}
+
+abstract class FfiBindings {
+ static final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+ static final RestoreSIGPIPEHandler =
+ ffiTestFunctions.lookupFunction<Void Function(), void Function()>(
+ "RestoreSIGPIPEHandler");
+ static final SleepOnAnyOS = ffiTestFunctions.lookupFunction<
+ Void Function(IntPtr), void Function(int)>("SleepOnAnyOS");
+}
+
+Future<void> main() async {
+ asyncStart();
+
+ final server = await Process.start(Platform.executable, <String>[
+ p.join(p.dirname(Platform.script.toFilePath()),
+ "socket_sigpipe_test_server.dart")
+ ]);
+ final serverPort = Completer<int>();
+ server.stdout
+ .transform(utf8.decoder)
+ .transform(LineSplitter())
+ .listen((line) {
+ print('server stdout: $line');
+ if (!serverPort.isCompleted) {
+ serverPort.complete(int.parse(line));
+ }
+ });
+ server.stderr
+ .transform(utf8.decoder)
+ .transform(LineSplitter())
+ .listen((data) {
+ print('server stderr: $data');
+ });
+
+ FfiBindings.RestoreSIGPIPEHandler();
+ final ws =
+ await WebSocket.connect('ws://localhost:${await serverPort.future}');
+ ws.listen((var data) {
+ print('Got $data');
+ // Sleep to prevent closed socket events coming through and being handled.
+ // This way websocket stays open and writing into it should trigger SIGPIPE.
+ // Unless of course we requested SIGPIPE not to be generated on broken socket
+ // pipe. This is what this test is testing - that the SIGPIPE is not generated
+ // on broken socket pipe.
+ ws.add('foo');
+ FfiBindings.SleepOnAnyOS(10 /*seconds*/); // give server time to exit
+ ws.add('baz');
+ ws.close();
+ }, onDone: () {
+ asyncEnd();
+ }, onError: (e, st) {
+ Expect.fail('Client websocket failed $e $st');
+ });
+}
diff --git a/tests/standalone/io/socket_sigpipe_test_server.dart b/tests/standalone/io/socket_sigpipe_test_server.dart
new file mode 100644
index 0000000..89265af
--- /dev/null
+++ b/tests/standalone/io/socket_sigpipe_test_server.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Helper server program for socket_sigpipe_test.dart
+
+import "package:expect/expect.dart";
+import "dart:async";
+import "dart:io";
+
+main() {
+ HttpServer.bind("127.0.0.1", 0).then((server) {
+ print(server.port);
+ server.listen((request) {
+ WebSocketTransformer.upgrade(request).then((websocket) async {
+ websocket.add('bar');
+ await websocket.close();
+ await server.close();
+ print('closed');
+ });
+ });
+ });
+}
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 3c981bc..d299104 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -47,6 +47,7 @@
[ $runtime == dart_precompiled ]
http_launch_test: Skip
io/addlatexhash_test: Skip
+io/socket_sigpipe_test: SkipByDesign # Spawns server process using Platform.executable
io/wait_for_event_isolate_test: SkipByDesign # Uses mirrors.
io/wait_for_event_microtask_test: SkipByDesign # Uses mirrors.
io/wait_for_event_nested_microtask_test: SkipByDesign # Uses mirrors.
diff --git a/tests/standalone_2/io/socket_sigpipe_test.dart b/tests/standalone_2/io/socket_sigpipe_test.dart
new file mode 100644
index 0000000..ec6f5c8
--- /dev/null
+++ b/tests/standalone_2/io/socket_sigpipe_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Tests that SIGPIPE won't terminate websocket client dart app.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:ffi';
+import 'dart:io';
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+import 'package:ffi/ffi.dart';
+import 'package:path/path.dart' as p;
+
+import '../../../tests/ffi/dylib_utils.dart';
+
+class Isolate extends Opaque {}
+
+abstract class FfiBindings {
+ static final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+ static final RestoreSIGPIPEHandler =
+ ffiTestFunctions.lookupFunction<Void Function(), void Function()>(
+ "RestoreSIGPIPEHandler");
+ static final SleepOnAnyOS = ffiTestFunctions.lookupFunction<
+ Void Function(IntPtr), void Function(int)>("SleepOnAnyOS");
+}
+
+Future<void> main() async {
+ asyncStart();
+
+ final server = await Process.start(Platform.executable, <String>[
+ p.join(p.dirname(Platform.script.toFilePath()),
+ "socket_sigpipe_test_server.dart")
+ ]);
+ final serverPort = Completer<int>();
+ server.stdout
+ .transform(utf8.decoder)
+ .transform(LineSplitter())
+ .listen((line) {
+ print('server stdout: $line');
+ if (!serverPort.isCompleted) {
+ serverPort.complete(int.parse(line));
+ }
+ });
+ server.stderr
+ .transform(utf8.decoder)
+ .transform(LineSplitter())
+ .listen((data) {
+ print('server stderr: $data');
+ });
+
+ FfiBindings.RestoreSIGPIPEHandler();
+ final ws =
+ await WebSocket.connect('ws://localhost:${await serverPort.future}');
+ ws.listen((var data) {
+ print('Got $data');
+ // Sleep to prevent closed socket events coming through and being handled.
+ // This way websocket stays open and writing into it should trigger SIGPIPE.
+ // Unless of course we requested SIGPIPE not to be generated on broken socket
+ // pipe. This is what this test is testing - that the SIGPIPE is not generated
+ // on broken socket pipe.
+ ws.add('foo');
+ FfiBindings.SleepOnAnyOS(10 /*seconds*/); // give server time to exit
+ ws.add('baz');
+ ws.close();
+ }, onDone: () {
+ asyncEnd();
+ }, onError: (e, st) {
+ Expect.fail('Client websocket failed $e $st');
+ });
+}
diff --git a/tests/standalone_2/io/socket_sigpipe_test_server.dart b/tests/standalone_2/io/socket_sigpipe_test_server.dart
new file mode 100644
index 0000000..89265af
--- /dev/null
+++ b/tests/standalone_2/io/socket_sigpipe_test_server.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Helper server program for socket_sigpipe_test.dart
+
+import "package:expect/expect.dart";
+import "dart:async";
+import "dart:io";
+
+main() {
+ HttpServer.bind("127.0.0.1", 0).then((server) {
+ print(server.port);
+ server.listen((request) {
+ WebSocketTransformer.upgrade(request).then((websocket) async {
+ websocket.add('bar');
+ await websocket.close();
+ await server.close();
+ print('closed');
+ });
+ });
+ });
+}
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status
index df81919..702d8e9 100644
--- a/tests/standalone_2/standalone_2.status
+++ b/tests/standalone_2/standalone_2.status
@@ -47,6 +47,7 @@
[ $runtime == dart_precompiled ]
http_launch_test: Skip
io/addlatexhash_test: Skip
+io/socket_sigpipe_test: SkipByDesign # Spawns server process using Platform.executable
io/wait_for_event_isolate_test: SkipByDesign # Uses mirrors.
io/wait_for_event_microtask_test: SkipByDesign # Uses mirrors.
io/wait_for_event_nested_microtask_test: SkipByDesign # Uses mirrors.
diff --git a/tools/VERSION b/tools/VERSION
index d2adf79..f9064bf 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
MINOR 14
PATCH 0
PRERELEASE 188
-PRERELEASE_PATCH 3
\ No newline at end of file
+PRERELEASE_PATCH 5
\ No newline at end of file