mirror of
https://github.com/SFML/SFML.git
synced 2024-11-25 04:41:05 +08:00
Abort looping in SoundStream::streamData if an OpenAL error occurs that would have caused it to never terminate.
Backports #2026 and fixes #1831 for SFML 2
This commit is contained in:
parent
1f345d7d25
commit
c7d1112234
@ -27,6 +27,7 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Audio/ALCheck.hpp>
|
#include <SFML/Audio/ALCheck.hpp>
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
|
#include <SFML/System/ThreadLocalPtr.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
@ -37,6 +38,15 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// A nested named namespace is used here to allow unity builds of SFML.
|
||||||
|
namespace AlCheckImpl
|
||||||
|
{
|
||||||
|
sf::ThreadLocalPtr<ALenum> lastError(AL_NO_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
namespace priv
|
namespace priv
|
||||||
@ -49,6 +59,8 @@ void alCheckError(const char* file, unsigned int line, const char* expression)
|
|||||||
|
|
||||||
if (errorCode != AL_NO_ERROR)
|
if (errorCode != AL_NO_ERROR)
|
||||||
{
|
{
|
||||||
|
AlCheckImpl::lastError = &errorCode;
|
||||||
|
|
||||||
std::string fileString = file;
|
std::string fileString = file;
|
||||||
std::string error = "Unknown error";
|
std::string error = "Unknown error";
|
||||||
std::string description = "No description";
|
std::string description = "No description";
|
||||||
@ -101,6 +113,15 @@ void alCheckError(const char* file, unsigned int line, const char* expression)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
ALenum alGetLastErrorImpl()
|
||||||
|
{
|
||||||
|
ALenum lastError = AlCheckImpl::lastError ? *AlCheckImpl::lastError : AL_NO_ERROR;
|
||||||
|
AlCheckImpl::lastError = AL_NO_ERROR;
|
||||||
|
return lastError;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace priv
|
} // namespace priv
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
@ -55,11 +55,13 @@ namespace priv
|
|||||||
// If in debug mode, perform a test on every call
|
// If in debug mode, perform a test on every call
|
||||||
// The do-while loop is needed so that alCheck can be used as a single statement in if/else branches
|
// The do-while loop is needed so that alCheck can be used as a single statement in if/else branches
|
||||||
#define alCheck(expr) do { expr; sf::priv::alCheckError(__FILE__, __LINE__, #expr); } while (false)
|
#define alCheck(expr) do { expr; sf::priv::alCheckError(__FILE__, __LINE__, #expr); } while (false)
|
||||||
|
#define alGetLastError sf::priv::alGetLastErrorImpl
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// Else, we don't add any overhead
|
// Else, we don't add any overhead
|
||||||
#define alCheck(expr) (expr)
|
#define alCheck(expr) (expr)
|
||||||
|
#define alGetLastError alGetError
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -74,6 +76,15 @@ namespace priv
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void alCheckError(const char* file, unsigned int line, const char* expression);
|
void alCheckError(const char* file, unsigned int line, const char* expression);
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Get the last OpenAL error on this thread
|
||||||
|
///
|
||||||
|
/// \return The last OpenAL error on this thread
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
ALenum alGetLastErrorImpl();
|
||||||
|
|
||||||
} // namespace priv
|
} // namespace priv
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
@ -404,6 +404,15 @@ void SoundStream::streamData()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if any error has occurred
|
||||||
|
if (alGetLastError() != AL_NO_ERROR)
|
||||||
|
{
|
||||||
|
// Abort streaming (exit main loop)
|
||||||
|
Lock lock(m_threadMutex);
|
||||||
|
m_isStreaming = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Leave some time for the other threads if the stream is still playing
|
// Leave some time for the other threads if the stream is still playing
|
||||||
if (SoundSource::getStatus() != Stopped)
|
if (SoundSource::getStatus() != Stopped)
|
||||||
sleep(m_processingInterval);
|
sleep(m_processingInterval);
|
||||||
|
Loading…
Reference in New Issue
Block a user