Skip to content

Commit

Permalink
Added IsolateNameServer functionality (flutter#5410)
Browse files Browse the repository at this point in the history
* Added IsolateNameServer functionality, which allows for the association
of string names with isolate SendPort ids that can be used to establish
inter-isolate communications.
  • Loading branch information
bkonyi authored Jun 12, 2018
1 parent 412f8b8 commit 61a2d12
Show file tree
Hide file tree
Showing 25 changed files with 426 additions and 22 deletions.
4 changes: 4 additions & 0 deletions lib/ui/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ source_set("ui") {
"dart_runtime_hooks.h",
"dart_ui.cc",
"dart_ui.h",
"isolate_name_server/isolate_name_server.cc",
"isolate_name_server/isolate_name_server.h",
"isolate_name_server/isolate_name_server_natives.cc",
"isolate_name_server/isolate_name_server_natives.h",
"painting/canvas.cc",
"painting/canvas.h",
"painting/codec.cc",
Expand Down
2 changes: 2 additions & 0 deletions lib/ui/dart_ui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "flutter/lib/ui/compositing/scene.h"
#include "flutter/lib/ui/compositing/scene_builder.h"
#include "flutter/lib/ui/dart_runtime_hooks.h"
#include "flutter/lib/ui/isolate_name_server/isolate_name_server_natives.h"
#include "flutter/lib/ui/painting/canvas.h"
#include "flutter/lib/ui/painting/codec.h"
#include "flutter/lib/ui/painting/frame_info.h"
Expand Down Expand Up @@ -60,6 +61,7 @@ void DartUI::InitForGlobal() {
FrameInfo::RegisterNatives(g_natives);
ImageFilter::RegisterNatives(g_natives);
ImageShader::RegisterNatives(g_natives);
IsolateNameServerNatives::RegisterNatives(g_natives);
Paragraph::RegisterNatives(g_natives);
ParagraphBuilder::RegisterNatives(g_natives);
Picture::RegisterNatives(g_natives);
Expand Down
1 change: 1 addition & 0 deletions lib/ui/dart_ui.gni
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ dart_ui_files = [
"$flutter_root/lib/ui/geometry.dart",
"$flutter_root/lib/ui/hash_codes.dart",
"$flutter_root/lib/ui/hooks.dart",
"$flutter_root/lib/ui/isolate_name_server.dart",
"$flutter_root/lib/ui/lerp.dart",
"$flutter_root/lib/ui/natives.dart",
"$flutter_root/lib/ui/painting.dart",
Expand Down
44 changes: 44 additions & 0 deletions lib/ui/isolate_name_server.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

part of dart.ui;

abstract class IsolateNameServer {
// Looks up the [SendPort] associated with a given name. Returns null
// if the name does not exist.
static SendPort lookupPortByName(String name) {
if (name == null) {
throw new ArgumentError("'name' cannot be null.");
}
return _lookupPortByName(name);
}

// Registers a SendPort with a given name. Returns true if registration is
// successful, false if the name entry already exists.
static bool registerPortWithName(SendPort port, String name) {
if (name == null) {
throw new ArgumentError("'name' cannot be null.");
}
if (port == null) {
throw new ArgumentError("'port' cannot be null.");
}
return _registerPortWithName(port, name);
}

// Removes a name to SendPort mapping given a name. Returns true if the
// mapping was successfully removed, false if the mapping does not exist.
static bool removePortNameMapping(String name) {
if (name == null) {
throw new ArgumentError("'name' cannot be null.");
}
return _removePortNameMapping(name);
}

static SendPort _lookupPortByName(String name)
native 'IsolateNameServerNatives_LookupPortByName';
static bool _registerPortWithName(SendPort port, String name)
native 'IsolateNameServerNatives_RegisterPortWithName';
static bool _removePortNameMapping(String name)
native 'IsolateNameServerNatives_RemovePortNameMapping';
}
44 changes: 44 additions & 0 deletions lib/ui/isolate_name_server/isolate_name_server.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2018 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/lib/ui/isolate_name_server/isolate_name_server.h"

namespace blink {

Dart_Port IsolateNameServer::LookupIsolatePortByName(const std::string& name) {
std::unique_lock<std::mutex> lock(mutex_);
return LookupIsolatePortByNameUnprotected(name);
}

Dart_Port IsolateNameServer::LookupIsolatePortByNameUnprotected(
const std::string& name) {
auto port_iterator = port_mapping_.find(name);
if (port_iterator != port_mapping_.end()) {
return port_iterator->second;
}
return ILLEGAL_PORT;
}

bool IsolateNameServer::RegisterIsolatePortWithName(Dart_Port port,
const std::string& name) {
std::unique_lock<std::mutex> lock(mutex_);
if (LookupIsolatePortByNameUnprotected(name) != ILLEGAL_PORT) {
// Name is already registered.
return false;
}
port_mapping_[name] = port;
return true;
}

bool IsolateNameServer::RemoveIsolateNameMapping(const std::string& name) {
std::unique_lock<std::mutex> lock(mutex_);
auto port_iterator = port_mapping_.find(name);
if (port_iterator == port_mapping_.end()) {
return false;
}
port_mapping_.erase(port_iterator);
return true;
}

} // namespace blink
50 changes: 50 additions & 0 deletions lib/ui/isolate_name_server/isolate_name_server.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2018 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.

#ifndef FLUTTER_LIB_UI_ISOLATE_NAME_SERVER_H_
#define FLUTTER_LIB_UI_ISOLATE_NAME_SERVER_H_

#include <map>
#include <mutex>
#include <string>

#include "flutter/fml/synchronization/thread_annotations.h"
#include "lib/fxl/macros.h"
#include "third_party/dart/runtime/include/dart_api.h"

#define LOCK_UNLOCK(m) FML_ACQUIRE(m) FML_RELEASE(m)

namespace blink {

class IsolateNameServer {
public:
IsolateNameServer() {}

// Looks up the Dart_Port associated with a given name. Returns ILLEGAL_PORT
// if the name does not exist.
Dart_Port LookupIsolatePortByName(const std::string& name)
LOCK_UNLOCK(mutex_);

// Registers a Dart_Port with a given name. Returns true if registration is
// successful, false if the name entry already exists.
bool RegisterIsolatePortWithName(Dart_Port port, const std::string& name)
LOCK_UNLOCK(mutex_);

// Removes a name to Dart_Port mapping given a name. Returns true if the
// mapping was successfully removed, false if the mapping does not exist.
bool RemoveIsolateNameMapping(const std::string& name) LOCK_UNLOCK(mutex_);

private:
Dart_Port LookupIsolatePortByNameUnprotected(const std::string& name)
FML_EXCLUSIVE_LOCKS_REQUIRED(mutex_);

mutable std::mutex mutex_;
std::map<std::string, Dart_Port> port_mapping_ FML_GUARDED_BY(mutex_);

FXL_DISALLOW_COPY_AND_ASSIGN(IsolateNameServer);
};

} // namespace blink

#endif // FLUTTER_LIB_UI_ISOLATE_NAME_SERVER_H_
64 changes: 64 additions & 0 deletions lib/ui/isolate_name_server/isolate_name_server_natives.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2018 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 <string>

#include "flutter/lib/ui/isolate_name_server/isolate_name_server.h"
#include "flutter/lib/ui/isolate_name_server/isolate_name_server_natives.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "lib/tonic/dart_binding_macros.h"
#include "lib/tonic/dart_library_natives.h"

namespace blink {

Dart_Handle IsolateNameServerNatives::LookupPortByName(
const std::string& name) {
IsolateNameServer* name_server =
UIDartState::Current()->GetIsolateNameServer();
Dart_Port port = name_server->LookupIsolatePortByName(name);
if (port == ILLEGAL_PORT) {
return Dart_Null();
}
return Dart_NewSendPort(port);
}

Dart_Handle IsolateNameServerNatives::RegisterPortWithName(
Dart_Handle port_handle,
const std::string& name) {
IsolateNameServer* name_server =
UIDartState::Current()->GetIsolateNameServer();
Dart_Port port = ILLEGAL_PORT;
Dart_SendPortGetId(port_handle, &port);
if (!name_server->RegisterIsolatePortWithName(port, name)) {
return Dart_False();
}
return Dart_True();
}

Dart_Handle IsolateNameServerNatives::RemovePortNameMapping(
const std::string& name) {
IsolateNameServer* name_server =
UIDartState::Current()->GetIsolateNameServer();
if (!name_server->RemoveIsolateNameMapping(name)) {
return Dart_False();
}
return Dart_True();
}

#define FOR_EACH_BINDING(V) \
V(IsolateNameServerNatives, LookupPortByName) \
V(IsolateNameServerNatives, RegisterPortWithName) \
V(IsolateNameServerNatives, RemovePortNameMapping)

FOR_EACH_BINDING(DART_NATIVE_CALLBACK_STATIC)

#define DART_REGISTER_NATIVE_STATIC_(CLASS, METHOD) \
DART_REGISTER_NATIVE_STATIC(CLASS, METHOD),

void IsolateNameServerNatives::RegisterNatives(
tonic::DartLibraryNatives* natives) {
natives->Register({FOR_EACH_BINDING(DART_REGISTER_NATIVE_STATIC_)});
}

} // namespace blink
27 changes: 27 additions & 0 deletions lib/ui/isolate_name_server/isolate_name_server_natives.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2018 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.

#ifndef FLUTTER_LIB_UI_ISOLATE_NAME_SERVER_NATIVES_H_
#define FLUTTER_LIB_UI_ISOLATE_NAME_SERVER_NATIVES_H_

#include "third_party/dart/runtime/include/dart_api.h"

namespace tonic {
class DartLibraryNatives;
} // namespace tonic

namespace blink {

class IsolateNameServerNatives {
public:
static Dart_Handle LookupPortByName(const std::string& name);
static Dart_Handle RegisterPortWithName(Dart_Handle port_handle,
const std::string& name);
static Dart_Handle RemovePortNameMapping(const std::string& name);
static void RegisterNatives(tonic::DartLibraryNatives* natives);
};

} // namespace blink

#endif // FLUTTER_LIB_UI_ISOLATE_NAME_SERVER_NATIVES_H_
2 changes: 2 additions & 0 deletions lib/ui/ui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import 'dart:collection' as collection;
import 'dart:convert';
import 'dart:developer' as developer;
import 'dart:io';
import 'dart:isolate' show SendPort;
import 'dart:math' as math;
import 'dart:nativewrappers';
import 'dart:typed_data';
Expand All @@ -25,6 +26,7 @@ part 'compositing.dart';
part 'geometry.dart';
part 'hash_codes.dart';
part 'hooks.dart';
part 'isolate_name_server.dart';
part 'lerp.dart';
part 'natives.dart';
part 'painting.dart';
Expand Down
10 changes: 8 additions & 2 deletions lib/ui/ui_dart_state.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,17 @@ UIDartState::UIDartState(TaskRunners task_runners,
fxl::RefPtr<flow::SkiaUnrefQueue> skia_unref_queue,
std::string advisory_script_uri,
std::string advisory_script_entrypoint,
std::string logger_prefix)
std::string logger_prefix,
IsolateNameServer* isolate_name_server)
: task_runners_(std::move(task_runners)),
add_callback_(std::move(add_callback)),
remove_callback_(std::move(remove_callback)),
resource_context_(std::move(resource_context)),
advisory_script_uri_(std::move(advisory_script_uri)),
advisory_script_entrypoint_(std::move(advisory_script_entrypoint)),
logger_prefix_(std::move(logger_prefix)),
skia_unref_queue_(std::move(skia_unref_queue)) {
skia_unref_queue_(std::move(skia_unref_queue)),
isolate_name_server_(isolate_name_server) {
AddOrRemoveTaskObserver(true /* add */);
}

Expand Down Expand Up @@ -100,4 +102,8 @@ fml::WeakPtr<GrContext> UIDartState::GetResourceContext() const {
return resource_context_;
}

IsolateNameServer* UIDartState::GetIsolateNameServer() {
return isolate_name_server_;
}

} // namespace blink
7 changes: 6 additions & 1 deletion lib/ui/ui_dart_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "flutter/common/task_runners.h"
#include "flutter/flow/skia_gpu_object.h"
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/lib/ui/isolate_name_server/isolate_name_server.h"
#include "lib/fxl/build_config.h"
#include "lib/tonic/dart_microtask_queue.h"
#include "lib/tonic/dart_persistent_value.h"
Expand Down Expand Up @@ -46,6 +47,8 @@ class UIDartState : public tonic::DartState {

fml::WeakPtr<GrContext> GetResourceContext() const;

IsolateNameServer* GetIsolateNameServer();

template <class T>
static flow::SkiaGPUObject<T> CreateGPUObject(sk_sp<T> object) {
if (!object) {
Expand All @@ -65,7 +68,8 @@ class UIDartState : public tonic::DartState {
fxl::RefPtr<flow::SkiaUnrefQueue> skia_unref_queue,
std::string advisory_script_uri,
std::string advisory_script_entrypoint,
std::string logger_prefix);
std::string logger_prefix,
IsolateNameServer* isolate_name_server);

~UIDartState() override;

Expand All @@ -90,6 +94,7 @@ class UIDartState : public tonic::DartState {
std::unique_ptr<Window> window_;
fxl::RefPtr<flow::SkiaUnrefQueue> skia_unref_queue_;
tonic::DartMicrotaskQueue microtask_queue_;
IsolateNameServer* isolate_name_server_;

void AddOrRemoveTaskObserver(bool add);
};
Expand Down
11 changes: 6 additions & 5 deletions runtime/dart_isolate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
namespace blink {

fml::WeakPtr<DartIsolate> DartIsolate::CreateRootIsolate(
const DartVM* vm,
DartVM* vm,
fxl::RefPtr<DartSnapshot> isolate_snapshot,
fxl::RefPtr<DartSnapshot> shared_snapshot,
TaskRunners task_runners,
Expand Down Expand Up @@ -94,7 +94,7 @@ fml::WeakPtr<DartIsolate> DartIsolate::CreateRootIsolate(
return embedder_isolate;
}

DartIsolate::DartIsolate(const DartVM* vm,
DartIsolate::DartIsolate(DartVM* vm,
fxl::RefPtr<DartSnapshot> isolate_snapshot,
fxl::RefPtr<DartSnapshot> shared_snapshot,
TaskRunners task_runners,
Expand All @@ -110,7 +110,8 @@ DartIsolate::DartIsolate(const DartVM* vm,
std::move(unref_queue),
advisory_script_uri,
advisory_script_entrypoint,
vm->GetSettings().log_tag),
vm->GetSettings().log_tag,
vm->GetIsolateNameServer()),
vm_(vm),
isolate_snapshot_(std::move(isolate_snapshot)),
shared_snapshot_(std::move(shared_snapshot)),
Expand All @@ -131,7 +132,7 @@ DartIsolate::Phase DartIsolate::GetPhase() const {
return phase_;
}

const DartVM* DartIsolate::GetDartVM() const {
DartVM* DartIsolate::GetDartVM() const {
return vm_;
}

Expand Down Expand Up @@ -651,7 +652,7 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
return {nullptr, {}};
}

const DartVM* vm = embedder_isolate->GetDartVM();
DartVM* const vm = embedder_isolate->GetDartVM();

if (!is_root_isolate) {
auto raw_embedder_isolate = embedder_isolate.release();
Expand Down
Loading

0 comments on commit 61a2d12

Please sign in to comment.