be1/qliquidsfz

LiquidSFZ::Synth usage not thread safe

Closed this issue · 3 comments

If you use a LiquidSFZ::Synth object, you need to ensure that only one thread at a time accesses it. Internally, no locking is performed to ensure this. So the problem with your implementation right now is that two threads can and do use the synth instance from different threads at the same time, namely

  • int LiquidMainWindow::process(jack_nframes_t nframes)
  • void SFZLoader::run()

As the process function is called in the jack thread and load can run for a long time in the loader thread, LiquidSFZ::Synth functions could be executed at the same time, for instance Synth::load and Synth::process, if you are unlucky this causes a crash.

There are probably multiple ways to fix this. Here is one:

I'd suggest using a mutex in the process function and in the loader thread to protect the synth instance. In a naive implementation this would stall the jack thread during load, which is unacceptable. So instead of locking the mutex during process(), I'd recommend using tryLock(). If you don't get the lock in process(), simply write a block of zero samples and return immediately.

be1 commented

Ok, I will fix this soon. Thank you for your report.

be1 commented

I did not test the fix in commit e9cf587 but i thing this is correct, following your suggestion. If not, feel free to re-open this bug.

be1 commented

Ooops, i did a big mistake. It is late in the night and my brain just thought upside-down... Instead of writings zeroes to Jack and not calling Synth::process, i wrote something inconsistent and pointless.
Reopening this bug and working on it now.