comparison render_sdl.c @ 2370:6bcc2ab01ac6

Fix netplay crash
author Michael Pavone <pavone@retrodev.com>
date Mon, 13 Nov 2023 23:37:29 -0800
parents d6a207861cc8
children 1c09f5be285b
comparison
equal deleted inserted replaced
2369:3e064001594a 2370:6bcc2ab01ac6
157 mix_buf = NULL; 157 mix_buf = NULL;
158 } 158 }
159 */ 159 */
160 } 160 }
161 161
162 static uint8_t audio_active;
162 void *render_new_audio_opaque(void) 163 void *render_new_audio_opaque(void)
163 { 164 {
164 return SDL_CreateCond(); 165 return SDL_CreateCond();
165 } 166 }
166 167
169 SDL_DestroyCond(opaque); 170 SDL_DestroyCond(opaque);
170 } 171 }
171 172
172 void render_audio_created(audio_source *source) 173 void render_audio_created(audio_source *source)
173 { 174 {
175 audio_active = 1;
174 if (sync_src == SYNC_AUDIO) { 176 if (sync_src == SYNC_AUDIO) {
175 //SDL_PauseAudio acquires the audio device lock, which is held while the callback runs 177 //SDL_PauseAudio acquires the audio device lock, which is held while the callback runs
176 //since our callback can itself be stuck waiting on the audio_ready condition variable 178 //since our callback can itself be stuck waiting on the audio_ready condition variable
177 //calling SDL_PauseAudio(0) again for audio sources after the first can deadlock 179 //calling SDL_PauseAudio(0) again for audio sources after the first can deadlock
178 //fortunately SDL_GetAudioStatus does not acquire the lock so is safe to call here 180 //fortunately SDL_GetAudioStatus does not acquire the lock so is safe to call here
190 if (sync_src == SYNC_AUDIO) { 192 if (sync_src == SYNC_AUDIO) {
191 SDL_CondSignal(audio_ready); 193 SDL_CondSignal(audio_ready);
192 } 194 }
193 if (!remaining_sources && render_is_audio_sync()) { 195 if (!remaining_sources && render_is_audio_sync()) {
194 SDL_PauseAudio(1); 196 SDL_PauseAudio(1);
197 audio_active = 0;
195 if (sync_src == SYNC_AUDIO_THREAD) { 198 if (sync_src == SYNC_AUDIO_THREAD) {
196 SDL_CondSignal(frame_ready); 199 SDL_CondSignal(frame_ready);
197 } 200 }
198 } 201 }
199 } 202 }
200 203
201 void render_source_resumed(audio_source *src) 204 void render_source_resumed(audio_source *src)
202 { 205 {
206 audio_active = 1;
203 if (sync_src == SYNC_AUDIO) { 207 if (sync_src == SYNC_AUDIO) {
204 //SDL_PauseAudio acquires the audio device lock, which is held while the callback runs 208 //SDL_PauseAudio acquires the audio device lock, which is held while the callback runs
205 //since our callback can itself be stuck waiting on the audio_ready condition variable 209 //since our callback can itself be stuck waiting on the audio_ready condition variable
206 //calling SDL_PauseAudio(0) again for audio sources after the first can deadlock 210 //calling SDL_PauseAudio(0) again for audio sources after the first can deadlock
207 //fortunately SDL_GetAudioStatus does not acquire the lock so is safe to call here 211 //fortunately SDL_GetAudioStatus does not acquire the lock so is safe to call here
1827 } 1831 }
1828 SDL_PauseAudio(0); 1832 SDL_PauseAudio(0);
1829 SDL_LockMutex(frame_mutex); 1833 SDL_LockMutex(frame_mutex);
1830 for(;;) 1834 for(;;)
1831 { 1835 {
1832 while (!frame_queue_len && SDL_GetAudioStatus() == SDL_AUDIO_PLAYING) 1836 while (!frame_queue_len && audio_active)
1833 { 1837 {
1834 SDL_CondWait(frame_ready, frame_mutex); 1838 SDL_CondWait(frame_ready, frame_mutex);
1835 } 1839 }
1836 while (frame_queue_len) 1840 while (frame_queue_len)
1837 { 1841 {
1841 SDL_UnlockMutex(frame_mutex); 1845 SDL_UnlockMutex(frame_mutex);
1842 process_framebuffer(f.buffer, f.which, f.width); 1846 process_framebuffer(f.buffer, f.which, f.width);
1843 release_buffer(f.buffer); 1847 release_buffer(f.buffer);
1844 SDL_LockMutex(frame_mutex); 1848 SDL_LockMutex(frame_mutex);
1845 } 1849 }
1846 if (SDL_GetAudioStatus() != SDL_AUDIO_PLAYING) { 1850 if (!audio_active) {
1847 break; 1851 break;
1848 } 1852 }
1849 } 1853 }
1850 1854
1851 SDL_UnlockMutex(frame_mutex); 1855 SDL_UnlockMutex(frame_mutex);