zita-convolver: fix hang at when re-loading state

The convolver may be re-activated shortly after initialization
(e.g. session load, switching snapshots, or buffer-size.

In this case not all process threads may have started.
Convproc::stop_process() skips them (their state is still ST_IDLE).
Yet some short time later the thread's main function runs
and changes the state to ST_PROC, and check_stop () waits forever.

This is solved by waiting for all threads to start.
This commit is contained in:
Robin Gareus 2021-03-30 01:28:44 +02:00
parent f7ab563da0
commit cce1a67e75
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
2 changed files with 22 additions and 5 deletions

View File

@ -265,6 +265,16 @@ Convproc::start_process (int abspri, int policy)
for (k = (_minpart == _quantum) ? 1 : 0; k < _nlevels; k++) {
_convlev[k]->start (abspri, policy);
}
while (!check_started ((_minpart == _quantum) ? 1 : 0)) {
#ifdef _MSC_VER
Sleep (40);
#else
usleep (40000);
#endif
sched_yield ();
}
_state = ST_PROC;
return 0;
}
@ -352,10 +362,11 @@ Convproc::cleanup (void)
while (!check_stop ()) {
#ifdef _MSC_VER
Sleep (100);
Sleep (40);
#else
usleep (100000);
usleep (40000);
#endif
sched_yield ();
}
for (k = 0; k < _ninp; k++) {
delete[] _inpbuff[k];
@ -382,14 +393,19 @@ Convproc::cleanup (void)
return 0;
}
bool
Convproc::check_started (uint32_t k)
{
for (; (k < _nlevels) && (_convlev[k]->_stat == Convlevel::ST_PROC); k++) ;
return (k == _nlevels) ? true : false;
}
bool
Convproc::check_stop (void)
{
uint32_t k;
for (k = 0; (k < _nlevels) && (_convlev[k]->_stat == Convlevel::ST_IDLE); k++) {
;
}
for (k = 0; (k < _nlevels) && (_convlev[k]->_stat == Convlevel::ST_IDLE); k++) ;
if (k == _nlevels) {
_state = ST_STOP;
return true;

View File

@ -397,6 +397,7 @@ public:
int stop_process (void);
bool check_started (uint32_t);
bool check_stop (void);
int cleanup (void);