mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 09:53:59 +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
assignment-client/src/audio
|
@ -15,8 +15,8 @@
|
|||
#include "AudioMixerSlavePool.h"
|
||||
|
||||
void AudioMixerSlaveThread::run() {
|
||||
while (!_stop) {
|
||||
wait(); // for the audio pool to notify
|
||||
while (true) {
|
||||
wait();
|
||||
|
||||
// iterate over all available nodes
|
||||
SharedNodePointer node;
|
||||
|
@ -24,7 +24,11 @@ void AudioMixerSlaveThread::run() {
|
|||
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);
|
||||
}
|
||||
|
||||
void AudioMixerSlaveThread::notify() {
|
||||
void AudioMixerSlaveThread::notify(bool stopping) {
|
||||
{
|
||||
Lock lock(_pool._mutex);
|
||||
assert(_pool._numFinished < _pool._numThreads);
|
||||
++_pool._numFinished;
|
||||
if (stopping) {
|
||||
++_pool._numStopped;
|
||||
}
|
||||
}
|
||||
_pool._poolCondition.notify_one();
|
||||
}
|
||||
|
@ -139,18 +146,28 @@ void AudioMixerSlavePool::resize(int numThreads) {
|
|||
} else if (numThreads < _numThreads) {
|
||||
auto extraBegin = _slaves.begin() + numThreads;
|
||||
|
||||
// stop extra slaves...
|
||||
// mark slaves to stop...
|
||||
auto slave = extraBegin;
|
||||
while (slave != _slaves.end()) {
|
||||
(*slave)->stop();
|
||||
(*slave)->_stop = true;
|
||||
++slave;
|
||||
}
|
||||
|
||||
// ...cycle slaves with empty queue...
|
||||
_numStarted = _numFinished = 0;
|
||||
_slaveCondition.notify_all();
|
||||
// ...cycle them until they do stop...
|
||||
{
|
||||
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;
|
||||
while (slave != _slaves.end()) {
|
||||
QThread* thread = reinterpret_cast<QThread*>(slave->get());
|
||||
|
@ -159,7 +176,7 @@ void AudioMixerSlavePool::resize(int numThreads) {
|
|||
++slave;
|
||||
}
|
||||
|
||||
// ...and delete them
|
||||
// ...and erase them
|
||||
_slaves.erase(extraBegin, _slaves.end());
|
||||
}
|
||||
|
||||
|
|
|
@ -34,20 +34,16 @@ public:
|
|||
AudioMixerSlaveThread(AudioMixerSlavePool& pool) : _pool(pool) {}
|
||||
|
||||
void run() override final;
|
||||
void stop() { _stop = true; }
|
||||
|
||||
private:
|
||||
friend class AudioMixerSlavePool;
|
||||
|
||||
void wait();
|
||||
void notify();
|
||||
void notify(bool stopping);
|
||||
bool try_pop(SharedNodePointer& node);
|
||||
|
||||
// frame state
|
||||
AudioMixerSlavePool& _pool;
|
||||
|
||||
// synchronization state
|
||||
std::atomic<bool> _stop;
|
||||
bool _stop;
|
||||
};
|
||||
|
||||
// Slave pool for audio mixers
|
||||
|
@ -79,7 +75,7 @@ private:
|
|||
std::vector<std::unique_ptr<AudioMixerSlaveThread>> _slaves;
|
||||
|
||||
friend void AudioMixerSlaveThread::wait();
|
||||
friend void AudioMixerSlaveThread::notify();
|
||||
friend void AudioMixerSlaveThread::notify(bool stopping);
|
||||
friend bool AudioMixerSlaveThread::try_pop(SharedNodePointer& node);
|
||||
|
||||
// synchronization state
|
||||
|
@ -89,6 +85,7 @@ private:
|
|||
int _numThreads { 0 };
|
||||
int _numStarted { 0 }; // guarded by _mutex
|
||||
int _numFinished { 0 }; // guarded by _mutex
|
||||
int _numStopped { 0 }; // guarded by _mutex
|
||||
|
||||
// frame state
|
||||
Queue _queue;
|
||||
|
|
Loading…
Reference in a new issue