mirror of https://github.com/axmolengine/axmol.git
fixed #16477: [android, audio] Deadlock if preload the same file more than 3 times in preload callback. (#16478)
And added test case.
This commit is contained in:
parent
35f937cd40
commit
01e67f6203
|
@ -210,16 +210,16 @@ void AudioPlayerProvider::preloadEffect(const std::string &audioFilePath, const
|
|||
return;
|
||||
}
|
||||
|
||||
_pcmCacheMutex.lock();
|
||||
auto&& iter = _pcmCache.find(audioFilePath);
|
||||
if (iter != _pcmCache.end())
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(_pcmCacheMutex);
|
||||
auto&& iter = _pcmCache.find(audioFilePath);
|
||||
if (iter != _pcmCache.end())
|
||||
{
|
||||
ALOGV("preload return from cache: (%s)", audioFilePath.c_str());
|
||||
cb(true, iter->second);
|
||||
return;
|
||||
}
|
||||
ALOGV("preload return from cache: (%s)", audioFilePath.c_str());
|
||||
_pcmCacheMutex.unlock();
|
||||
cb(true, iter->second);
|
||||
return;
|
||||
}
|
||||
_pcmCacheMutex.unlock();
|
||||
|
||||
auto info = getFileInfo(audioFilePath);
|
||||
preloadEffect(info, [this, cb, audioFilePath](bool succeed, PcmData data){
|
||||
|
@ -246,17 +246,17 @@ void AudioPlayerProvider::preloadEffect(const AudioFileInfo &info, const Preload
|
|||
{
|
||||
std::string audioFilePath = info.url;
|
||||
|
||||
// 1. First time check, if it wasn't in the cache, goto 2 step
|
||||
_pcmCacheMutex.lock();
|
||||
auto&& iter = _pcmCache.find(audioFilePath);
|
||||
if (iter != _pcmCache.end())
|
||||
{
|
||||
// 1. First time check, if it wasn't in the cache, goto 2 step
|
||||
std::lock_guard<std::mutex> lk(_pcmCacheMutex);
|
||||
auto&& iter = _pcmCache.find(audioFilePath);
|
||||
if (iter != _pcmCache.end())
|
||||
{
|
||||
ALOGV("1. Return pcm data from cache, url: %s", info.url.c_str());
|
||||
cb(true, iter->second);
|
||||
return;
|
||||
}
|
||||
ALOGV("1. Return pcm data from cache, url: %s", info.url.c_str());
|
||||
_pcmCacheMutex.unlock();
|
||||
cb(true, iter->second);
|
||||
return;
|
||||
}
|
||||
_pcmCacheMutex.unlock();
|
||||
|
||||
{
|
||||
// 2. Check whether the audio file is being preloaded, if it has been removed from map just now,
|
||||
|
@ -273,17 +273,19 @@ void AudioPlayerProvider::preloadEffect(const AudioFileInfo &info, const Preload
|
|||
return;
|
||||
}
|
||||
|
||||
{ // 3. Check it in cache again. If it has been removed from map just now, the file is in
|
||||
// the cache absolutely.
|
||||
std::lock_guard<std::mutex> lk2(_pcmCacheMutex);
|
||||
auto&& iter = _pcmCache.find(audioFilePath);
|
||||
if (iter != _pcmCache.end())
|
||||
{
|
||||
ALOGV("2. Return pcm data from cache, url: %s", info.url.c_str());
|
||||
cb(true, iter->second);
|
||||
return;
|
||||
}
|
||||
// 3. Check it in cache again. If it has been removed from map just now, the file is in
|
||||
// the cache absolutely.
|
||||
_pcmCacheMutex.lock();
|
||||
auto&& iter = _pcmCache.find(audioFilePath);
|
||||
if (iter != _pcmCache.end())
|
||||
{
|
||||
ALOGV("2. Return pcm data from cache, url: %s", info.url.c_str());
|
||||
_pcmCacheMutex.unlock();
|
||||
cb(true, iter->second);
|
||||
return;
|
||||
}
|
||||
_pcmCacheMutex.unlock();
|
||||
|
||||
|
||||
PreloadCallbackParam param;
|
||||
param.callback = cb;
|
||||
|
|
|
@ -43,6 +43,7 @@ AudioEngineTests::AudioEngineTests()
|
|||
ADD_TEST_CASE(AudioSwitchStateTest);
|
||||
ADD_TEST_CASE(AudioSmallFileTest);
|
||||
ADD_TEST_CASE(AudioPauseResumeAfterPlay);
|
||||
ADD_TEST_CASE(AudioPreloadSameFileMultipleTimes);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -189,7 +190,7 @@ AudioEngineTestDemo::AudioEngineTestDemo()
|
|||
void AudioEngineTestDemo::onExit()
|
||||
{
|
||||
*_isDestroyed = true;
|
||||
AudioEngine::stopAll();
|
||||
AudioEngine::uncacheAll();
|
||||
TestCase::onExit();
|
||||
}
|
||||
|
||||
|
@ -830,3 +831,32 @@ std::string AudioPauseResumeAfterPlay::subtitle() const
|
|||
{
|
||||
return "Should not crash";
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
void AudioPreloadSameFileMultipleTimes::onEnter()
|
||||
{
|
||||
AudioEngineTestDemo::onEnter();
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
AudioEngine::preload("audio/SoundEffectsFX009/FX082.mp3", [i](bool isSucceed){
|
||||
log("111: %d preload %s", i, isSucceed ? "succeed" : "failed");
|
||||
AudioEngine::preload("audio/SoundEffectsFX009/FX082.mp3", [i](bool isSucceed){
|
||||
log("222: %d preload %s", i, isSucceed ? "succeed" : "failed");
|
||||
AudioEngine::preload("audio/SoundEffectsFX009/FX082.mp3", [i](bool isSucceed){
|
||||
log("333: %d preload %s", i, isSucceed ? "succeed" : "failed");
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
std::string AudioPreloadSameFileMultipleTimes::title() const
|
||||
{
|
||||
return "Preload same file multiple times";
|
||||
}
|
||||
|
||||
std::string AudioPreloadSameFileMultipleTimes::subtitle() const
|
||||
{
|
||||
return "Should not crash";
|
||||
}
|
||||
|
|
|
@ -210,4 +210,15 @@ public:
|
|||
virtual std::string subtitle() const override;
|
||||
};
|
||||
|
||||
class AudioPreloadSameFileMultipleTimes : public AudioEngineTestDemo
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(AudioPreloadSameFileMultipleTimes);
|
||||
|
||||
virtual void onEnter() override;
|
||||
|
||||
virtual std::string title() const override;
|
||||
virtual std::string subtitle() const override;
|
||||
};
|
||||
|
||||
#endif /* defined(__NEWAUDIOENGINE_TEST_H_) */
|
||||
|
|
Loading…
Reference in New Issue