summaryrefslogtreecommitdiff
path: root/scene/2d
diff options
context:
space:
mode:
authorLyuma <xn.lyuma@gmail.com>2021-10-28 19:45:29 -0700
committerLyuma <xn.lyuma@gmail.com>2021-10-28 19:45:29 -0700
commitc088a2dd897de6c20ac8f5563700f3e455aa818b (patch)
tree2e334fbb2524374db3858fd23036c025fd4e1550 /scene/2d
parentd3547be9ae8ae8bfbbece4757fc0759b712354a7 (diff)
Fix crash due to reentrancy in AudioStreamPlayer* finished signal.
This crash occurred when an audio stream finished playing in NOTIFICATION_INTERNAL_PROCESS, during which it would iterate through a loop of playbacks, leading to a "finished" signal, which removed the audio player from the tree which led to a NOTIFICATION_EXIT_TREE, which would mutate the array of playbacks while within the above loop. This moves the signal callback outside of the loop which avoids the crash. Note: previously, the signal was called multiple times if the same player finishes multiple times in one frame. Now it is at most once per frame. Affects AudioStreamPlayer, AudioStreamPlayer2D and AudioStreamPlayer3D
Diffstat (limited to 'scene/2d')
-rw-r--r--scene/2d/audio_stream_player_2d.cpp4
1 files changed, 3 insertions, 1 deletions
diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp
index 18a50ae098..f73d52152e 100644
--- a/scene/2d/audio_stream_player_2d.cpp
+++ b/scene/2d/audio_stream_player_2d.cpp
@@ -78,7 +78,6 @@ void AudioStreamPlayer2D::_notification(int p_what) {
Vector<Ref<AudioStreamPlayback>> playbacks_to_remove;
for (Ref<AudioStreamPlayback> &playback : stream_playbacks) {
if (playback.is_valid() && !AudioServer::get_singleton()->is_playback_active(playback) && !AudioServer::get_singleton()->is_playback_paused(playback)) {
- emit_signal(SNAME("finished"));
playbacks_to_remove.push_back(playback);
}
}
@@ -91,6 +90,9 @@ void AudioStreamPlayer2D::_notification(int p_what) {
active.clear();
set_physics_process_internal(false);
}
+ if (!playbacks_to_remove.is_empty()) {
+ emit_signal(SNAME("finished"));
+ }
}
while (stream_playbacks.size() > max_polyphony) {