Commit ab614cdc authored by Guillaume Roguez's avatar Guillaume Roguez

alsalayer: fix too long blocking AlsaThread when joining it

AlsaThread calls AlsaLayer::openDevice() that may block 10s
if alsa device is busy. And this call is done 3 times!
It's a problem if it occures during thread join(), made at call hangup
for examble, blocking all the application until the thread die.

This patch reduces the timeout of openDevice to 2s and check
if thread exit is requested at each retry.

Issue: #75538
Change-Id: I3affa3869d039393677b57d2c9456f2ff1405264
parent b42da5db
......@@ -41,6 +41,7 @@
#include <thread>
#include <atomic>
#include <chrono>
namespace ring {
......@@ -180,15 +181,19 @@ bool AlsaLayer::openDevice(snd_pcm_t **pcm, const std::string &dev, snd_pcm_stre
{
RING_DBG("Alsa: Opening %s", dev.c_str());
static const int MAX_RETRIES = 100;
int err = snd_pcm_open(pcm, dev.c_str(), stream, 0);
// Retry if busy, since dmix plugin may not have released the device yet
for (int tries = 0; tries < MAX_RETRIES and err == -EBUSY; ++tries) {
const struct timespec req = {0, 100000000L};
nanosleep(&req, 0);
static const int MAX_RETRIES = 20; // times of 100ms
int err, tries = 0;
do {
err = snd_pcm_open(pcm, dev.c_str(), stream, 0);
}
// Retry if busy, since dmix plugin may not have released the device yet
if (err == -EBUSY) {
// We're called in audioThread_ context, so if exit is requested
// force return now
if (not audioThread_->isRunning())
return false;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
} while (err == -EBUSY and ++tries <= MAX_RETRIES);
if (err < 0) {
RING_ERR("Alsa: couldn't open device %s : %s", dev.c_str(),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment