Skip to content

Commit

Permalink
Version 2.14.0-186.0.dev
Browse files Browse the repository at this point in the history
Merge commit '4d0fb34272be75e6fd40fafa73507546a002ad6d' into 'dev'
  • Loading branch information
Dart CI committed Jun 4, 2021
2 parents ad66b9b + 4d0fb34 commit 657d6db
Show file tree
Hide file tree
Showing 19 changed files with 146 additions and 39 deletions.
17 changes: 0 additions & 17 deletions pkg/_fe_analyzer_shared/lib/src/base/errors.dart
Expand Up @@ -54,23 +54,6 @@ abstract class ErrorCode {
// ignore: unnecessary_null_comparison
assert(isUnresolvedIdentifier != null);

@Deprecated('Use the default constructor')
const ErrorCode.temporary2({
String? correction,
bool hasPublishedDocs = false,
bool isUnresolvedIdentifier = false,
required String message,
required String name,
required String uniqueName,
}) : this(
correction: correction,
hasPublishedDocs: hasPublishedDocs,
isUnresolvedIdentifier: isUnresolvedIdentifier,
message: message,
name: name,
uniqueName: uniqueName,
);

/**
* The template used to create the correction to be displayed for this error,
* or `null` if there is no correction information for this error. The
Expand Down
1 change: 1 addition & 0 deletions pkg/analysis_server/analysis_options.yaml
Expand Up @@ -17,6 +17,7 @@ linter:
rules:
- await_only_futures
- avoid_single_cascade_in_expression_statements
- depend_on_referenced_packages
- empty_statements
- iterable_contains_unrelated_type
- list_remove_unrelated_type
Expand Down
1 change: 1 addition & 0 deletions pkg/analysis_server_client/analysis_options.yaml
Expand Up @@ -5,6 +5,7 @@ analyzer:
linter:
rules:
- await_only_futures
- depend_on_referenced_packages
- empty_statements
- unnecessary_brace_in_string_interps
#
Expand Down
1 change: 1 addition & 0 deletions pkg/analyzer/analysis_options.yaml
Expand Up @@ -30,6 +30,7 @@ linter:
- avoid_dynamic_calls
- avoid_unused_constructor_parameters
- await_only_futures
- depend_on_referenced_packages
- empty_statements
- iterable_contains_unrelated_type
- list_remove_unrelated_type
Expand Down
1 change: 1 addition & 0 deletions pkg/analyzer_cli/analysis_options.yaml
Expand Up @@ -11,6 +11,7 @@ analyzer:
linter:
rules:
avoid_unused_constructor_parameters: true
depend_on_referenced_packages: true
directives_ordering: true

# We import heavily from package:analyzer/src.
Expand Down
1 change: 1 addition & 0 deletions pkg/analyzer_plugin/analysis_options.yaml
Expand Up @@ -4,6 +4,7 @@ analyzer:
linter:
rules:
- await_only_futures
- depend_on_referenced_packages
- empty_statements
- unnecessary_brace_in_string_interps
#
Expand Down
1 change: 1 addition & 0 deletions pkg/dartdev/analysis_options.yaml
Expand Up @@ -13,6 +13,7 @@ analyzer:
linter:
rules:
- always_declare_return_types
- depend_on_referenced_packages
- directives_ordering
- overridden_fields
- prefer_single_quotes
Expand Down
2 changes: 2 additions & 0 deletions runtime/bin/file_system_watcher.cc
Expand Up @@ -14,6 +14,8 @@
namespace dart {
namespace bin {

bool FileSystemWatcher::delayed_filewatch_callback_ = false;

void FUNCTION_NAME(FileSystemWatcher_IsSupported)(Dart_NativeArguments args) {
Dart_SetBooleanReturnValue(args, FileSystemWatcher::IsSupported());
}
Expand Down
8 changes: 8 additions & 0 deletions runtime/bin/file_system_watcher.h
Expand Up @@ -48,7 +48,15 @@ class FileSystemWatcher {
static intptr_t GetSocketId(intptr_t id, intptr_t path_id);
static Dart_Handle ReadEvents(intptr_t id, intptr_t path_id);

static void set_delayed_filewatch_callback(bool value) {
delayed_filewatch_callback_ = value;
}
static bool delayed_filewatch_callback() {
return delayed_filewatch_callback_;
}

private:
static bool delayed_filewatch_callback_;
DISALLOW_COPY_AND_ASSIGN(FileSystemWatcher);
};

Expand Down
29 changes: 17 additions & 12 deletions runtime/bin/file_system_watcher_macos.cc
Expand Up @@ -61,7 +61,6 @@ class FSEventsWatcher {
int write_fd,
bool recursive)
: watcher_(watcher),
ready_(false),
base_path_length_(strlen(base_path)),
path_ref_(CFStringCreateWithCString(NULL,
base_path,
Expand All @@ -74,9 +73,14 @@ class FSEventsWatcher {
}

~Node() {
Stop();
// This is invoked outside of [Callback] execution because
// [context.release] callback is invoked when [FSEventStream] is
// deallocated, the same [FSEventStream] that [Callback] gets a reference
// to during its execution. [Callback] holding a reference prevents stream
// from deallocation.
close(write_fd_);
CFRelease(path_ref_);
watcher_ = nullptr; // this is to catch access-after-free in Callback
}

void set_ref(FSEventStreamRef ref) { ref_ = ref; }
Expand All @@ -85,6 +89,9 @@ class FSEventsWatcher {
FSEventStreamContext context;
memset(&context, 0, sizeof(context));
context.info = reinterpret_cast<void*>(this);
context.release = [](const void* info) {
delete static_cast<const Node*>(info);
};
CFArrayRef array = CFArrayCreate(
NULL, reinterpret_cast<const void**>(&path_ref_), 1, NULL);
FSEventStreamRef ref = FSEventStreamCreate(
Expand All @@ -93,7 +100,6 @@ class FSEventsWatcher {
CFRelease(array);

set_ref(ref);
ready_.store(true, std::memory_order_release);

FSEventStreamScheduleWithRunLoop(ref_, watcher_->run_loop_,
kCFRunLoopDefaultMode);
Expand All @@ -103,23 +109,19 @@ class FSEventsWatcher {
}

void Stop() {
ASSERT(ready_);
FSEventStreamStop(ref_);
FSEventStreamInvalidate(ref_);
FSEventStreamRelease(ref_);
ready_.store(false, std::memory_order_release);
}

FSEventsWatcher* watcher() const { return watcher_; }
bool ready() const { return ready_.load(std::memory_order_acquire); }
intptr_t base_path_length() const { return base_path_length_; }
int read_fd() const { return read_fd_; }
int write_fd() const { return write_fd_; }
bool recursive() const { return recursive_; }

private:
FSEventsWatcher* watcher_;
std::atomic<bool> ready_;
intptr_t base_path_length_;
CFStringRef path_ref_;
int read_fd_;
Expand Down Expand Up @@ -218,12 +220,15 @@ class FSEventsWatcher {
void* event_paths,
const FSEventStreamEventFlags event_flags[],
const FSEventStreamEventId event_ids[]) {
Node* node = reinterpret_cast<Node*>(client);
if (FileSystemWatcher::delayed_filewatch_callback()) {
// Used in tests to highlight race between callback invocation
// and unwatching the file path, Node destruction
TimerUtils::Sleep(1000 /* ms */);
}
Node* node = static_cast<Node*>(client);
RELEASE_ASSERT(node->watcher() != nullptr);
ASSERT(Thread::Compare(node->watcher()->threadId_,
Thread::GetCurrentThreadId()));
if (!node->ready()) {
return;
}
for (size_t i = 0; i < num_events; i++) {
char* path = reinterpret_cast<char**>(event_paths)[i];
FSEvent event;
Expand Down Expand Up @@ -274,7 +279,7 @@ intptr_t FileSystemWatcher::WatchPath(intptr_t id,

void FileSystemWatcher::UnwatchPath(intptr_t id, intptr_t path_id) {
USE(id);
delete reinterpret_cast<FSEventsWatcher::Node*>(path_id);
reinterpret_cast<FSEventsWatcher::Node*>(path_id)->Stop();
}

intptr_t FileSystemWatcher::GetSocketId(intptr_t id, intptr_t path_id) {
Expand Down
4 changes: 4 additions & 0 deletions runtime/bin/main_options.cc
Expand Up @@ -10,6 +10,7 @@

#include "bin/dartdev_isolate.h"
#include "bin/error_exit.h"
#include "bin/file_system_watcher.h"
#include "bin/options.h"
#include "bin/platform.h"
#include "bin/utils.h"
Expand Down Expand Up @@ -483,6 +484,9 @@ bool Options::ParseArguments(int argc,
Options::bypass_trusting_system_roots());
#endif // !defined(DART_IO_SECURE_SOCKET_DISABLED)

FileSystemWatcher::set_delayed_filewatch_callback(
Options::delayed_filewatch_callback());

// The arguments to the VM are at positions 1 through i-1 in argv.
Platform::SetExecutableArguments(i, argv);

Expand Down
3 changes: 2 additions & 1 deletion runtime/bin/main_options.h
Expand Up @@ -49,7 +49,8 @@ namespace bin {
V(enable_service_port_fallback, enable_service_port_fallback) \
V(disable_dart_dev, disable_dart_dev) \
V(long_ssl_cert_evaluation, long_ssl_cert_evaluation) \
V(bypass_trusting_system_roots, bypass_trusting_system_roots)
V(bypass_trusting_system_roots, bypass_trusting_system_roots) \
V(delayed_filewatch_callback, delayed_filewatch_callback)

// Boolean flags that have a short form.
#define SHORT_BOOL_OPTIONS_LIST(V) \
Expand Down
3 changes: 2 additions & 1 deletion runtime/vm/kernel_isolate.cc
Expand Up @@ -127,7 +127,8 @@ class RunKernelTask : public ThreadPool::Task {
// isolate_ was set as side effect of create callback.
ASSERT(KernelIsolate::IsKernelIsolate(isolate));

isolate->message_handler()->Run(Dart::thread_pool(), NULL, ShutdownIsolate,
isolate->message_handler()->Run(isolate->group()->thread_pool(), NULL,
ShutdownIsolate,
reinterpret_cast<uword>(isolate));
}

Expand Down
3 changes: 2 additions & 1 deletion runtime/vm/service_isolate.cc
Expand Up @@ -389,7 +389,8 @@ class RunServiceTask : public ThreadPool::Task {
return;
}

isolate->message_handler()->Run(Dart::thread_pool(), NULL, ShutdownIsolate,
isolate->message_handler()->Run(isolate->group()->thread_pool(), NULL,
ShutdownIsolate,
reinterpret_cast<uword>(isolate));
}

Expand Down
40 changes: 40 additions & 0 deletions tests/standalone/io/file_system_watcher_large_set_test.dart
@@ -0,0 +1,40 @@
// Copyright (c) 2013, 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.

// VMOptions=--delayed-filewatch-callback --enable-isolate-groups --experimental-enable-isolate-groups-jit
// VMOptions=--delayed-filewatch-callback --no-enable-isolate-groups

// Verifies that cancelling subscription from inside of the event handler
// works as expected, does not result in crash or hang.

import "dart:async";
import "dart:io";

import "package:path/path.dart";

final completer = Completer<void>();
late StreamSubscription subscription;

void handleWatchEvent(event) {
if (event is FileSystemCreateEvent && event.path.endsWith('txt')) {
subscription.cancel();
completer.complete();
}
}

void main() async {
if (!FileSystemEntity.isWatchSupported) return;
final dir = Directory.systemTemp.createTempSync('dart_file_system_watcher');
final watcher = dir.watch();
subscription = watcher.listen(handleWatchEvent);

print('watching ${dir.path}');
for (int i = 0; i < 1000; i++) {
File(join(dir.path, 'file_$i.txt')).createSync();
}
await completer.future;
try {
dir.deleteSync(recursive: true);
} catch (_) {}
}
14 changes: 11 additions & 3 deletions tests/standalone/string_overflow_test.dart
Expand Up @@ -4,13 +4,21 @@

// Test to ensure that the VM does not have an integer overflow issue
// when concatenating strings.
// See https://github.com/dart-lang/sdk/issues/11214

import "package:expect/expect.dart";

main() {
String a = "a";
for (; a.length < 256 * 1024 * 1024;) a = a + a;

var concat = "$a$a$a$a$a$a$a$a";
Expect.equals(concat.length, 2147483648);
var caughtOutOfMemoryException = false;
try {
while (true) {
a = "$a$a$a$a$a$a$a$a";
}
} on OutOfMemoryError {
caughtOutOfMemoryException = true;
}
Expect.isTrue(caughtOutOfMemoryException);
Expect.isTrue(a.startsWith('aaaaa') && a.length > 1024);
}
40 changes: 40 additions & 0 deletions tests/standalone_2/io/file_system_watcher_large_set_test.dart
@@ -0,0 +1,40 @@
// Copyright (c) 2013, 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.

// VMOptions=--delayed-filewatch-callback --enable-isolate-groups --experimental-enable-isolate-groups-jit
// VMOptions=--delayed-filewatch-callback --no-enable-isolate-groups

// Verifies that cancelling subscription from inside of the event handler
// works as expected, does not result in crash or hang.

import "dart:async";
import "dart:io";

import "package:path/path.dart";

final completer = Completer<void>();
var subscription;

void handleWatchEvent(event) {
if (event is FileSystemCreateEvent && event.path.endsWith('txt')) {
subscription.cancel();
completer.complete();
}
}

void main() async {
if (!FileSystemEntity.isWatchSupported) return;
final dir = Directory.systemTemp.createTempSync('dart_file_system_watcher');
final watcher = dir.watch();
subscription = watcher.listen(handleWatchEvent);

print('watching ${dir.path}');
for (int i = 0; i < 1000; i++) {
File(join(dir.path, 'file_$i.txt')).createSync();
}
await completer.future;
try {
dir.deleteSync(recursive: true);
} catch (_) {}
}
14 changes: 11 additions & 3 deletions tests/standalone_2/string_overflow_test.dart
Expand Up @@ -6,13 +6,21 @@

// Test to ensure that the VM does not have an integer overflow issue
// when concatenating strings.
// See https://github.com/dart-lang/sdk/issues/11214

import "package:expect/expect.dart";

main() {
String a = "a";
for (; a.length < 256 * 1024 * 1024;) a = a + a;

var concat = "$a$a$a$a$a$a$a$a";
Expect.equals(concat.length, 2147483648);
var caughtOutOfMemoryException = false;
try {
while (true) {
a = "$a$a$a$a$a$a$a$a";
}
} on OutOfMemoryError {
caughtOutOfMemoryException = true;
}
Expect.isTrue(caughtOutOfMemoryException);
Expect.isTrue(a.startsWith('aaaaa') && a.length > 1024);
}
2 changes: 1 addition & 1 deletion tools/VERSION
Expand Up @@ -27,5 +27,5 @@ CHANNEL dev
MAJOR 2
MINOR 14
PATCH 0
PRERELEASE 185
PRERELEASE 186
PRERELEASE_PATCH 0

0 comments on commit 657d6db

Please sign in to comment.