[AD] [patch] race condition in mixer.c |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
There is a race condition in mixer.c that causes crashes on SMP
machines. _mix_some_samples() checks for mixer_voice[i].playing but
nothing guarantees that this value won't be changed before the samples
have been mixed.
I could not find a way to fix this in an elegant way because it
would need a plugin API change, so I just fixed it for my platform
(pthreads). Patch enclosed so that everyone is aware of the problem.
Regards,
--
Sam.
--- allegro4-4.0.3.orig/src/mixer.c
+++ allegro4-4.0.3/src/mixer.c
@@ -27,6 +27,12 @@
#include "allegro.h"
#include "allegro/internal/aintern.h"
+#ifdef HAVE_LIBPTHREAD
+
+#include <pthread.h>
+static pthread_mutex_t voice_mutex;
+
+#endif
typedef struct MIXER_VOICE
@@ -258,6 +264,10 @@
mixer_lock_mem();
+#ifdef HAVE_LIBPTHREAD
+ pthread_mutex_init(&voice_mutex, NULL);
+#endif
+
return 0;
}
@@ -268,6 +278,10 @@
*/
void _mixer_exit(void)
{
+#ifdef HAVE_LIBPTHREAD
+ pthread_mutex_destroy(&voice_mutex);
+#endif
+
if (mix_buffer) {
free(mix_buffer);
mix_buffer = NULL;
@@ -1065,6 +1079,10 @@
for (i=0; i<mix_size/2; i++)
*(l++) = 0x80008000;
+#ifdef HAVE_LIBPTHREAD
+ pthread_mutex_lock(&voice_mutex);
+#endif
+
if (_sound_hq >= 2) {
/* top quality interpolated 16 bit mixing */
for (i=0; i<mix_voices; i++) {
@@ -1166,6 +1184,10 @@
}
}
+#ifdef HAVE_LIBPTHREAD
+ pthread_mutex_unlock(&voice_mutex);
+#endif
+
_farsetsel(seg);
/* transfer to conventional memory buffer using a clip table */
@@ -1232,9 +1254,15 @@
*/
void _mixer_release_voice(int voice)
{
+#ifdef HAVE_LIBPTHREAD
+ pthread_mutex_lock(&voice_mutex);
+#endif
mixer_voice[voice].playing = FALSE;
mixer_voice[voice].data8 = NULL;
mixer_voice[voice].data16 = NULL;
+#ifdef HAVE_LIBPTHREAD
+ pthread_mutex_unlock(&voice_mutex);
+#endif
}
END_OF_FUNCTION(_mixer_release_voice);