Changeset 1321

Show
Ignore:
Timestamp:
01/26/08 20:27:22 (7 months ago)
Author:
bjornroche
Message:

fixed potential isues with accessing freed memory in Core Audio code when dealing with xruns

Location:
portaudio/branches/v19-devel/src/hostapi/coreaudio
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • portaudio/branches/v19-devel/src/hostapi/coreaudio/pa_mac_core_utilities.c

    r1318 r1321  
    6161#include <libkern/OSAtomic.h> 
    6262#include <strings.h> 
     63#include <pthread.h> 
     64#include "pa_memorybarrier.h" 
    6365 
    6466PaError PaMacCore_SetUnixError( int err, int line ) 
     
    636638typedef struct PaMacXRunListNode_s PaMacXRunListNode; 
    637639 
     640/** Always empty, so that it can always be the one returned by 
     641    addToXRunListenerList. note that it's not a pointer. */ 
     642static PaMacXRunListNode firstXRunListNode; 
     643static int xRunListSize; 
     644static pthread_mutex_t xrunMutex; 
     645 
    638646OSStatus xrunCallback( 
    639647    AudioDeviceID inDevice,  
     
    645653   PaMacXRunListNode *node = (PaMacXRunListNode *) inClientData; 
    646654 
    647    node = node->next ; //skip the first node 
    648  
    649    for( ; node; node=node->next ) { 
    650       PaMacCoreStream *stream = node->stream; 
    651  
    652       if( stream->state != ACTIVE ) 
    653          continue; //if the stream isn't active, we don't care if the device is dropping 
    654  
    655       if( isInput ) { 
    656          if( stream->inputDevice == inDevice ) 
    657             OSAtomicOr32( paInputOverflow, (uint32_t *)&(stream->xrunFlags) ); 
    658       } else { 
    659          if( stream->outputDevice == inDevice ) 
    660             OSAtomicOr32( paOutputUnderflow, (uint32_t *)&(stream->xrunFlags) ); 
     655   int ret = pthread_mutex_trylock( &xrunMutex ) ; 
     656 
     657   if( ret == 0 ) { 
     658 
     659      node = node->next ; //skip the first node 
     660 
     661      for( ; node; node=node->next ) { 
     662         PaUtil_ReadMemoryBarrier(); 
     663         PaMacCoreStream *stream = node->stream; 
     664 
     665         if( stream->state != ACTIVE ) 
     666            continue; //if the stream isn't active, we don't care if the device is dropping 
     667 
     668         if( isInput ) { 
     669            if( stream->inputDevice == inDevice ) 
     670               OSAtomicOr32( paInputOverflow, (uint32_t *)&(stream->xrunFlags) ); 
     671         } else { 
     672            if( stream->outputDevice == inDevice ) 
     673               OSAtomicOr32( paOutputUnderflow, (uint32_t *)&(stream->xrunFlags) ); 
     674         } 
    661675      } 
     676 
     677      pthread_mutex_unlock( &xrunMutex ); 
    662678   } 
    663679 
     
    665681} 
    666682 
    667 /** Always empty, so that it can always be the one returned by 
    668     addToXRunListenerList. note that it's not a pointer. */ 
    669 static PaMacXRunListNode firstXRunListNode; 
    670 static int xRunListSize; 
    671  
    672 void initializeXRunListenerList() 
     683int initializeXRunListenerList() 
    673684{ 
    674685   xRunListSize = 0; 
    675686   bzero( (void *) &firstXRunListNode, sizeof(firstXRunListNode) ); 
    676 } 
    677 void destroyXRunListenerList() 
     687   return pthread_mutex_init( &xrunMutex, NULL ); 
     688} 
     689int destroyXRunListenerList() 
    678690{ 
    679691   PaMacXRunListNode *node; 
     
    685697   } 
    686698   xRunListSize = 0; 
     699   return pthread_mutex_destroy( &xrunMutex ); 
    687700} 
    688701 
    689702void *addToXRunListenerList( void *stream ) 
    690703{ 
     704   pthread_mutex_lock( &xrunMutex ); 
    691705   PaMacXRunListNode *newNode; 
    692706   // setup new node: 
     
    694708   newNode->stream = (PaMacCoreStream *) stream; 
    695709   newNode->next = firstXRunListNode.next; 
     710   PaUtil_WriteMemoryBarrier(); 
    696711   // insert: 
    697712   firstXRunListNode.next = newNode; 
     713   pthread_mutex_unlock( &xrunMutex ); 
    698714 
    699715   return &firstXRunListNode; 
     
    702718int removeFromXRunListenerList( void *stream ) 
    703719{ 
     720   pthread_mutex_lock( &xrunMutex ); 
    704721   PaMacXRunListNode *node, *prev; 
    705722   prev = &firstXRunListNode; 
     
    710727         --xRunListSize; 
    711728         prev->next = node->next; 
     729         PaUtil_WriteMemoryBarrier(); 
    712730         free( node ); 
     731         pthread_mutex_unlock( &xrunMutex ); 
    713732         return xRunListSize; 
    714733      } 
     
    717736   } 
    718737 
     738   pthread_mutex_unlock( &xrunMutex ); 
    719739   // failure 
    720740   return xRunListSize; 
  • portaudio/branches/v19-devel/src/hostapi/coreaudio/pa_mac_core_utilities.h

    r1318 r1321  
    218218    void* inClientData ) ; 
    219219 
    220 void initializeXRunListenerList(); 
    221 void destroyXRunListenerList(); 
     220/** returns zero on success or a unix style error code. */ 
     221int initializeXRunListenerList(); 
     222/** returns zero on success or a unix style error code. */ 
     223int destroyXRunListenerList(); 
    222224 
    223225/**Returns the list, so that it can be passed to CorAudio.*/