mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
This patch optimizes C++11 range-based for loops where the variable is
copied in each iteration but it would suffice to obtain it by const
reference. This is only applied to loop variables of types that are
expensive to copy which means they are not trivially copyable or have a
non-trivial copy constructor or destructor.
To ensure that it is safe to replace the copy with a const reference
only the following cases are modified:
* The loop variable is const-qualified.
* The loop variable is not const, but only const methods or operators
are invoked on it, or it is used as const reference or value argument
in constructors or function calls.
This is an application of the internal performance-for-range-copy
clang-tidy analysis.
208 lines
6.4 KiB
C++
208 lines
6.4 KiB
C++
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "flutter/runtime/dart_service_isolate.h"
|
|
|
|
#include <string.h>
|
|
#include <algorithm>
|
|
|
|
#include "flutter/fml/logging.h"
|
|
#include "flutter/fml/posix_wrappers.h"
|
|
#include "flutter/runtime/embedder_resources.h"
|
|
#include "third_party/dart/runtime/include/dart_api.h"
|
|
#include "third_party/tonic/converter/dart_converter.h"
|
|
#include "third_party/tonic/dart_library_natives.h"
|
|
#include "third_party/tonic/logging/dart_error.h"
|
|
|
|
#define RETURN_ERROR_HANDLE(handle) \
|
|
if (Dart_IsError(handle)) { \
|
|
return handle; \
|
|
}
|
|
|
|
#define SHUTDOWN_ON_ERROR(handle) \
|
|
if (Dart_IsError(handle)) { \
|
|
*error = fml::strdup(Dart_GetError(handle)); \
|
|
Dart_ExitScope(); \
|
|
Dart_ShutdownIsolate(); \
|
|
return false; \
|
|
}
|
|
|
|
namespace flutter {
|
|
namespace {
|
|
|
|
static Dart_LibraryTagHandler g_embedder_tag_handler;
|
|
static tonic::DartLibraryNatives* g_natives;
|
|
static std::string g_observatory_uri;
|
|
|
|
Dart_NativeFunction GetNativeFunction(Dart_Handle name,
|
|
int argument_count,
|
|
bool* auto_setup_scope) {
|
|
FML_CHECK(g_natives);
|
|
return g_natives->GetNativeFunction(name, argument_count, auto_setup_scope);
|
|
}
|
|
|
|
const uint8_t* GetSymbol(Dart_NativeFunction native_function) {
|
|
FML_CHECK(g_natives);
|
|
return g_natives->GetSymbol(native_function);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
std::mutex DartServiceIsolate::callbacks_mutex_;
|
|
|
|
std::set<std::unique_ptr<DartServiceIsolate::ObservatoryServerStateCallback>>
|
|
DartServiceIsolate::callbacks_;
|
|
|
|
void DartServiceIsolate::NotifyServerState(Dart_NativeArguments args) {
|
|
Dart_Handle exception = nullptr;
|
|
std::string uri =
|
|
tonic::DartConverter<std::string>::FromArguments(args, 0, exception);
|
|
|
|
if (exception) {
|
|
return;
|
|
}
|
|
|
|
g_observatory_uri = uri;
|
|
|
|
// Collect callbacks to fire in a separate collection and invoke them outside
|
|
// the lock.
|
|
std::vector<DartServiceIsolate::ObservatoryServerStateCallback>
|
|
callbacks_to_fire;
|
|
{
|
|
std::scoped_lock lock(callbacks_mutex_);
|
|
for (auto& callback : callbacks_) {
|
|
callbacks_to_fire.push_back(*callback.get());
|
|
}
|
|
}
|
|
|
|
for (const auto& callback_to_fire : callbacks_to_fire) {
|
|
callback_to_fire(uri);
|
|
}
|
|
}
|
|
|
|
DartServiceIsolate::CallbackHandle DartServiceIsolate::AddServerStatusCallback(
|
|
const DartServiceIsolate::ObservatoryServerStateCallback& callback) {
|
|
if (!callback) {
|
|
return 0;
|
|
}
|
|
|
|
auto callback_pointer =
|
|
std::make_unique<DartServiceIsolate::ObservatoryServerStateCallback>(
|
|
callback);
|
|
|
|
auto handle = reinterpret_cast<CallbackHandle>(callback_pointer.get());
|
|
|
|
{
|
|
std::scoped_lock lock(callbacks_mutex_);
|
|
callbacks_.insert(std::move(callback_pointer));
|
|
}
|
|
|
|
if (!g_observatory_uri.empty()) {
|
|
callback(g_observatory_uri);
|
|
}
|
|
|
|
return handle;
|
|
}
|
|
|
|
bool DartServiceIsolate::RemoveServerStatusCallback(
|
|
CallbackHandle callback_handle) {
|
|
std::scoped_lock lock(callbacks_mutex_);
|
|
auto found = std::find_if(
|
|
callbacks_.begin(), callbacks_.end(),
|
|
[callback_handle](const auto& item) {
|
|
return reinterpret_cast<CallbackHandle>(item.get()) == callback_handle;
|
|
});
|
|
|
|
if (found == callbacks_.end()) {
|
|
return false;
|
|
}
|
|
|
|
callbacks_.erase(found);
|
|
return true;
|
|
}
|
|
|
|
void DartServiceIsolate::Shutdown(Dart_NativeArguments args) {
|
|
// NO-OP.
|
|
}
|
|
|
|
bool DartServiceIsolate::Startup(std::string server_ip,
|
|
intptr_t server_port,
|
|
Dart_LibraryTagHandler embedder_tag_handler,
|
|
bool disable_origin_check,
|
|
bool disable_service_auth_codes,
|
|
bool enable_service_port_fallback,
|
|
char** error) {
|
|
Dart_Isolate isolate = Dart_CurrentIsolate();
|
|
FML_CHECK(isolate);
|
|
|
|
// Remember the embedder's library tag handler.
|
|
g_embedder_tag_handler = embedder_tag_handler;
|
|
FML_CHECK(g_embedder_tag_handler);
|
|
|
|
// Setup native entries.
|
|
if (!g_natives) {
|
|
g_natives = new tonic::DartLibraryNatives();
|
|
g_natives->Register({
|
|
{"VMServiceIO_NotifyServerState", NotifyServerState, 1, true},
|
|
{"VMServiceIO_Shutdown", Shutdown, 0, true},
|
|
});
|
|
}
|
|
|
|
Dart_Handle uri = Dart_NewStringFromCString("dart:vmservice_io");
|
|
Dart_Handle library = Dart_LookupLibrary(uri);
|
|
SHUTDOWN_ON_ERROR(library);
|
|
Dart_Handle result = Dart_SetRootLibrary(library);
|
|
SHUTDOWN_ON_ERROR(result);
|
|
result = Dart_SetNativeResolver(library, GetNativeFunction, GetSymbol);
|
|
SHUTDOWN_ON_ERROR(result);
|
|
|
|
// Make runnable.
|
|
Dart_ExitScope();
|
|
Dart_ExitIsolate();
|
|
*error = Dart_IsolateMakeRunnable(isolate);
|
|
if (*error) {
|
|
Dart_EnterIsolate(isolate);
|
|
Dart_ShutdownIsolate();
|
|
return false;
|
|
}
|
|
Dart_EnterIsolate(isolate);
|
|
Dart_EnterScope();
|
|
|
|
library = Dart_RootLibrary();
|
|
SHUTDOWN_ON_ERROR(library);
|
|
|
|
// Set the HTTP server's ip.
|
|
result = Dart_SetField(library, Dart_NewStringFromCString("_ip"),
|
|
Dart_NewStringFromCString(server_ip.c_str()));
|
|
SHUTDOWN_ON_ERROR(result);
|
|
// If we have a port specified, start the server immediately.
|
|
bool auto_start = server_port >= 0;
|
|
if (server_port < 0) {
|
|
// Adjust server_port to port 0 which will result in the first available
|
|
// port when the HTTP server is started.
|
|
server_port = 0;
|
|
}
|
|
// Set the HTTP's servers port.
|
|
result = Dart_SetField(library, Dart_NewStringFromCString("_port"),
|
|
Dart_NewInteger(server_port));
|
|
SHUTDOWN_ON_ERROR(result);
|
|
result = Dart_SetField(library, Dart_NewStringFromCString("_autoStart"),
|
|
Dart_NewBoolean(auto_start));
|
|
SHUTDOWN_ON_ERROR(result);
|
|
result =
|
|
Dart_SetField(library, Dart_NewStringFromCString("_originCheckDisabled"),
|
|
Dart_NewBoolean(disable_origin_check));
|
|
SHUTDOWN_ON_ERROR(result);
|
|
result =
|
|
Dart_SetField(library, Dart_NewStringFromCString("_authCodesDisabled"),
|
|
Dart_NewBoolean(disable_service_auth_codes));
|
|
SHUTDOWN_ON_ERROR(result);
|
|
result = Dart_SetField(
|
|
library, Dart_NewStringFromCString("_enableServicePortFallback"),
|
|
Dart_NewBoolean(enable_service_port_fallback));
|
|
return true;
|
|
}
|
|
|
|
} // namespace flutter
|