From cce1a67e75e9e4031edd70f433f295089deb0010 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Tue, 30 Mar 2021 01:28:44 +0200 Subject: [PATCH] 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. --- libs/zita-convolver/zita-convolver.cc | 26 +++++++++++++++---- .../zita-convolver/zita-convolver.h | 1 + 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/libs/zita-convolver/zita-convolver.cc b/libs/zita-convolver/zita-convolver.cc index 96a00c05d5..3b2473b854 100644 --- a/libs/zita-convolver/zita-convolver.cc +++ b/libs/zita-convolver/zita-convolver.cc @@ -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; diff --git a/libs/zita-convolver/zita-convolver/zita-convolver.h b/libs/zita-convolver/zita-convolver/zita-convolver.h index 81fa0c8321..74f8e41c5b 100644 --- a/libs/zita-convolver/zita-convolver/zita-convolver.h +++ b/libs/zita-convolver/zita-convolver/zita-convolver.h @@ -397,6 +397,7 @@ public: int stop_process (void); + bool check_started (uint32_t); bool check_stop (void); int cleanup (void);