Fix potential memory leaks if CoreAudio initialization fails.
authorRyan C. Gordon <icculus@icculus.org>
Sat, 28 Oct 2006 07:44:38 +0000
changeset 2055 72cc2226d6a3
parent 2054 d22372343744
child 2056 ba0a03843db4
Fix potential memory leaks if CoreAudio initialization fails.
src/audio/macosx/SDL_coreaudio.c
src/audio/macosx/SDL_coreaudio.h
--- a/src/audio/macosx/SDL_coreaudio.c	Sat Oct 28 07:39:35 2006 +0000
+++ b/src/audio/macosx/SDL_coreaudio.c	Sat Oct 28 07:44:38 2006 +0000
@@ -315,26 +315,29 @@
 COREAUDIO_CloseDevice(_THIS)
 {
     if (this->hidden != NULL) {
-        OSStatus result = noErr;
-        AURenderCallbackStruct callback;
-        const AudioUnitElement output_bus = 0;
-        const AudioUnitElement input_bus = 1;
-        const int iscapture = this->iscapture;
-        const AudioUnitElement bus = ((iscapture) ? input_bus : output_bus);
-        const AudioUnitScope scope = ((iscapture) ? kAudioUnitScope_Output :
-                                                    kAudioUnitScope_Input);
+        if (this->hidden->audioUnitOpened) {
+            OSStatus result = noErr;
+            AURenderCallbackStruct callback;
+            const AudioUnitElement output_bus = 0;
+            const AudioUnitElement input_bus = 1;
+            const int iscapture = this->iscapture;
+            const AudioUnitElement bus = ((iscapture) ? input_bus : output_bus);
+            const AudioUnitScope scope = ((iscapture) ? kAudioUnitScope_Output :
+                                                        kAudioUnitScope_Input);
 
-        /* stop processing the audio unit */
-        result = AudioOutputUnitStop(this->hidden->audioUnit);
+            /* stop processing the audio unit */
+            result = AudioOutputUnitStop(this->hidden->audioUnit);
 
-        /* Remove the input callback */
-        SDL_memset(&callback, '\0', sizeof (AURenderCallbackStruct));
-        result = AudioUnitSetProperty(this->hidden->audioUnit,
-                                      kAudioUnitProperty_SetRenderCallback,
-                                      scope, bus, &callback, sizeof (callback));
+            /* Remove the input callback */
+            SDL_memset(&callback, '\0', sizeof (AURenderCallbackStruct));
+            result = AudioUnitSetProperty(this->hidden->audioUnit,
+                                          kAudioUnitProperty_SetRenderCallback,
+                                          scope, bus, &callback,
+                                          sizeof (callback));
 
-        CloseComponent(this->hidden->audioUnit);
-
+            CloseComponent(this->hidden->audioUnit);
+            this->hidden->audioUnitOpened = 0;
+        }
         SDL_free(this->hidden->buffer);
         SDL_free(this->hidden);
         this->hidden = NULL;
@@ -435,6 +438,8 @@
     result = OpenAComponent(comp, &this->hidden->audioUnit);
     CHECK_RESULT("OpenAComponent");
 
+    this->hidden->audioUnitOpened = 1;
+
     // !!! FIXME: this is wrong?
     enableIO = ((iscapture) ? 1 : 0);
     result = AudioUnitSetProperty(this->hidden->audioUnit,
@@ -544,6 +549,7 @@
     }
 
     if (!valid_datatype) {      /* shouldn't happen, but just in case... */
+        COREAUDIO_CloseDevice(this);
         SDL_SetError("Unsupported audio format");
         return 0;
     }
@@ -554,6 +560,7 @@
         strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
 
     if (!prepare_audiounit(this, devname, iscapture, &strdesc)) {
+        COREAUDIO_CloseDevice(this); \
         return 0;  /* prepare_audiounit() will call SDL_SetError()... */
     }
 
--- a/src/audio/macosx/SDL_coreaudio.h	Sat Oct 28 07:39:35 2006 +0000
+++ b/src/audio/macosx/SDL_coreaudio.h	Sat Oct 28 07:44:38 2006 +0000
@@ -32,6 +32,7 @@
 struct SDL_PrivateAudioData
 {
     AudioUnit audioUnit;
+    int audioUnitInitialized;
     void *buffer;
     UInt32 bufferOffset;
     UInt32 bufferSize;