Support cleaner Dart isolate shutdown handling. (flutter/engine#4121)

If an isolate shuts down (for example if an app calls
Isolate.current.kill()), the UIDartState* on DartController will refer
to a freed object. This wires through notification that the is shutting
down through to the DartController so it can clean up appropriately.

This also makes gives the vm-service isolate an UIDartState* so that
the shutdown callback can behave correctly.
This commit is contained in:
Ian McKellar
2017-09-19 12:11:05 -07:00
committed by GitHub
parent aa090950f6
commit 093a8a4dfd
6 changed files with 29 additions and 5 deletions

View File

@@ -20,6 +20,7 @@ class Window;
class IsolateClient {
public:
virtual void DidCreateSecondaryIsolate(Dart_Isolate isolate) = 0;
virtual void WillShutDownIsolate(Dart_Isolate isolate) = 0;
protected:
virtual ~IsolateClient();
@@ -35,6 +36,9 @@ class UIDartState : public tonic::DartState {
UIDartState* CreateForChildIsolate();
IsolateClient* isolate_client() { return isolate_client_; }
void set_isolate_client(IsolateClient* isolate_client) {
isolate_client_ = isolate_client;
}
Dart_Port main_port() const { return main_port_; }
const std::string& debug_name() const { return debug_name_; }
Window* window() const { return window_.get(); }

View File

@@ -49,6 +49,8 @@ DartController::DartController()
DartController::~DartController() {
if (ui_dart_state_) {
ui_dart_state_->set_isolate_client(nullptr);
// Don't use a tonic::DartIsolateScope here since we never exit the isolate.
Dart_EnterIsolate(ui_dart_state_->isolate());
// Clear the message notify callback.
@@ -217,4 +219,8 @@ void DartController::CreateIsolateFor(
Dart_ExitIsolate();
}
void DartController::IsolateShuttingDown() {
ui_dart_state_ = nullptr;
}
} // namespace blink

View File

@@ -35,6 +35,8 @@ class DartController {
UIDartState* dart_state() const { return ui_dart_state_; }
void IsolateShuttingDown();
private:
bool SendStartMessage(Dart_Handle root_library);

View File

@@ -24,6 +24,7 @@
#include "flutter/lib/ui/dart_runtime_hooks.h"
#include "flutter/lib/ui/dart_ui.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "flutter/lib/ui/window/window.h"
#include "flutter/runtime/dart_service_isolate.h"
#include "flutter/runtime/start_up.h"
#include "lib/fxl/arraysize.h"
@@ -129,7 +130,11 @@ void IsolateShutdownCallback(void* callback_data) {
Dart_Handle sticky_error = Dart_GetStickyError();
FXL_CHECK(LogIfError(sticky_error));
}
tonic::DartState* dart_state = static_cast<tonic::DartState*>(callback_data);
UIDartState* dart_state = static_cast<UIDartState*>(callback_data);
IsolateClient* isolate_client = dart_state->isolate_client();
if (isolate_client) {
isolate_client->WillShutDownIsolate(dart_state->isolate());
}
delete dart_state;
}
@@ -188,11 +193,13 @@ Dart_Isolate ServiceIsolateCreateCallback(const char* script_uri,
// No VM-service in release mode.
return nullptr;
#else // FLUTTER_RUNTIME_MODE
tonic::DartState* dart_state = new tonic::DartState();
Dart_Isolate isolate = Dart_CreateIsolate(
script_uri, "main", g_default_isolate_snapshot_data,
g_default_isolate_snapshot_instructions, nullptr, dart_state, error);
UIDartState* dart_state = new UIDartState(nullptr, nullptr);
Dart_Isolate isolate =
Dart_CreateIsolate(script_uri, "main", g_default_isolate_snapshot_data,
g_default_isolate_snapshot_instructions, nullptr,
static_cast<tonic::DartState*>(dart_state), error);
FXL_CHECK(isolate) << error;
dart_state->set_debug_name_prefix(script_uri);
dart_state->SetIsolate(isolate);
FXL_CHECK(Dart_IsServiceIsolate(isolate));
FXL_CHECK(!LogIfError(

View File

@@ -137,6 +137,10 @@ void RuntimeController::DidCreateSecondaryIsolate(Dart_Isolate isolate) {
client_->DidCreateSecondaryIsolate(isolate);
}
void RuntimeController::WillShutDownIsolate(Dart_Isolate isolate) {
dart_controller_->IsolateShuttingDown();
}
Dart_Port RuntimeController::GetMainPort() {
if (!dart_controller_) {
return ILLEGAL_PORT;

View File

@@ -61,6 +61,7 @@ class RuntimeController : public WindowClient, public IsolateClient {
void HandlePlatformMessage(fxl::RefPtr<PlatformMessage> message) override;
void DidCreateSecondaryIsolate(Dart_Isolate isolate) override;
void WillShutDownIsolate(Dart_Isolate isolate) override;
RuntimeDelegate* client_;
std::string language_code_;