浏览代码

lock-free multithreaded code may lead to double-free or other unexpected results (ie. crash)
* hopefully fixes the following crash @ windows phone store:
Frame Image Function Offset
0 ntdll.dll RtlReportCriticalFailure 0x0000004e
1 ntdll.dll RtlpReportHeapFailure 0x0000001e
2 ntdll.dll RtlpHeapHandleError 0x00000016
3 ntdll.dll RtlpLogHeapFailure 0x0000005a
4 ntdll.dll RtlFreeHeap 0x0004d31e
5 MSVCR110.dll free 0x00000018
6 SDLPal.exe 0x00018b92

Wei Mingzhi 9 年之前
父节点
当前提交
1311e08673
共有 1 个文件被更改,包括 18 次插入0 次删除
  1. 18 0
      sound.c

+ 18 - 0
sound.c

@@ -52,6 +52,7 @@ typedef struct tagSNDPLAYER
 {
    FILE                     *mkf;
    SDL_AudioSpec             spec;
+   SDL_mutex                *mtx;
    LPBYTE                    buf[2], pos[2];
    INT                       audio_len[2];
 #ifdef PAL_HAS_CD
@@ -245,6 +246,8 @@ SOUND_FillAudio(
       return;
    }
 
+   SDL_mutexP(gSndPlayer.mtx);
+
    for (i = 0; i < 2; i++)
    {
       //
@@ -277,6 +280,7 @@ SOUND_FillAudio(
       gSndPlayer.pos[i] += len;
       gSndPlayer.audio_len[i] -= len;
    }
+   SDL_mutexV(gSndPlayer.mtx);
 }
 
 INT
@@ -355,6 +359,7 @@ SOUND_OpenAudio(
    gSndPlayer.pos[1] = NULL;
    gSndPlayer.audio_len[1] = 0;
 
+   gSndPlayer.mtx = SDL_CreateMutex();
    gSndOpened = TRUE;
 
    //
@@ -433,6 +438,7 @@ SOUND_CloseAudio(
 
 --*/
 {
+   SDL_mutexP(gSndPlayer.mtx);
    SDL_CloseAudio();
 
    if (gSndPlayer.buf[0] != NULL)
@@ -453,6 +459,8 @@ SOUND_CloseAudio(
       gSndPlayer.mkf = NULL;
    }
 
+   SDL_DestroyMutex(gSndPlayer.mtx);
+
 #ifdef PAL_HAS_MP3
    SDL_mutexP(gSndPlayer.lock);
 
@@ -564,12 +572,14 @@ SOUND_PlayChannel(
    //
    // Stop playing current sound.
    //
+   SDL_mutexP(gSndPlayer.mtx);
    if (gSndPlayer.buf[iChannel] != NULL)
    {
       LPBYTE p = gSndPlayer.buf[iChannel];
       gSndPlayer.buf[iChannel] = NULL;
       free(p);
    }
+   SDL_mutexV(gSndPlayer.mtx);
 
    if (iSoundNum < 0)
    {
@@ -635,9 +645,17 @@ SOUND_PlayChannel(
       return;
    }
 
+   SDL_mutexP(gSndPlayer.mtx);
+   if (gSndPlayer.buf[iChannel] != NULL)
+   {
+	   LPBYTE p = gSndPlayer.buf[iChannel];
+	   gSndPlayer.buf[iChannel] = NULL;
+	   free(p);
+   }
    gSndPlayer.buf[iChannel] = wavecvt.buf;
    gSndPlayer.audio_len[iChannel] = wavecvt.len * wavecvt.len_mult;
    gSndPlayer.pos[iChannel] = wavecvt.buf;
+   SDL_mutexV(gSndPlayer.mtx);
 }
 
 VOID