Changeset 1343

Show
Ignore:
Timestamp:
02/18/08 03:27:03 (6 months ago)
Author:
rossb
Message:

added explicit management of the asioDrivers instance creation and destruction. this fixes a leak where the asioDrivers instance was never destroyed.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • portaudio/branches/v19-devel/src/hostapi/asio/pa_asio.cpp

    r1230 r1343  
    7878    synchronous full duplex double-buffered architecture of ASIO. 
    7979 
    80     @todo check that CoInitialize()/CoUninitialize() are always correctly 
    81         paired, even in error cases. 
    82  
    8380    @todo implement host api specific extension to set i/o buffer sizes in frames 
    8481 
     
    121118#include <string.h> 
    122119//#include <values.h> 
     120#include <new> 
    123121 
    124122#include <windows.h> 
     
    165163*/ 
    166164 
    167 /* external references */ 
    168 extern AsioDrivers* asioDrivers ; 
    169 bool loadAsioDriver(char *name); 
     165 
     166/* external reference to ASIO SDK's asioDrivers. 
     167 
     168 This is a bit messy because we want to explicitly manage  
     169 allocation/deallocation of this structure, but some layers of the SDK  
     170 which we currently use (eg the implementation in asio.cpp) still 
     171 use this global version. 
     172 
     173 For now we keep it in sync with our local instance in the host 
     174 API representation structure, but later we should be able to remove 
     175 all dependence on it. 
     176*/ 
     177extern AsioDrivers* asioDrivers; 
    170178 
    171179 
    172180/* We are trying to be compatible with CARBON but this has not been thoroughly tested. */ 
    173 /* not tested at all since new code was introduced. */ 
     181/* not tested at all since new V19 code was introduced. */ 
    174182#define CARBON_COMPATIBLE  (0) 
    175  
    176  
    177183 
    178184 
     
    301307    PaUtilAllocationGroup *allocations; 
    302308 
     309    AsioDrivers *asioDrivers; 
    303310    void *systemSpecific; 
    304311     
     
    324331    allocated in <group>. 
    325332*/ 
    326 static char **GetAsioDriverNames( PaUtilAllocationGroup *group, long driverCount ) 
     333static char **GetAsioDriverNames( PaAsioHostApiRepresentation *asioHostApi, PaUtilAllocationGroup *group, long driverCount ) 
    327334{ 
    328335    char **result = 0; 
     
    342349        result[i] = result[0] + (32 * i); 
    343350 
    344     asioDrivers->getDriverNames( result, driverCount ); 
     351    asioHostApi->asioDrivers->getDriverNames( result, driverCount ); 
    345352 
    346353error: 
     
    953960    is returned the driver will already be closed. 
    954961*/ 
    955 static PaError LoadAsioDriver( const char *driverName, 
     962static PaError LoadAsioDriver( PaAsioHostApiRepresentation *asioHostApi, const char *driverName, 
    956963        PaAsioDriverInfo *driverInfo, void *systemSpecific ) 
    957964{ 
     
    960967    int asioIsInitialized = 0; 
    961968 
    962     if( !loadAsioDriver( const_cast<char*>(driverName) ) ) 
     969    /* @todo note that the V18 version always called CoInitialize() here to ensure  
     970        that COM was initialized before loading the driver.  
     971        probably the docs need to require clients to initialize COM in new threads? 
     972    */ 
     973    if( !asioHostApi->asioDrivers->loadDriver( const_cast<char*>(driverName) ) ) 
    963974    { 
    964975        result = paUnanticipatedHostError; 
     
    10401051    } 
    10411052 
     1053    asioHostApi->asioDrivers = 0; /* avoid surprises in our error handler below */ 
     1054 
    10421055    asioHostApi->allocations = PaUtil_CreateAllocationGroup(); 
    10431056    if( !asioHostApi->allocations ) 
     
    10461059        goto error; 
    10471060    } 
     1061 
     1062    /* Allocate the AsioDrivers() driver list (class from ASIO SDK) */ 
     1063    try 
     1064    { 
     1065        asioHostApi->asioDrivers = new AsioDrivers(); /* calls CoInitialize(0) */ 
     1066    }  
     1067    catch (std::bad_alloc) 
     1068    { 
     1069        asioHostApi->asioDrivers = 0; 
     1070    } 
     1071    /* some implementations of new (ie MSVC, see http://support.microsoft.com/?kbid=167733) 
     1072       don't throw std::bad_alloc, so we also explicitly test for a null return. */ 
     1073    if( asioHostApi->asioDrivers == 0 ) 
     1074    { 
     1075        result = paInsufficientMemory; 
     1076        goto error; 
     1077    } 
     1078 
     1079    asioDrivers = asioHostApi->asioDrivers; /* keep SDK global in sync until we stop depending on it */ 
    10481080 
    10491081    asioHostApi->systemSpecific = 0; 
     
    10601092        /* use desktop window as system specific ptr */ 
    10611093        asioHostApi->systemSpecific = GetDesktopWindow(); 
    1062         CoInitialize(NULL); 
    10631094    #endif 
    1064  
    1065     /* MUST BE CHECKED : to force fragments loading on Mac */ 
    1066     loadAsioDriver( "dummy" );  
    10671095 
    10681096    /* driverCount is the number of installed drivers - not necessarily 
    10691097        the number of installed physical devices. */ 
    10701098    #if MAC 
    1071         driverCount = asioDrivers->getNumFragments(); 
     1099        driverCount = asioHostApi->asioDrivers->getNumFragments(); 
    10721100    #elif WINDOWS 
    1073         driverCount = asioDrivers->asioGetNumDev(); 
     1101        driverCount = asioHostApi->asioDrivers->asioGetNumDev(); 
    10741102    #endif 
    10751103 
    10761104    if( driverCount > 0 ) 
    10771105    { 
    1078         names = GetAsioDriverNames( asioHostApi->allocations, driverCount ); 
     1106        names = GetAsioDriverNames( asioHostApi, asioHostApi->allocations, driverCount ); 
    10791107        if( !names ) 
    10801108        { 
     
    11421170 
    11431171            /* Attempt to load the asio driver... */ 
    1144             if( LoadAsioDriver( names[i], &paAsioDriverInfo, asioHostApi->systemSpecific ) == paNoError ) 
     1172            if( LoadAsioDriver( asioHostApi, names[i], &paAsioDriverInfo, asioHostApi->systemSpecific ) == paNoError ) 
    11451173            { 
    11461174                PaAsioDeviceInfo *asioDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ]; 
     
    13121340        } 
    13131341 
     1342        delete asioHostApi->asioDrivers; 
     1343        asioDrivers = asioHostApi->asioDrivers; /* keep SDK global in sync until we stop depending on it */ 
     1344 
    13141345        PaUtil_FreeMemory( asioHostApi ); 
    13151346    } 
     
    13241355    /* 
    13251356        IMPLEMENT ME: 
    1326             - clean up any resources not handled by the allocation group 
     1357            - clean up any resources not handled by the allocation group (need to review if there are any) 
    13271358    */ 
    13281359 
     
    13321363        PaUtil_DestroyAllocationGroup( asioHostApi->allocations ); 
    13331364    } 
     1365 
     1366    delete asioHostApi->asioDrivers; /* calls CoUninitialize() */ 
     1367    asioDrivers = asioHostApi->asioDrivers; /* keep SDK global in sync until we stop depending on it */ 
    13341368 
    13351369    PaUtil_FreeMemory( asioHostApi ); 
     
    14311465    if( asioHostApi->openAsioDeviceIndex == paNoDevice ) 
    14321466    { 
    1433         result = LoadAsioDriver( asioHostApi->inheritedHostApiRep.deviceInfos[ asioDeviceIndex ]->name, 
     1467        result = LoadAsioDriver( asioHostApi, asioHostApi->inheritedHostApiRep.deviceInfos[ asioDeviceIndex ]->name, 
    14341468                driverInfo, asioHostApi->systemSpecific ); 
    14351469        if( result != paNoError ) 
     
    17631797        rather than the ones in our device info structure which may be stale */ 
    17641798 
    1765     result = LoadAsioDriver( asioHostApi->inheritedHostApiRep.deviceInfos[ asioDeviceIndex ]->name, 
     1799    result = LoadAsioDriver( asioHostApi, asioHostApi->inheritedHostApiRep.deviceInfos[ asioDeviceIndex ]->name, 
    17661800            driverInfo, asioHostApi->systemSpecific ); 
    17671801    if( result == paNoError ) 
     
    28972931    asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice]; 
    28982932 
    2899     if( !loadAsioDriver( const_cast<char*>(asioDeviceInfo->commonDeviceInfo.name) ) ) 
     2933    /* @todo note that the V18 version always called CoInitialize() here to ensure  
     2934        that COM was initialized before loading the driver.  
     2935        probably the docs need to require clients to initialize COM in new threads? 
     2936    */ 
     2937    if( !asioHostApi->asioDrivers->loadDriver( const_cast<char*>(asioDeviceInfo->commonDeviceInfo.name) ) ) 
    29002938    { 
    29012939        result = paUnanticipatedHostError;