Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit a6c09b8

Browse files
committed
WPH migration
1 parent 95b2ebf commit a6c09b8

File tree

12 files changed

+182
-36
lines changed

12 files changed

+182
-36
lines changed

lib/ui/painting/image_encoding.cc

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ enum ImageByteFormat {
3535
kPNG,
3636
};
3737

38-
void FinalizeSkData(void* isolate_callback_data,
39-
Dart_WeakPersistentHandle handle,
40-
void* peer) {
38+
void FinalizeSkData(void* isolate_callback_data, void* peer) {
4139
SkData* buffer = reinterpret_cast<SkData*>(peer);
4240
buffer->unref();
4341
}

runtime/dart_isolate.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,11 @@ void DartIsolate::AddIsolateShutdownCallback(const fml::closure& closure) {
865865
}
866866

867867
void DartIsolate::OnShutdownCallback() {
868+
tonic::DartState* state = tonic::DartState::Current();
869+
if (state != nullptr) {
870+
state->SetIsShuttingDown();
871+
}
872+
868873
{
869874
tonic::DartApiScope api_scope;
870875
Dart_Handle sticky_error = Dart_GetStickyError();

shell/platform/embedder/embedder.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1862,8 +1862,7 @@ FlutterEngineResult FlutterEnginePostDartObject(
18621862
dart_object.value.as_external_typed_data.data = buffer;
18631863
dart_object.value.as_external_typed_data.peer = peer;
18641864
dart_object.value.as_external_typed_data.callback =
1865-
+[](void* unused_isolate_callback_data,
1866-
Dart_WeakPersistentHandle unused_handle, void* peer) {
1865+
+[](void* unused_isolate_callback_data, void* peer) {
18671866
auto typed_peer = reinterpret_cast<ExternalTypedDataPeer*>(peer);
18681867
typed_peer->trampoline(typed_peer->user_data);
18691868
delete typed_peer;

shell/platform/fuchsia/dart_runner/dart_runner.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ void IsolateShutdownCallback(void* isolate_group_data, void* isolate_data) {
9292
tonic::DartMicrotaskQueue::GetForCurrentThread()->Destroy();
9393
async_loop_quit(loop);
9494
}
95+
96+
auto state =
97+
static_cast<std::shared_ptr<tonic::DartState>*>(isolate_group_data);
98+
state->get()->SetIsShuttingDown();
9599
}
96100

97101
void IsolateGroupCleanupCallback(void* isolate_group_data) {

third_party/tonic/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ source_set("tonic") {
2929
"dart_persistent_value.h",
3030
"dart_state.cc",
3131
"dart_state.h",
32+
"dart_weak_persistent_value.cc",
33+
"dart_weak_persistent_value.h",
3234
"dart_wrappable.cc",
3335
"dart_wrappable.h",
3436
"dart_wrapper_info.h",

third_party/tonic/dart_state.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ DartState::DartState(int dirfd,
2727
message_handler_(new DartMessageHandler()),
2828
file_loader_(new FileLoader(dirfd)),
2929
message_epilogue_(message_epilogue),
30-
has_set_return_code_(false) {}
30+
has_set_return_code_(false),
31+
is_shutting_down_(false) {}
3132

3233
DartState::~DartState() {}
3334

third_party/tonic/dart_state.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ class DartState : public std::enable_shared_from_this<DartState> {
6868
void SetReturnCodeCallback(std::function<void(uint32_t)> callback);
6969
bool has_set_return_code() const { return has_set_return_code_; }
7070

71+
void SetIsShuttingDown() { is_shutting_down_ = true; }
72+
bool IsShuttingDown() { return is_shutting_down_; }
73+
7174
virtual void DidSetIsolate();
7275

7376
static Dart_Handle HandleLibraryTag(Dart_LibraryTag tag,
@@ -83,6 +86,7 @@ class DartState : public std::enable_shared_from_this<DartState> {
8386
std::function<void(Dart_Handle)> message_epilogue_;
8487
std::function<void(uint32_t)> set_return_code_callback_;
8588
bool has_set_return_code_;
89+
std::atomic<bool> is_shutting_down_;
8690

8791
protected:
8892
TONIC_DISALLOW_COPY_AND_ASSIGN(DartState);
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "tonic/dart_weak_persistent_value.h"
6+
7+
#include "tonic/dart_state.h"
8+
#include "tonic/scopes/dart_isolate_scope.h"
9+
10+
namespace tonic {
11+
12+
DartWeakPersistentValue::DartWeakPersistentValue() : handle_(nullptr) {}
13+
14+
DartWeakPersistentValue::~DartWeakPersistentValue() {
15+
Clear();
16+
}
17+
18+
void DartWeakPersistentValue::Set(DartState* dart_state,
19+
Dart_Handle object,
20+
void* peer,
21+
intptr_t external_allocation_size,
22+
Dart_HandleFinalizer callback) {
23+
TONIC_DCHECK(is_empty());
24+
dart_state_ = dart_state->GetWeakPtr();
25+
handle_ = Dart_NewWeakPersistentHandle(object, peer, external_allocation_size,
26+
callback);
27+
}
28+
29+
void DartWeakPersistentValue::Clear() {
30+
if (!handle_) {
31+
return;
32+
}
33+
34+
auto dart_state = dart_state_.lock();
35+
if (!dart_state) {
36+
return;
37+
}
38+
39+
if (!dart_state->IsShuttingDown()) {
40+
if (Dart_CurrentIsolateGroup()) {
41+
Dart_DeleteWeakPersistentHandle(handle_);
42+
} else {
43+
DartIsolateScope scope(dart_state->isolate());
44+
Dart_DeleteWeakPersistentHandle(handle_);
45+
}
46+
}
47+
// If it's shutting down, the handle will be deleted already.
48+
49+
dart_state_.reset();
50+
handle_ = nullptr;
51+
}
52+
53+
Dart_Handle DartWeakPersistentValue::Get() {
54+
auto dart_state = dart_state_.lock();
55+
TONIC_DCHECK(dart_state);
56+
TONIC_DCHECK(!dart_state->IsShuttingDown());
57+
if (!handle_) {
58+
return nullptr;
59+
}
60+
return Dart_HandleFromWeakPersistent(handle_);
61+
}
62+
63+
} // namespace tonic
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef LIB_TONIC_DART_WEAK_PERSISTENT_VALUE_H_
6+
#define LIB_TONIC_DART_WEAK_PERSISTENT_VALUE_H_
7+
8+
#include <memory>
9+
10+
#include "third_party/dart/runtime/include/dart_api.h"
11+
#include "tonic/common/macros.h"
12+
13+
namespace tonic {
14+
class DartState;
15+
16+
// DartWeakPersistentValue is a bookkeeping class to help pair calls to
17+
// Dart_NewWeakPersistentHandle with Dart_DeleteWeakPersistentHandle even in
18+
// the case if IsolateGroup shutdown. Consider using this class instead of
19+
// holding a Dart_PersistentHandle directly so that you don't leak the
20+
// Dart_WeakPersistentHandle.
21+
class DartWeakPersistentValue {
22+
public:
23+
DartWeakPersistentValue();
24+
~DartWeakPersistentValue();
25+
26+
Dart_WeakPersistentHandle value() const { return handle_; }
27+
bool is_empty() const { return handle_ == nullptr; }
28+
29+
void Set(DartState* dart_state,
30+
Dart_Handle object,
31+
void* peer,
32+
intptr_t external_allocation_size,
33+
Dart_HandleFinalizer callback);
34+
void Clear();
35+
Dart_Handle Get();
36+
37+
const std::weak_ptr<DartState>& dart_state() const { return dart_state_; }
38+
39+
private:
40+
std::weak_ptr<DartState> dart_state_;
41+
Dart_WeakPersistentHandle handle_;
42+
43+
TONIC_DISALLOW_COPY_AND_ASSIGN(DartWeakPersistentValue);
44+
};
45+
46+
} // namespace tonic
47+
48+
#endif // LIB_TONIC_DART_WEAK_PERSISTENT_VALUE_H_

third_party/tonic/dart_wrappable.cc

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@
1212
namespace tonic {
1313

1414
DartWrappable::~DartWrappable() {
15-
TONIC_CHECK(!dart_wrapper_);
15+
// Calls the destructor of dart_wrapper_ to delete WeakPersistentHandle.
1616
}
1717

1818
// TODO(dnfield): Delete this. https://github.com/flutter/flutter/issues/50997
1919
Dart_Handle DartWrappable::CreateDartWrapper(DartState* dart_state) {
20-
TONIC_DCHECK(!dart_wrapper_);
20+
if (!dart_wrapper_.is_empty()) {
21+
// Any previously given out wrapper must have been GCed.
22+
TONIC_DCHECK(Dart_IsNull(dart_wrapper_.Get()));
23+
dart_wrapper_.Clear();
24+
}
25+
2126
const DartWrapperInfo& info = GetDartWrapperInfo();
2227

2328
Dart_PersistentHandle type = dart_state->class_library().GetClass(info);
@@ -36,14 +41,19 @@ Dart_Handle DartWrappable::CreateDartWrapper(DartState* dart_state) {
3641
TONIC_DCHECK(!LogIfError(res));
3742

3843
this->RetainDartWrappableReference(); // Balanced in FinalizeDartWrapper.
39-
dart_wrapper_ = Dart_NewWeakPersistentHandle(
40-
wrapper, this, GetAllocationSize(), &FinalizeDartWrapper);
44+
dart_wrapper_.Set(dart_state, wrapper, this, GetAllocationSize(),
45+
&FinalizeDartWrapper);
4146

4247
return wrapper;
4348
}
4449

4550
void DartWrappable::AssociateWithDartWrapper(Dart_Handle wrapper) {
46-
TONIC_DCHECK(!dart_wrapper_);
51+
if (!dart_wrapper_.is_empty()) {
52+
// Any previously given out wrapper must have been GCed.
53+
TONIC_DCHECK(Dart_IsNull(dart_wrapper_.Get()));
54+
dart_wrapper_.Clear();
55+
}
56+
4757
TONIC_CHECK(!LogIfError(wrapper));
4858

4959
const DartWrapperInfo& info = GetDartWrapperInfo();
@@ -54,26 +64,25 @@ void DartWrappable::AssociateWithDartWrapper(Dart_Handle wrapper) {
5464
wrapper, kWrapperInfoIndex, reinterpret_cast<intptr_t>(&info))));
5565

5666
this->RetainDartWrappableReference(); // Balanced in FinalizeDartWrapper.
57-
dart_wrapper_ = Dart_NewWeakPersistentHandle(
58-
wrapper, this, GetAllocationSize(), &FinalizeDartWrapper);
67+
68+
DartState* dart_state = DartState::Current();
69+
dart_wrapper_.Set(dart_state, wrapper, this, GetAllocationSize(),
70+
&FinalizeDartWrapper);
5971
}
6072

6173
void DartWrappable::ClearDartWrapper() {
62-
TONIC_DCHECK(dart_wrapper_);
63-
Dart_Handle wrapper = Dart_HandleFromWeakPersistent(dart_wrapper_);
74+
TONIC_DCHECK(!dart_wrapper_.is_empty());
75+
Dart_Handle wrapper = dart_wrapper_.Get();
6476
TONIC_CHECK(!LogIfError(Dart_SetNativeInstanceField(wrapper, kPeerIndex, 0)));
6577
TONIC_CHECK(
6678
!LogIfError(Dart_SetNativeInstanceField(wrapper, kWrapperInfoIndex, 0)));
67-
Dart_DeleteWeakPersistentHandle(dart_wrapper_);
68-
dart_wrapper_ = nullptr;
79+
dart_wrapper_.Clear();
6980
this->ReleaseDartWrappableReference();
7081
}
7182

7283
void DartWrappable::FinalizeDartWrapper(void* isolate_callback_data,
73-
Dart_WeakPersistentHandle wrapper,
7484
void* peer) {
7585
DartWrappable* wrappable = reinterpret_cast<DartWrappable*>(peer);
76-
wrappable->dart_wrapper_ = nullptr;
7786
wrappable->ReleaseDartWrappableReference(); // Balanced in CreateDartWrapper.
7887
}
7988

0 commit comments

Comments
 (0)