Skip to content

Commit 4ac8612

Browse files
chinmaygardeNoamDev
authored andcommitted
Fix data race in DartIsolateGroupData. (flutter-team-archive#15949)
This class is meant to be thread safe. In fact, its headerdoc statement on thread safety even mentions this. All fields on the class are readonly except the child isolate preparer. This field is set during VM instantiated isolate initialization. The VM may launch multiple isolate in the same isolate group on at the same time (each on a VM backed thread pool thread). Attempting to set the field without synchronization is a data race. Fixes flutter/flutter#49358 Fixes b/147798920
1 parent 2ad14d4 commit 4ac8612

3 files changed

Lines changed: 15 additions & 6 deletions

File tree

runtime/dart_isolate.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ bool DartIsolate::InitializeIsolate(
814814
// also a root isolate) by the utility routines in the VM. However, secondary
815815
// isolates will be run by the VM if they are marked as runnable.
816816
if (!embedder_isolate->IsRootIsolate()) {
817-
const ChildIsolatePreparer& child_isolate_preparer =
817+
auto child_isolate_preparer =
818818
embedder_isolate->GetIsolateGroupData().GetChildIsolatePreparer();
819819
FML_DCHECK(child_isolate_preparer);
820820
if (!child_isolate_preparer(embedder_isolate.get())) {

runtime/dart_isolate_group_data.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ const std::string& DartIsolateGroupData::GetAdvisoryScriptEntrypoint() const {
4444
return advisory_script_entrypoint_;
4545
}
4646

47-
const ChildIsolatePreparer& DartIsolateGroupData::GetChildIsolatePreparer()
48-
const {
47+
ChildIsolatePreparer DartIsolateGroupData::GetChildIsolatePreparer() const {
48+
std::scoped_lock lock(child_isolate_preparer_mutex_);
4949
return child_isolate_preparer_;
5050
}
5151

@@ -59,6 +59,7 @@ const fml::closure& DartIsolateGroupData::GetIsolateShutdownCallback() const {
5959

6060
void DartIsolateGroupData::SetChildIsolatePreparer(
6161
const ChildIsolatePreparer& value) {
62+
std::scoped_lock lock(child_isolate_preparer_mutex_);
6263
child_isolate_preparer_ = value;
6364
}
6465

runtime/dart_isolate_group_data.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef FLUTTER_RUNTIME_DART_ISOLATE_GROUP_DATA_H_
66
#define FLUTTER_RUNTIME_DART_ISOLATE_GROUP_DATA_H_
77

8+
#include <mutex>
89
#include <string>
910

1011
#include "flutter/common/settings.h"
@@ -37,25 +38,32 @@ class DartIsolateGroupData {
3738
~DartIsolateGroupData();
3839

3940
const Settings& GetSettings() const;
41+
4042
fml::RefPtr<const DartSnapshot> GetIsolateSnapshot() const;
43+
4144
const std::string& GetAdvisoryScriptURI() const;
45+
4246
const std::string& GetAdvisoryScriptEntrypoint() const;
43-
const ChildIsolatePreparer& GetChildIsolatePreparer() const;
47+
48+
ChildIsolatePreparer GetChildIsolatePreparer() const;
49+
4450
const fml::closure& GetIsolateCreateCallback() const;
51+
4552
const fml::closure& GetIsolateShutdownCallback() const;
4653

4754
void SetChildIsolatePreparer(const ChildIsolatePreparer& value);
4855

4956
private:
50-
FML_DISALLOW_COPY_AND_ASSIGN(DartIsolateGroupData);
51-
5257
const Settings settings_;
5358
const fml::RefPtr<const DartSnapshot> isolate_snapshot_;
5459
const std::string advisory_script_uri_;
5560
const std::string advisory_script_entrypoint_;
61+
mutable std::mutex child_isolate_preparer_mutex_;
5662
ChildIsolatePreparer child_isolate_preparer_;
5763
const fml::closure isolate_create_callback_;
5864
const fml::closure isolate_shutdown_callback_;
65+
66+
FML_DISALLOW_COPY_AND_ASSIGN(DartIsolateGroupData);
5967
};
6068

6169
} // namespace flutter

0 commit comments

Comments
 (0)