Version 2.14.0-94.0.dev
Merge commit '7eb280566593eb577f0a75066f25f02271cfe417' into 'dev'
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/function_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/function_test.dart
new file mode 100644
index 0000000..77f3d6b
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/function_test.dart
@@ -0,0 +1,95 @@
+// 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.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../context_collection_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FunctionTest);
+ });
+}
+
+@reflectiveTest
+class FunctionTest extends PubPackageResolutionTest {
+ test_genericFunction_upwards() async {
+ await assertNoErrorsInCode('''
+void foo<T>(T x, T y) {}
+
+f() {
+ foo(1, 2);
+}
+''');
+ assertTypeArgumentTypes(
+ findNode.methodInvocation('foo('),
+ ['int'],
+ );
+ }
+
+ test_genericFunction_upwards_missingRequiredArgument() async {
+ await assertErrorsInCode('''
+void foo<T>({required T x, required T y}) {}
+
+f() {
+ foo(x: 1);
+}
+''', [
+ error(CompileTimeErrorCode.MISSING_REQUIRED_ARGUMENT, 54, 3),
+ ]);
+ assertTypeArgumentTypes(
+ findNode.methodInvocation('foo('),
+ ['int'],
+ );
+ }
+
+ test_genericFunction_upwards_notEnoughPositionalArguments() async {
+ await assertErrorsInCode('''
+void foo<T>(T x, T y) {}
+
+f() {
+ foo(1);
+}
+''', [
+ error(CompileTimeErrorCode.NOT_ENOUGH_POSITIONAL_ARGUMENTS, 37, 3),
+ ]);
+ assertTypeArgumentTypes(
+ findNode.methodInvocation('foo('),
+ ['int'],
+ );
+ }
+
+ test_genericFunction_upwards_tooManyPositionalArguments() async {
+ await assertErrorsInCode('''
+void foo<T>(T x, T y) {}
+
+f() {
+ foo(1, 2, 3);
+}
+''', [
+ error(CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS, 44, 1),
+ ]);
+ assertTypeArgumentTypes(
+ findNode.methodInvocation('foo('),
+ ['int'],
+ );
+ }
+
+ test_genericFunction_upwards_undefinedNamedParameter() async {
+ await assertErrorsInCode('''
+void foo<T>(T x, T y) {}
+
+f() {
+ foo(1, 2, z: 3);
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER, 44, 1),
+ ]);
+ assertTypeArgumentTypes(
+ findNode.methodInvocation('foo('),
+ ['int'],
+ );
+ }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/test_all.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/test_all.dart
index a998d76..17dfe68 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/test_all.dart
@@ -9,6 +9,7 @@
import 'equality_expressions_test.dart' as equality_expressions;
import 'extension_methods_test.dart' as extension_methods;
import 'function_expression_test.dart' as function_expression;
+import 'function_test.dart' as function;
import 'list_literal_test.dart' as list_literal;
import 'local_variable_test.dart' as local_variable;
import 'logical_boolean_expressions_test.dart' as logical_boolean_expressions;
@@ -25,6 +26,7 @@
conditional_expression.main();
equality_expressions.main();
extension_methods.main();
+ function.main();
function_expression.main();
list_literal.main();
local_variable.main();
diff --git a/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart b/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart
index d1f7457..841251e 100644
--- a/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart
@@ -72,6 +72,16 @@
]);
}
+ test_function_async_block_Future_String__to_Future_int() async {
+ await assertErrorsInCode('''
+Future<int> f(Future<String> a) async {
+ return a;
+}
+''', [
+ error(CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_FUNCTION, 49, 1),
+ ]);
+ }
+
test_function_async_block_Future_void() async {
await assertNoErrorsInCode('''
void f1(Future<void> a) async { return a; }
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 2c79318..81ffb05 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -472,62 +472,6 @@
]);
}
- test_functionModifiers_async() async {
- await assertErrorsInCode('''
-import 'dart:math' show Random;
-
-dynamic x;
-
-foo1() async => x;
-Future foo2() async => x;
-Future<int> foo3() async => x;
-Future<int> foo4() async => new Future<int>.value(x);
-Future<int> foo5() async => new Future<String>.value(x);
-
-bar1() async { return x; }
-Future bar2() async { return x; }
-Future<int> bar3() async { return x; }
-Future<int> bar4() async {
- return new Future<int>.value(x);
-}
-Future<int> bar5() async {
- return new Future<String>.value(x);
-}
-
-int y;
-Future<int> z;
-
-baz() async {
- int a = await x;
- int b = await y;
- int c = await z;
- String d = await z;
-}
-
-Future<bool> get issue_ddc_264 async {
- await 42;
- if (new Random().nextBool()) {
- return true;
- } else {
- return new Future<bool>.value(false);
- }
-}
-
-
-Future<String> issue_sdk_26404() async {
- return ((1 > 0) ? new Future<String>.value('hello') : "world");
-}
-''', [
- error(CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_FUNCTION, 203, 27),
- error(CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_FUNCTION, 433, 27),
- error(HintCode.UNUSED_LOCAL_VARIABLE, 508, 1),
- error(HintCode.UNUSED_LOCAL_VARIABLE, 527, 1),
- error(HintCode.UNUSED_LOCAL_VARIABLE, 546, 1),
- error(HintCode.UNUSED_LOCAL_VARIABLE, 568, 1),
- error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 572, 7),
- ]);
- }
-
test_functionTypingAndSubtyping_classes() async {
await assertErrorsInCode('''
class A {}
@@ -1679,27 +1623,6 @@
]);
}
- test_functionTypingAndSubtyping_uninferredClosure() async {
- await assertErrorsInCode('''
-typedef num Num2Num(num x);
-void main() {
- Num2Num g = (int x) { return x; };
- print(g(42));
-}
-''', [
- error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 56, 21),
- ]);
- }
-
- test_functionTypingAndSubtyping_void() async {
- await assertNoErrorsInCode('''
-class A {
- void bar() => null;
- void foo() => bar(); // allowed
-}
-''');
- }
-
test_genericClassMethodOverride() async {
await assertErrorsInCode('''
class A {}
@@ -1721,50 +1644,6 @@
]);
}
- test_genericFunctionWrongNumberOfArguments() async {
- await assertErrorsInCode(r'''
-T foo<T>(T x, T y) => x;
-T bar<T>({T x, T y}) => x;
-
-main() {
- String x;
- // resolving these shouldn't crash.
- foo(1, 2, 3);
- x = foo('1', '2', '3');
- foo(1);
- x = foo('1');
- x = foo(1, 2, 3);
- x = foo(1);
-
- // named arguments
- bar(y: 1, x: 2, z: 3);
- x = bar(z: '1', x: '2', y: '3');
- bar(y: 1);
- x = bar(x: '1', z: 42);
- x = bar(y: 1, x: 2, z: 3);
- x = bar(x: 1);
-}
-''', [
- error(HintCode.UNUSED_LOCAL_VARIABLE, 71, 1),
- error(CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS, 124, 1),
- error(CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS, 148, 3),
- error(CompileTimeErrorCode.NOT_ENOUGH_POSITIONAL_ARGUMENTS, 159, 3),
- error(CompileTimeErrorCode.NOT_ENOUGH_POSITIONAL_ARGUMENTS, 173, 5),
- error(CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS, 196, 1),
- error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 190, 1),
- error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 193, 1),
- error(CompileTimeErrorCode.NOT_ENOUGH_POSITIONAL_ARGUMENTS, 209, 3),
- error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 210, 1),
- error(CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER, 254, 1),
- error(CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER, 271, 1),
- error(CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER, 327, 1),
- error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 348, 1),
- error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 354, 1),
- error(CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER, 357, 1),
- error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 377, 1),
- ]);
- }
-
test_genericMethodOverride() async {
await assertNoErrorsInCode('''
class Future<T> {
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart
index 558f4da..a4c6fd4 100644
--- a/pkg/vm/lib/transformations/ffi.dart
+++ b/pkg/vm/lib/transformations/ffi.dart
@@ -784,6 +784,25 @@
InterfaceType(compoundClass, Nullability.legacy),
SubtypeCheckMode.ignoringNullabilities);
}
+
+ Expression getCompoundTypedDataBaseField(
+ Expression receiver, int fileOffset) {
+ return PropertyGet(
+ receiver, compoundTypedDataBaseField.name, compoundTypedDataBaseField)
+ ..fileOffset = fileOffset;
+ }
+
+ Expression getArrayTypedDataBaseField(Expression receiver,
+ [int fileOffset = TreeNode.noOffset]) {
+ return PropertyGet(
+ receiver, arrayTypedDataBaseField.name, arrayTypedDataBaseField)
+ ..fileOffset = fileOffset;
+ }
+
+ Expression multiply(Expression a, Expression b) {
+ return MethodInvocation(
+ a, numMultiplication.name, Arguments([b]), numMultiplication);
+ }
}
/// Checks if any library depends on dart:ffi.
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index e69b8a1..f841be3 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -1033,11 +1033,8 @@
? transformer.loadUnalignedMethods
: transformer.loadMethods)[nativeType],
Arguments([
- PropertyGet(
- ThisExpression(),
- transformer.compoundTypedDataBaseField.name,
- transformer.compoundTypedDataBaseField)
- ..fileOffset = fileOffset,
+ transformer.getCompoundTypedDataBaseField(
+ ThisExpression(), fileOffset),
transformer.runtimeBranchOnLayout(offsets)
]))
..fileOffset = fileOffset);
@@ -1060,11 +1057,8 @@
? transformer.storeUnalignedMethods
: transformer.storeMethods)[nativeType],
Arguments([
- PropertyGet(
- ThisExpression(),
- transformer.compoundTypedDataBaseField.name,
- transformer.compoundTypedDataBaseField)
- ..fileOffset = fileOffset,
+ transformer.getCompoundTypedDataBaseField(
+ ThisExpression(), fileOffset),
transformer.runtimeBranchOnLayout(offsets),
VariableGet(argument)
]))
@@ -1103,11 +1097,8 @@
StaticInvocation(
transformer.loadMethods[NativeType.kIntptr],
Arguments([
- PropertyGet(
- ThisExpression(),
- transformer.compoundTypedDataBaseField.name,
- transformer.compoundTypedDataBaseField)
- ..fileOffset = fileOffset,
+ transformer.getCompoundTypedDataBaseField(
+ ThisExpression(), fileOffset),
transformer.runtimeBranchOnLayout(offsets)
]))
..fileOffset = fileOffset
@@ -1132,11 +1123,8 @@
ReturnStatement(StaticInvocation(
transformer.storeMethods[NativeType.kIntptr],
Arguments([
- PropertyGet(
- ThisExpression(),
- transformer.compoundTypedDataBaseField.name,
- transformer.compoundTypedDataBaseField)
- ..fileOffset = fileOffset,
+ transformer.getCompoundTypedDataBaseField(
+ ThisExpression(), fileOffset),
transformer.runtimeBranchOnLayout(offsets),
PropertyGet(VariableGet(argument), transformer.addressGetter.name,
transformer.addressGetter)
@@ -1183,11 +1171,8 @@
constructor,
Arguments([
transformer.typedDataBaseOffset(
- PropertyGet(
- ThisExpression(),
- transformer.compoundTypedDataBaseField.name,
- transformer.compoundTypedDataBaseField)
- ..fileOffset = fileOffset,
+ transformer.getCompoundTypedDataBaseField(
+ ThisExpression(), fileOffset),
transformer.runtimeBranchOnLayout(offsets),
transformer.runtimeBranchOnLayout(size),
dartType,
@@ -1212,17 +1197,11 @@
ReturnStatement(StaticInvocation(
transformer.memCopy,
Arguments([
- PropertyGet(
- ThisExpression(),
- transformer.compoundTypedDataBaseField.name,
- transformer.compoundTypedDataBaseField)
- ..fileOffset = fileOffset,
+ transformer.getCompoundTypedDataBaseField(
+ ThisExpression(), fileOffset),
transformer.runtimeBranchOnLayout(offsets),
- PropertyGet(
- VariableGet(argument),
- transformer.compoundTypedDataBaseField.name,
- transformer.compoundTypedDataBaseField)
- ..fileOffset = fileOffset,
+ transformer.getCompoundTypedDataBaseField(
+ VariableGet(argument), fileOffset),
ConstantExpression(IntConstant(0)),
transformer.runtimeBranchOnLayout(size),
]))
@@ -1367,11 +1346,8 @@
transformer.arrayConstructor,
Arguments([
transformer.typedDataBaseOffset(
- PropertyGet(
- ThisExpression(),
- transformer.compoundTypedDataBaseField.name,
- transformer.compoundTypedDataBaseField)
- ..fileOffset = fileOffset,
+ transformer.getCompoundTypedDataBaseField(
+ ThisExpression(), fileOffset),
transformer.runtimeBranchOnLayout(offsets),
transformer.runtimeBranchOnLayout(size),
typeArgument,
@@ -1400,17 +1376,11 @@
ReturnStatement(StaticInvocation(
transformer.memCopy,
Arguments([
- PropertyGet(
- ThisExpression(),
- transformer.compoundTypedDataBaseField.name,
- transformer.compoundTypedDataBaseField)
- ..fileOffset = fileOffset,
+ transformer.getCompoundTypedDataBaseField(
+ ThisExpression(), fileOffset),
transformer.runtimeBranchOnLayout(offsets),
- PropertyGet(
- VariableGet(argument),
- transformer.arrayTypedDataBaseField.name,
- transformer.arrayTypedDataBaseField)
- ..fileOffset = fileOffset,
+ transformer.getArrayTypedDataBaseField(
+ VariableGet(argument), fileOffset),
ConstantExpression(IntConstant(0)),
transformer.runtimeBranchOnLayout(size),
]))
diff --git a/pkg/vm/lib/transformations/ffi_use_sites.dart b/pkg/vm/lib/transformations/ffi_use_sites.dart
index 8f9b4a3..24e4b89 100644
--- a/pkg/vm/lib/transformations/ffi_use_sites.dart
+++ b/pkg/vm/lib/transformations/ffi_use_sites.dart
@@ -327,11 +327,7 @@
Expression sizeInBytes = _inlineSizeOf(nativeType);
if (sizeInBytes != null) {
if (node.arguments.positional.length == 2) {
- sizeInBytes = MethodInvocation(
- node.arguments.positional[1],
- numMultiplication.name,
- Arguments([sizeInBytes]),
- numMultiplication);
+ sizeInBytes = multiply(node.arguments.positional[1], sizeInBytes);
}
return MethodInvocation(
node.arguments.positional[0],
@@ -485,11 +481,7 @@
pointer,
offsetByMethod.name,
Arguments([
- MethodInvocation(
- node.arguments.positional[1],
- numMultiplication.name,
- Arguments([_inlineSizeOf(dartType)]),
- numMultiplication)
+ multiply(node.arguments.positional[1], _inlineSizeOf(dartType))
]),
offsetByMethod);
}
@@ -503,10 +495,8 @@
.firstWhere((c) => c.name == Name("#fromTypedDataBase"));
final typedDataBasePrime = typedDataBaseOffset(
- PropertyGet(NullCheck(node.arguments.positional[0]),
- arrayTypedDataBaseField.name, arrayTypedDataBaseField),
- MethodInvocation(node.arguments.positional[1], numMultiplication.name,
- Arguments([_inlineSizeOf(dartType)]), numMultiplication),
+ getArrayTypedDataBaseField(NullCheck(node.arguments.positional[0])),
+ multiply(node.arguments.positional[1], _inlineSizeOf(dartType)),
_inlineSizeOf(dartType),
dartType,
node.fileOffset);
@@ -574,26 +564,17 @@
type: coreTypes.intNonNullableRawType)
..fileOffset = node.fileOffset;
final elementSizeVar = VariableDeclaration("#elementSize",
- initializer: MethodInvocation(
+ initializer: multiply(
VariableGet(singleElementSizeVar),
- numMultiplication.name,
- Arguments([
- PropertyGet(
- VariableGet(arrayVar),
- arrayNestedDimensionsFlattened.name,
- arrayNestedDimensionsFlattened)
- ]),
- numMultiplication),
+ PropertyGet(
+ VariableGet(arrayVar),
+ arrayNestedDimensionsFlattened.name,
+ arrayNestedDimensionsFlattened)),
type: coreTypes.intNonNullableRawType)
..fileOffset = node.fileOffset;
final offsetVar = VariableDeclaration("#offset",
- initializer: MethodInvocation(
- VariableGet(elementSizeVar),
- numMultiplication.name,
- Arguments([
- VariableGet(indexVar),
- ]),
- numMultiplication),
+ initializer:
+ multiply(VariableGet(elementSizeVar), VariableGet(indexVar)),
type: coreTypes.intNonNullableRawType)
..fileOffset = node.fileOffset;
@@ -618,8 +599,7 @@
arrayConstructor,
Arguments([
typedDataBaseOffset(
- PropertyGet(VariableGet(arrayVar),
- arrayTypedDataBaseField.name, arrayTypedDataBaseField),
+ getArrayTypedDataBaseField(VariableGet(arrayVar)),
VariableGet(offsetVar),
VariableGet(elementSizeVar),
dartType,
@@ -641,13 +621,11 @@
StaticInvocation(
memCopy,
Arguments([
- PropertyGet(VariableGet(arrayVar), arrayTypedDataBaseField.name,
- arrayTypedDataBaseField)
- ..fileOffset = node.fileOffset,
+ getArrayTypedDataBaseField(
+ VariableGet(arrayVar), node.fileOffset),
VariableGet(offsetVar),
- PropertyGet(node.arguments.positional[2],
- arrayTypedDataBaseField.name, arrayTypedDataBaseField)
- ..fileOffset = node.fileOffset,
+ getArrayTypedDataBaseField(
+ node.arguments.positional[2], node.fileOffset),
ConstantExpression(IntConstant(0)),
VariableGet(elementSizeVar),
]))
@@ -673,13 +651,8 @@
return MethodInvocation(
node.receiver,
offsetByMethod.name,
- Arguments([
- MethodInvocation(
- node.arguments.positional.single,
- numMultiplication.name,
- Arguments([inlineSizeOf]),
- numMultiplication)
- ]),
+ Arguments(
+ [multiply(node.arguments.positional.single, inlineSizeOf)]),
offsetByMethod);
}
}
@@ -711,13 +684,8 @@
return MethodInvocation(
node.receiver,
offsetByMethod.name,
- Arguments([
- MethodInvocation(
- node.arguments.positional.single,
- numMultiplication.name,
- Arguments([inlineSizeOf]),
- numMultiplication)
- ]),
+ Arguments(
+ [multiply(node.arguments.positional.single, inlineSizeOf)]),
offsetByMethod);
}
}
diff --git a/runtime/bin/process.h b/runtime/bin/process.h
index 34fc299..cf141b2 100644
--- a/runtime/bin/process.h
+++ b/runtime/bin/process.h
@@ -170,11 +170,17 @@
DISALLOW_IMPLICIT_CONSTRUCTORS(Process);
};
+typedef void (*sa_handler_t)(int);
+
class SignalInfo {
public:
- SignalInfo(intptr_t fd, intptr_t signal, SignalInfo* next)
+ SignalInfo(intptr_t fd,
+ intptr_t signal,
+ sa_handler_t oldact,
+ SignalInfo* next)
: fd_(fd),
signal_(signal),
+ oldact_(oldact),
// SignalInfo is expected to be created when in a isolate.
port_(Dart_GetMainPortId()),
next_(next),
@@ -197,12 +203,14 @@
intptr_t fd() const { return fd_; }
intptr_t signal() const { return signal_; }
+ sa_handler_t oldact() const { return oldact_; }
Dart_Port port() const { return port_; }
SignalInfo* next() const { return next_; }
private:
intptr_t fd_;
intptr_t signal_;
+ sa_handler_t oldact_;
// The port_ is used to identify what isolate the signal-info belongs to.
Dart_Port port_;
SignalInfo* next_;
diff --git a/runtime/bin/process_android.cc b/runtime/bin/process_android.cc
index b296299..700de02 100644
--- a/runtime/bin/process_android.cc
+++ b/runtime/bin/process_android.cc
@@ -1009,8 +1009,10 @@
MutexLocker lock(signal_mutex);
SignalInfo* handler = signal_handlers;
bool listen = true;
+ sa_handler_t oldact_handler = nullptr;
while (handler != NULL) {
if (handler->signal() == signal) {
+ oldact_handler = handler->oldact();
listen = false;
break;
}
@@ -1023,14 +1025,17 @@
for (int i = 0; i < kSignalsCount; i++) {
sigaddset(&act.sa_mask, kSignals[i]);
}
- int status = NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
+ struct sigaction oldact = {};
+ intptr_t status = NO_RETRY_EXPECTED(sigaction(signal, &act, &oldact));
if (status < 0) {
close(fds[0]);
close(fds[1]);
return -1;
}
+ oldact_handler = oldact.sa_handler;
}
- signal_handlers = new SignalInfo(fds[1], signal, signal_handlers);
+ signal_handlers =
+ new SignalInfo(fds[1], signal, oldact_handler, signal_handlers);
return fds[0];
}
@@ -1038,7 +1043,9 @@
ThreadSignalBlocker blocker(kSignalsCount, kSignals);
MutexLocker lock(signal_mutex);
SignalInfo* handler = signal_handlers;
- bool unlisten = true;
+ sa_handler_t oldact_handler = SIG_DFL;
+ bool any_removed = false;
+ bool any_remaining = false;
while (handler != NULL) {
bool remove = false;
if (handler->signal() == signal) {
@@ -1046,10 +1053,12 @@
if (signal_handlers == handler) {
signal_handlers = handler->next();
}
+ oldact_handler = handler->oldact();
handler->Unlink();
remove = true;
+ any_removed = true;
} else {
- unlisten = false;
+ any_remaining = true;
}
}
SignalInfo* next = handler->next();
@@ -1058,9 +1067,9 @@
}
handler = next;
}
- if (unlisten) {
+ if (any_removed && !any_remaining) {
struct sigaction act = {};
- act.sa_handler = SIG_DFL;
+ act.sa_handler = oldact_handler;
VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
}
}
@@ -1069,7 +1078,8 @@
ThreadSignalBlocker blocker(kSignalsCount, kSignals);
MutexLocker lock(signal_mutex);
SignalInfo* handler = signal_handlers;
- bool unlisten = true;
+ sa_handler_t oldact_handler = SIG_DFL;
+ bool any_remaining = false;
intptr_t signal = -1;
while (handler != NULL) {
bool remove = false;
@@ -1082,7 +1092,7 @@
remove = true;
signal = handler->signal();
} else {
- unlisten = false;
+ any_remaining = true;
}
}
SignalInfo* next = handler->next();
@@ -1091,9 +1101,9 @@
}
handler = next;
}
- if (unlisten && (signal != -1)) {
+ if ((signal != -1) && !any_remaining) {
struct sigaction act = {};
- act.sa_handler = SIG_DFL;
+ act.sa_handler = oldact_handler;
VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
}
}
diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc
index 7c81637..d1897fa 100644
--- a/runtime/bin/process_linux.cc
+++ b/runtime/bin/process_linux.cc
@@ -1003,8 +1003,10 @@
MutexLocker lock(signal_mutex);
SignalInfo* handler = signal_handlers;
bool listen = true;
+ sa_handler_t oldact_handler = nullptr;
while (handler != NULL) {
if (handler->signal() == signal) {
+ oldact_handler = handler->oldact();
listen = false;
break;
}
@@ -1017,7 +1019,8 @@
for (int i = 0; i < kSignalsCount; i++) {
sigaddset(&act.sa_mask, kSignals[i]);
}
- int status = NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
+ struct sigaction oldact = {};
+ int status = NO_RETRY_EXPECTED(sigaction(signal, &act, &oldact));
if (status < 0) {
int err = errno;
close(fds[0]);
@@ -1025,8 +1028,10 @@
errno = err;
return -1;
}
+ oldact_handler = oldact.sa_handler;
}
- signal_handlers = new SignalInfo(fds[1], signal, signal_handlers);
+ signal_handlers =
+ new SignalInfo(fds[1], signal, oldact_handler, signal_handlers);
return fds[0];
}
@@ -1034,7 +1039,9 @@
ThreadSignalBlocker blocker(kSignalsCount, kSignals);
MutexLocker lock(signal_mutex);
SignalInfo* handler = signal_handlers;
- bool unlisten = true;
+ sa_handler_t oldact_handler = SIG_DFL;
+ bool any_removed = false;
+ bool any_remaining = false;
while (handler != NULL) {
bool remove = false;
if (handler->signal() == signal) {
@@ -1044,8 +1051,10 @@
}
handler->Unlink();
remove = true;
+ oldact_handler = handler->oldact();
+ any_removed = true;
} else {
- unlisten = false;
+ any_remaining = true;
}
}
SignalInfo* next = handler->next();
@@ -1054,9 +1063,9 @@
}
handler = next;
}
- if (unlisten) {
+ if (any_removed && !any_remaining) {
struct sigaction act = {};
- act.sa_handler = SIG_DFL;
+ act.sa_handler = oldact_handler;
VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
}
}
@@ -1065,7 +1074,8 @@
ThreadSignalBlocker blocker(kSignalsCount, kSignals);
MutexLocker lock(signal_mutex);
SignalInfo* handler = signal_handlers;
- bool unlisten = true;
+ sa_handler_t oldact_handler = SIG_DFL;
+ bool any_remaining = false;
intptr_t signal = -1;
while (handler != NULL) {
bool remove = false;
@@ -1078,7 +1088,7 @@
remove = true;
signal = handler->signal();
} else {
- unlisten = false;
+ any_remaining = true;
}
}
SignalInfo* next = handler->next();
@@ -1087,9 +1097,9 @@
}
handler = next;
}
- if (unlisten && (signal != -1)) {
+ if ((signal != -1) && !any_remaining) {
struct sigaction act = {};
- act.sa_handler = SIG_DFL;
+ act.sa_handler = oldact_handler;
VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
}
}
diff --git a/runtime/bin/process_macos.cc b/runtime/bin/process_macos.cc
index 624ea8a..78a84ba 100644
--- a/runtime/bin/process_macos.cc
+++ b/runtime/bin/process_macos.cc
@@ -1037,8 +1037,10 @@
MutexLocker lock(signal_mutex);
SignalInfo* handler = signal_handlers;
bool listen = true;
+ sa_handler_t oldact_handler = nullptr;
while (handler != NULL) {
if (handler->signal() == signal) {
+ oldact_handler = handler->oldact();
listen = false;
break;
}
@@ -1051,14 +1053,17 @@
for (int i = 0; i < kSignalsCount; i++) {
sigaddset(&act.sa_mask, kSignals[i]);
}
- intptr_t status = NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
+ struct sigaction oldact = {};
+ intptr_t status = NO_RETRY_EXPECTED(sigaction(signal, &act, &oldact));
if (status < 0) {
close(fds[0]);
close(fds[1]);
return -1;
}
+ oldact_handler = oldact.sa_handler;
}
- signal_handlers = new SignalInfo(fds[1], signal, signal_handlers);
+ signal_handlers =
+ new SignalInfo(fds[1], signal, oldact_handler, signal_handlers);
return fds[0];
}
@@ -1070,7 +1075,9 @@
ThreadSignalBlocker blocker(kSignalsCount, kSignals);
MutexLocker lock(signal_mutex);
SignalInfo* handler = signal_handlers;
- bool unlisten = true;
+ sa_handler_t oldact_handler = SIG_DFL;
+ bool any_removed = false;
+ bool any_remaining = false;
while (handler != NULL) {
bool remove = false;
if (handler->signal() == signal) {
@@ -1080,8 +1087,10 @@
}
handler->Unlink();
remove = true;
+ oldact_handler = handler->oldact();
+ any_removed = true;
} else {
- unlisten = false;
+ any_remaining = true;
}
}
SignalInfo* next = handler->next();
@@ -1090,9 +1099,9 @@
}
handler = next;
}
- if (unlisten) {
+ if (any_removed && !any_remaining) {
struct sigaction act = {};
- act.sa_handler = SIG_DFL;
+ act.sa_handler = oldact_handler;
VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
}
}
@@ -1101,7 +1110,8 @@
ThreadSignalBlocker blocker(kSignalsCount, kSignals);
MutexLocker lock(signal_mutex);
SignalInfo* handler = signal_handlers;
- bool unlisten = true;
+ sa_handler_t oldact_handler = SIG_DFL;
+ bool any_remaining = false;
intptr_t signal = -1;
while (handler != NULL) {
bool remove = false;
@@ -1114,7 +1124,7 @@
remove = true;
signal = handler->signal();
} else {
- unlisten = false;
+ any_remaining = true;
}
}
SignalInfo* next = handler->next();
@@ -1123,9 +1133,9 @@
}
handler = next;
}
- if (unlisten && (signal != -1)) {
+ if ((signal != -1) && !any_remaining) {
struct sigaction act = {};
- act.sa_handler = SIG_DFL;
+ act.sa_handler = oldact_handler;
VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
}
}
diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc
index 8edd8dd..b3bc9a9 100644
--- a/runtime/bin/process_win.cc
+++ b/runtime/bin/process_win.cc
@@ -1032,7 +1032,8 @@
return -1;
}
}
- signal_handlers = new SignalInfo(write_fd, signal, signal_handlers);
+ signal_handlers =
+ new SignalInfo(write_fd, signal, /*oldact=*/nullptr, signal_handlers);
return reinterpret_cast<intptr_t>(new FileHandle(fds[kReadHandle]));
}
diff --git a/tools/VERSION b/tools/VERSION
index 99a1532..497b456 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 14
PATCH 0
-PRERELEASE 93
+PRERELEASE 94
PRERELEASE_PATCH 0
\ No newline at end of file