summaryrefslogtreecommitdiff
path: root/scene/audio
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/audio
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/audio')
-rw-r--r--scene/audio/audio_stream_player.cpp4
1 files changed, 3 insertions, 1 deletions
diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp
index 5065f21604..43c4ce4c82 100644
--- a/scene/audio/audio_stream_player.cpp
+++ b/scene/audio/audio_stream_player.cpp
@@ -45,7 +45,6 @@ void AudioStreamPlayer::_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);
}
}
@@ -58,6 +57,9 @@ void AudioStreamPlayer::_notification(int p_what) {
active.clear();
set_process_internal(false);
}
+ if (!playbacks_to_remove.is_empty()) {
+ emit_signal(SNAME("finished"));
+ }
}
if (p_what == NOTIFICATION_EXIT_TREE) {