Skip to content

Commit cad7908

Browse files
committed
ALSA: Free global configuration tree after each snd_ctl_close and snd_pcm_close (and therefore after successful open calls) to prevent memory leaks.
See https://github.com/alsa-project/alsa-lib/blob/master/MEMORY-LEAK
1 parent 7aba116 commit cad7908

File tree

1 file changed

+58
-6
lines changed

1 file changed

+58
-6
lines changed

RtAudio.cpp

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7897,13 +7897,15 @@ void RtApiAlsa :: probeDevices( void )
78977897
deviceID_prettyName.push_back({"default", "Default ALSA Device"});
78987898
defaultDeviceName = deviceID_prettyName[0].second;
78997899
snd_ctl_close( handle );
7900+
snd_config_update_free_global();
79007901
}
79017902

79027903
// Add the Pulse interface if available.
79037904
result = snd_ctl_open( &handle, "pulse", 0 );
79047905
if (result == 0) {
79057906
deviceID_prettyName.push_back({"pulse", "PulseAudio Sound Server"});
79067907
snd_ctl_close( handle );
7908+
snd_config_update_free_global();
79077909
}
79087910

79097911
// Count cards and devices and get ascii identifiers.
@@ -7966,8 +7968,10 @@ void RtApiAlsa :: probeDevices( void )
79667968
defaultDeviceName = name;
79677969
}
79687970
nextcard:
7969-
if ( handle )
7971+
if ( handle ) {
79707972
snd_ctl_close( handle );
7973+
snd_config_update_free_global();
7974+
}
79717975
snd_card_next( &card );
79727976
}
79737977

@@ -8066,6 +8070,7 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
80668070
result = snd_pcm_hw_params_any( phandle, params );
80678071
if ( result < 0 ) {
80688072
snd_pcm_close( phandle );
8073+
snd_config_update_free_global();
80698074
errorStream_ << "RtApiAlsa::probeDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << ".";
80708075
errorText_ = errorStream_.str();
80718076
error( RTAUDIO_WARNING );
@@ -8077,13 +8082,15 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
80778082
result = snd_pcm_hw_params_get_channels_max( params, &value );
80788083
if ( result < 0 ) {
80798084
snd_pcm_close( phandle );
8085+
snd_config_update_free_global();
80808086
errorStream_ << "RtApiAlsa::probeDeviceInfo: error getting device (" << name << ") output channels, " << snd_strerror( result ) << ".";
80818087
errorText_ = errorStream_.str();
80828088
error( RTAUDIO_WARNING );
80838089
goto captureProbe;
80848090
}
80858091
info.outputChannels = value;
80868092
snd_pcm_close( phandle );
8093+
snd_config_update_free_global();
80878094

80888095
captureProbe:
80898096
stream = SND_PCM_STREAM_CAPTURE;
@@ -8102,6 +8109,7 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
81028109
result = snd_pcm_hw_params_any( phandle, params );
81038110
if ( result < 0 ) {
81048111
snd_pcm_close( phandle );
8112+
snd_config_update_free_global();
81058113
errorStream_ << "RtApiAlsa::probeDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << ".";
81068114
errorText_ = errorStream_.str();
81078115
error( RTAUDIO_WARNING );
@@ -8112,6 +8120,7 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
81128120
result = snd_pcm_hw_params_get_channels_max( params, &value );
81138121
if ( result < 0 ) {
81148122
snd_pcm_close( phandle );
8123+
snd_config_update_free_global();
81158124
errorStream_ << "RtApiAlsa::probeDeviceInfo: error getting device (" << name << ") input channels, " << snd_strerror( result ) << ".";
81168125
errorText_ = errorStream_.str();
81178126
error( RTAUDIO_WARNING );
@@ -8120,6 +8129,7 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
81208129
}
81218130
info.inputChannels = value;
81228131
snd_pcm_close( phandle );
8132+
snd_config_update_free_global();
81238133

81248134
// If device opens for both playback and capture, we determine the channels.
81258135
if ( info.outputChannels > 0 && info.inputChannels > 0 )
@@ -8149,6 +8159,7 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
81498159
result = snd_pcm_hw_params_any( phandle, params );
81508160
if ( result < 0 ) {
81518161
snd_pcm_close( phandle );
8162+
snd_config_update_free_global();
81528163
errorStream_ << "RtApiAlsa::probeDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << ".";
81538164
errorText_ = errorStream_.str();
81548165
error( RTAUDIO_WARNING );
@@ -8167,6 +8178,7 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
81678178
}
81688179
if ( info.sampleRates.size() == 0 ) {
81698180
snd_pcm_close( phandle );
8181+
snd_config_update_free_global();
81708182
errorStream_ << "RtApiAlsa::probeDeviceInfo: no supported sample rates found for device (" << name << ").";
81718183
errorText_ = errorStream_.str();
81728184
error( RTAUDIO_WARNING );
@@ -8198,6 +8210,7 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
81988210
// Check that we have at least one supported format
81998211
if ( info.nativeFormats == 0 ) {
82008212
snd_pcm_close( phandle );
8213+
snd_config_update_free_global();
82018214
errorStream_ << "RtApiAlsa::probeDeviceInfo: pcm device (" << name << ") data format not supported by RtAudio.";
82028215
errorText_ = errorStream_.str();
82038216
error( RTAUDIO_WARNING );
@@ -8206,6 +8219,7 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
82068219

82078220
// Close the device and return
82088221
snd_pcm_close( phandle );
8222+
snd_config_update_free_global();
82098223
return true;
82108224
}
82118225

@@ -8256,6 +8270,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
82568270
result = snd_pcm_hw_params_any( phandle, hw_params );
82578271
if ( result < 0 ) {
82588272
snd_pcm_close( phandle );
8273+
snd_config_update_free_global();
82598274
errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting pcm device (" << name << ") parameters, " << snd_strerror( result ) << ".";
82608275
errorText_ = errorStream_.str();
82618276
return FAILURE;
@@ -8290,6 +8305,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
82908305

82918306
if ( result < 0 ) {
82928307
snd_pcm_close( phandle );
8308+
snd_config_update_free_global();
82938309
errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting pcm device (" << name << ") access, " << snd_strerror( result ) << ".";
82948310
errorText_ = errorStream_.str();
82958311
return FAILURE;
@@ -8356,6 +8372,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
83568372

83578373
// If we get here, no supported format was found.
83588374
snd_pcm_close( phandle );
8375+
snd_config_update_free_global();
83598376
errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device (" << name << ") data format not supported by RtAudio.";
83608377
errorText_ = errorStream_.str();
83618378
return FAILURE;
@@ -8364,6 +8381,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
83648381
result = snd_pcm_hw_params_set_format( phandle, hw_params, deviceFormat );
83658382
if ( result < 0 ) {
83668383
snd_pcm_close( phandle );
8384+
snd_config_update_free_global();
83678385
errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting pcm device (" << name << ") data format, " << snd_strerror( result ) << ".";
83688386
errorText_ = errorStream_.str();
83698387
return FAILURE;
@@ -8377,6 +8395,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
83778395
stream_.doByteSwap[mode] = true;
83788396
else if (result < 0) {
83798397
snd_pcm_close( phandle );
8398+
snd_config_update_free_global();
83808399
errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting pcm device (" << name << ") endian-ness, " << snd_strerror( result ) << ".";
83818400
errorText_ = errorStream_.str();
83828401
return FAILURE;
@@ -8387,6 +8406,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
83878406
result = snd_pcm_hw_params_set_rate_near( phandle, hw_params, (unsigned int*) &sampleRate, 0 );
83888407
if ( result < 0 ) {
83898408
snd_pcm_close( phandle );
8409+
snd_config_update_free_global();
83908410
errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting sample rate on device (" << name << "), " << snd_strerror( result ) << ".";
83918411
errorText_ = errorStream_.str();
83928412
return FAILURE;
@@ -8400,6 +8420,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
84008420
unsigned int deviceChannels = value;
84018421
if ( result < 0 || deviceChannels < channels + firstChannel ) {
84028422
snd_pcm_close( phandle );
8423+
snd_config_update_free_global();
84038424
errorStream_ << "RtApiAlsa::probeDeviceOpen: requested channel parameters not supported by device (" << name << "), " << snd_strerror( result ) << ".";
84048425
errorText_ = errorStream_.str();
84058426
return FAILURE;
@@ -8408,6 +8429,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
84088429
result = snd_pcm_hw_params_get_channels_min( hw_params, &value );
84098430
if ( result < 0 ) {
84108431
snd_pcm_close( phandle );
8432+
snd_config_update_free_global();
84118433
errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting minimum channels for device (" << name << "), " << snd_strerror( result ) << ".";
84128434
errorText_ = errorStream_.str();
84138435
return FAILURE;
@@ -8420,6 +8442,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
84208442
result = snd_pcm_hw_params_set_channels( phandle, hw_params, deviceChannels );
84218443
if ( result < 0 ) {
84228444
snd_pcm_close( phandle );
8445+
snd_config_update_free_global();
84238446
errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting channels for device (" << name << "), " << snd_strerror( result ) << ".";
84248447
errorText_ = errorStream_.str();
84258448
return FAILURE;
@@ -8431,6 +8454,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
84318454
result = snd_pcm_hw_params_set_period_size_near( phandle, hw_params, &periodSize, &dir );
84328455
if ( result < 0 ) {
84338456
snd_pcm_close( phandle );
8457+
snd_config_update_free_global();
84348458
errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting period size for device (" << name << "), " << snd_strerror( result ) << ".";
84358459
errorText_ = errorStream_.str();
84368460
return FAILURE;
@@ -8445,6 +8469,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
84458469
result = snd_pcm_hw_params_set_periods_near( phandle, hw_params, &periods, &dir );
84468470
if ( result < 0 ) {
84478471
snd_pcm_close( phandle );
8472+
snd_config_update_free_global();
84488473
errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting periods for device (" << name << "), " << snd_strerror( result ) << ".";
84498474
errorText_ = errorStream_.str();
84508475
return FAILURE;
@@ -8454,6 +8479,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
84548479
// MUST be the same in both directions!
84558480
if ( stream_.mode == OUTPUT && mode == INPUT && *bufferSize != stream_.bufferSize ) {
84568481
snd_pcm_close( phandle );
8482+
snd_config_update_free_global();
84578483
errorStream_ << "RtApiAlsa::probeDeviceOpen: system error setting buffer size for duplex stream on device (" << name << ").";
84588484
errorText_ = errorStream_.str();
84598485
return FAILURE;
@@ -8465,6 +8491,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
84658491
result = snd_pcm_hw_params( phandle, hw_params );
84668492
if ( result < 0 ) {
84678493
snd_pcm_close( phandle );
8494+
snd_config_update_free_global();
84688495
errorStream_ << "RtApiAlsa::probeDeviceOpen: error installing hardware configuration on device (" << name << "), " << snd_strerror( result ) << ".";
84698496
errorText_ = errorStream_.str();
84708497
return FAILURE;
@@ -8496,6 +8523,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
84968523
result = snd_pcm_sw_params( phandle, sw_params );
84978524
if ( result < 0 ) {
84988525
snd_pcm_close( phandle );
8526+
snd_config_update_free_global();
84998527
errorStream_ << "RtApiAlsa::probeDeviceOpen: error installing software configuration on device (" << name << "), " << snd_strerror( result ) << ".";
85008528
errorText_ = errorStream_.str();
85018529
return FAILURE;
@@ -8647,18 +8675,32 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
86478675
}
86488676
}
86498677

8678+
snd_config_update_free_global();
86508679
return SUCCESS;
86518680

86528681
error:
86538682
if ( apiInfo ) {
86548683
pthread_cond_destroy( &apiInfo->runnable_cv );
8655-
if ( apiInfo->handles[0] ) snd_pcm_close( apiInfo->handles[0] );
8656-
if ( apiInfo->handles[1] ) snd_pcm_close( apiInfo->handles[1] );
8684+
bool pcm_closed = false;
8685+
if ( apiInfo->handles[0] ) {
8686+
snd_pcm_close( apiInfo->handles[0] );
8687+
pcm_closed = true;
8688+
}
8689+
if ( apiInfo->handles[1] ) {
8690+
snd_pcm_close( apiInfo->handles[1] );
8691+
pcm_closed = true;
8692+
}
8693+
if ( pcm_closed ) {
8694+
snd_config_update_free_global();
8695+
}
86578696
delete apiInfo;
86588697
stream_.apiHandle = 0;
86598698
}
86608699

8661-
if ( phandle) snd_pcm_close( phandle );
8700+
if ( phandle) {
8701+
snd_pcm_close( phandle );
8702+
snd_config_update_free_global();
8703+
}
86628704

86638705
for ( int i=0; i<2; i++ ) {
86648706
if ( stream_.userBuffer[i] ) {
@@ -8704,8 +8746,18 @@ void RtApiAlsa :: closeStream()
87048746

87058747
if ( apiInfo ) {
87068748
pthread_cond_destroy( &apiInfo->runnable_cv );
8707-
if ( apiInfo->handles[0] ) snd_pcm_close( apiInfo->handles[0] );
8708-
if ( apiInfo->handles[1] ) snd_pcm_close( apiInfo->handles[1] );
8749+
bool pcm_closed = false;
8750+
if ( apiInfo->handles[0] ){
8751+
snd_pcm_close( apiInfo->handles[0] );
8752+
pcm_closed = true;
8753+
}
8754+
if ( apiInfo->handles[1] ){
8755+
snd_pcm_close( apiInfo->handles[1] );
8756+
pcm_closed = true;
8757+
}
8758+
if ( pcm_closed ) {
8759+
snd_config_update_free_global();
8760+
}
87098761
delete apiInfo;
87108762
stream_.apiHandle = 0;
87118763
}

0 commit comments

Comments
 (0)