mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 17:58:43 +02:00
fix thread cleanup of audio pool
This commit is contained in:
parent
d2ed3caf02
commit
ce9346f524
2 changed files with 32 additions and 18 deletions
|
@ -15,8 +15,8 @@
|
||||||
#include "AudioMixerSlavePool.h"
|
#include "AudioMixerSlavePool.h"
|
||||||
|
|
||||||
void AudioMixerSlaveThread::run() {
|
void AudioMixerSlaveThread::run() {
|
||||||
while (!_stop) {
|
while (true) {
|
||||||
wait(); // for the audio pool to notify
|
wait();
|
||||||
|
|
||||||
// iterate over all available nodes
|
// iterate over all available nodes
|
||||||
SharedNodePointer node;
|
SharedNodePointer node;
|
||||||
|
@ -24,7 +24,11 @@ void AudioMixerSlaveThread::run() {
|
||||||
mix(node);
|
mix(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
notify(); // the audio pool we are done
|
bool stopping = _stop;
|
||||||
|
notify(stopping);
|
||||||
|
if (stopping) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,11 +44,14 @@ void AudioMixerSlaveThread::wait() {
|
||||||
configure(_pool._begin, _pool._end, _pool._frame);
|
configure(_pool._begin, _pool._end, _pool._frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioMixerSlaveThread::notify() {
|
void AudioMixerSlaveThread::notify(bool stopping) {
|
||||||
{
|
{
|
||||||
Lock lock(_pool._mutex);
|
Lock lock(_pool._mutex);
|
||||||
assert(_pool._numFinished < _pool._numThreads);
|
assert(_pool._numFinished < _pool._numThreads);
|
||||||
++_pool._numFinished;
|
++_pool._numFinished;
|
||||||
|
if (stopping) {
|
||||||
|
++_pool._numStopped;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_pool._poolCondition.notify_one();
|
_pool._poolCondition.notify_one();
|
||||||
}
|
}
|
||||||
|
@ -139,18 +146,28 @@ void AudioMixerSlavePool::resize(int numThreads) {
|
||||||
} else if (numThreads < _numThreads) {
|
} else if (numThreads < _numThreads) {
|
||||||
auto extraBegin = _slaves.begin() + numThreads;
|
auto extraBegin = _slaves.begin() + numThreads;
|
||||||
|
|
||||||
// stop extra slaves...
|
// mark slaves to stop...
|
||||||
auto slave = extraBegin;
|
auto slave = extraBegin;
|
||||||
while (slave != _slaves.end()) {
|
while (slave != _slaves.end()) {
|
||||||
(*slave)->stop();
|
(*slave)->_stop = true;
|
||||||
++slave;
|
++slave;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...cycle slaves with empty queue...
|
// ...cycle them until they do stop...
|
||||||
_numStarted = _numFinished = 0;
|
{
|
||||||
_slaveCondition.notify_all();
|
Lock lock(_mutex);
|
||||||
|
_numStopped = 0;
|
||||||
|
while (_numStopped != (_numThreads - numThreads)) {
|
||||||
|
_numStarted = _numFinished = _numStopped;
|
||||||
|
_slaveCondition.notify_all();
|
||||||
|
_poolCondition.wait(lock, [&] {
|
||||||
|
assert(_numFinished <= _numThreads);
|
||||||
|
return _numFinished == _numThreads;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ...wait for them to finish...
|
// ...wait for threads to finish...
|
||||||
slave = extraBegin;
|
slave = extraBegin;
|
||||||
while (slave != _slaves.end()) {
|
while (slave != _slaves.end()) {
|
||||||
QThread* thread = reinterpret_cast<QThread*>(slave->get());
|
QThread* thread = reinterpret_cast<QThread*>(slave->get());
|
||||||
|
@ -159,7 +176,7 @@ void AudioMixerSlavePool::resize(int numThreads) {
|
||||||
++slave;
|
++slave;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...and delete them
|
// ...and erase them
|
||||||
_slaves.erase(extraBegin, _slaves.end());
|
_slaves.erase(extraBegin, _slaves.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,20 +34,16 @@ public:
|
||||||
AudioMixerSlaveThread(AudioMixerSlavePool& pool) : _pool(pool) {}
|
AudioMixerSlaveThread(AudioMixerSlavePool& pool) : _pool(pool) {}
|
||||||
|
|
||||||
void run() override final;
|
void run() override final;
|
||||||
void stop() { _stop = true; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class AudioMixerSlavePool;
|
friend class AudioMixerSlavePool;
|
||||||
|
|
||||||
void wait();
|
void wait();
|
||||||
void notify();
|
void notify(bool stopping);
|
||||||
bool try_pop(SharedNodePointer& node);
|
bool try_pop(SharedNodePointer& node);
|
||||||
|
|
||||||
// frame state
|
|
||||||
AudioMixerSlavePool& _pool;
|
AudioMixerSlavePool& _pool;
|
||||||
|
bool _stop;
|
||||||
// synchronization state
|
|
||||||
std::atomic<bool> _stop;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Slave pool for audio mixers
|
// Slave pool for audio mixers
|
||||||
|
@ -79,7 +75,7 @@ private:
|
||||||
std::vector<std::unique_ptr<AudioMixerSlaveThread>> _slaves;
|
std::vector<std::unique_ptr<AudioMixerSlaveThread>> _slaves;
|
||||||
|
|
||||||
friend void AudioMixerSlaveThread::wait();
|
friend void AudioMixerSlaveThread::wait();
|
||||||
friend void AudioMixerSlaveThread::notify();
|
friend void AudioMixerSlaveThread::notify(bool stopping);
|
||||||
friend bool AudioMixerSlaveThread::try_pop(SharedNodePointer& node);
|
friend bool AudioMixerSlaveThread::try_pop(SharedNodePointer& node);
|
||||||
|
|
||||||
// synchronization state
|
// synchronization state
|
||||||
|
@ -89,6 +85,7 @@ private:
|
||||||
int _numThreads { 0 };
|
int _numThreads { 0 };
|
||||||
int _numStarted { 0 }; // guarded by _mutex
|
int _numStarted { 0 }; // guarded by _mutex
|
||||||
int _numFinished { 0 }; // guarded by _mutex
|
int _numFinished { 0 }; // guarded by _mutex
|
||||||
|
int _numStopped { 0 }; // guarded by _mutex
|
||||||
|
|
||||||
// frame state
|
// frame state
|
||||||
Queue _queue;
|
Queue _queue;
|
||||||
|
|
Loading…
Reference in a new issue