Skip to content

Commit c571698

Browse files
authored
Avoid concurrent modification of persistent frame callbacks (#131677)
Fixes flutter/flutter#131415 We should do an audit of all such cases though, filed flutter/flutter#131678
1 parent b9c3f1f commit c571698

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

packages/flutter/lib/src/scheduler/binding.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1227,7 +1227,7 @@ mixin SchedulerBinding on BindingBase {
12271227
try {
12281228
// PERSISTENT FRAME CALLBACKS
12291229
_schedulerPhase = SchedulerPhase.persistentCallbacks;
1230-
for (final FrameCallback callback in _persistentCallbacks) {
1230+
for (final FrameCallback callback in List<FrameCallback>.of(_persistentCallbacks)) {
12311231
_invokeFrameCallback(callback, _currentFrameTimeStamp!);
12321232
}
12331233

packages/flutter/test/scheduler/binding_test.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,21 @@ void main() {
2828
);
2929
timeDilation = 1.0;
3030
});
31+
32+
test('Adding a persistent frame callback during a persistent frame callback', () {
33+
bool calledBack = false;
34+
SchedulerBinding.instance.addPersistentFrameCallback((Duration timeStamp) {
35+
if (!calledBack) {
36+
SchedulerBinding.instance.addPersistentFrameCallback((Duration timeStamp) {
37+
calledBack = true;
38+
});
39+
}
40+
});
41+
SchedulerBinding.instance.handleBeginFrame(null);
42+
SchedulerBinding.instance.handleDrawFrame();
43+
expect(calledBack, false);
44+
SchedulerBinding.instance.handleBeginFrame(null);
45+
SchedulerBinding.instance.handleDrawFrame();
46+
expect(calledBack, true);
47+
});
3148
}

0 commit comments

Comments
 (0)