From f6419ed96a769c63e2ec03d8037edf5866bd16ad Mon Sep 17 00:00:00 2001 From: bsp2 Date: Sat, 27 Apr 2019 16:56:13 +0200 Subject: [PATCH] clean up + fix deadlock issue --- src/engine.cpp | 21 +++++++---------- src/vst2_main.cpp | 59 ++++++++++++++++++----------------------------- 2 files changed, 30 insertions(+), 50 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index 73997c40..454f1f6b 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -124,6 +124,7 @@ static void engineStep() { } } +#ifndef USE_VST2 static void engineRun() { #ifdef _MSC_VER // Set CPU to flush-to-zero (FTZ) and denormals-are-zero (DAZ) mode @@ -146,7 +147,6 @@ static void engineRun() { global->engine.vipMutex.wait(); if (!global->gPaused) { - // std::lock_guard lock(global->engine.mutex); std::lock_guard lock(global->engine.mutex); for (int i = 0; i < mutexSteps; i++) { engineStep(); @@ -179,11 +179,11 @@ void engineStop() { global->engine.running = false; global->engine.thread.join(); } +#endif // USE_VST2 void engineAddModule(Module *module) { assert(module); - VIPLock vipLock(global->engine.vipMutex); - // std::lock_guard lock(global->engine.mutex); + // // VIPLock vipLock(global->engine.vipMutex); std::lock_guard lock(global->engine.mutex); // Check that the module is not already added auto it = std::find(global->gModules.begin(), global->gModules.end(), module); @@ -197,8 +197,7 @@ void engineAddModule(Module *module) { void engineRemoveModule(Module *module) { assert(module); - VIPLock vipLock(global->engine.vipMutex); - // std::lock_guard lock(global->engine.mutex); + // // VIPLock vipLock(global->engine.vipMutex); std::lock_guard lock(global->engine.mutex); // If a param is being smoothed on this module, stop smoothing it immediately if (module == global->engine.smoothModule) { @@ -235,8 +234,7 @@ static void updateActive() { void engineAddWire(Wire *wire) { assert(wire); - VIPLock vipLock(global->engine.vipMutex); - // std::lock_guard lock(global->engine.mutex); + // // VIPLock vipLock(global->engine.vipMutex); std::lock_guard lock(global->engine.mutex); // Check wire properties assert(wire->outputModule); @@ -253,8 +251,7 @@ void engineAddWire(Wire *wire) { void engineRemoveWire(Wire *wire) { assert(wire); - VIPLock vipLock(global->engine.vipMutex); - // std::lock_guard lock(global->engine.mutex); + // // VIPLock vipLock(global->engine.vipMutex); std::lock_guard lock(global->engine.mutex); // Check that the wire is already added auto it = std::find(global->gWires.begin(), global->gWires.end(), wire); @@ -458,8 +455,7 @@ namespace rack { #endif // USE_VST2 void engineSetParamSmooth(Module *module, int paramId, float value) { - VIPLock vipLock(global->engine.vipMutex); - // std::lock_guard lock(global->engine.mutex); + // // VIPLock vipLock(global->engine.vipMutex); std::lock_guard lock(global->engine.mutex); // Since only one param can be smoothed at a time, if another param is currently being smoothed, skip to its final state if (global->engine.smoothModule && !(global->engine.smoothModule == module && global->engine.smoothParamId == paramId)) { @@ -471,8 +467,7 @@ void engineSetParamSmooth(Module *module, int paramId, float value) { } void engineSetSampleRate(float newSampleRate) { - VIPLock vipLock(global->engine.vipMutex); - // std::lock_guard lock(global->engine.mutex); + // // VIPLock vipLock(global->engine.vipMutex); std::lock_guard lock(global->engine.mutex); global->engine.sampleRate = newSampleRate; global->engine.sampleTime = 1.0 / global->engine.sampleRate; diff --git a/src/vst2_main.cpp b/src/vst2_main.cpp index 742adbad..1fd3b538 100644 --- a/src/vst2_main.cpp +++ b/src/vst2_main.cpp @@ -870,39 +870,27 @@ public: bool setSampleRate(float _rate, bool _bLock = true) { bool r = false; - // Dprintf("xxx setSampleRate: 1 bLock=%d\n", _bLock); + // Dprintf("xxx setSampleRate: ENTER bLock=%d\n", _bLock); if((_rate >= float(MIN_SAMPLE_RATE)) && (_rate <= float(MAX_SAMPLE_RATE))) { - // Dprintf("xxx setSampleRate: 2\n"); if(_bLock) { - // Dprintf("xxx setSampleRate: 2.1\n"); setGlobals(); - // Dprintf("xxx setSampleRate: 2.2\n"); lockAudio(); - // Dprintf("xxx setSampleRate: 2.3\n"); } sample_rate = _rate; - // Dprintf("xxx setSampleRate: 3\n"); - vst2_set_samplerate(sample_rate * oversample.factor); // see engine.cpp - // Dprintf("xxx setSampleRate: 4\n"); - destroyResamplerStates(); - // Dprintf("xxx setSampleRate: 5\n"); - // Lazy-alloc resampler state if(!Dfltequal(oversample.factor, 1.0f)) { int err; - // Dprintf("xxx setSampleRate: 6\n"); - oversample.srs_in = speex_resampler_init(NUM_INPUTS, sUI(sample_rate), // in rate sUI(sample_rate * oversample.factor), // out rate @@ -910,8 +898,6 @@ public: &err ); - // Dprintf("xxx setSampleRate: 7\n"); - oversample.srs_out = speex_resampler_init(NUM_OUTPUTS, sUI(sample_rate * oversample.factor), // in rate sUI(sample_rate), // out rate @@ -922,16 +908,11 @@ public: Dprintf("xxx vstrack_plugin: initialize speex resampler (rate=%f factor=%f quality=%d)\n", sample_rate, oversample.factor, oversample.quality); } - // Dprintf("xxx setSampleRate: 8\n"); - if(_bLock) { - // Dprintf("xxx setSampleRate: 8.1\n"); unlockAudio(); - // Dprintf("xxx setSampleRate: 8.2\n"); } - // Dprintf("xxx setSampleRate: 9\n"); r = true; } @@ -1067,8 +1048,10 @@ public: } sUI getProgramChunk(uint8_t**_addr) { + sUI r = 0; setGlobals(); vst2_set_shared_plugin_tls_globals(); + rack::global_ui->app.mtx_param.lock(); if(NULL != last_program_chunk_str) { ::free(last_program_chunk_str); @@ -1077,9 +1060,10 @@ public: if(NULL != last_program_chunk_str) { *_addr = (uint8_t*)last_program_chunk_str; - return (sUI)strlen(last_program_chunk_str) + 1/*ASCIIZ*/; + r = (sUI)strlen(last_program_chunk_str) + 1/*ASCIIZ*/; } - return 0; + rack::global_ui->app.mtx_param.unlock(); + return r; } bool setBankChunk(size_t _size, uint8_t *_addr) { @@ -1088,28 +1072,23 @@ public: } bool setProgramChunk(size_t _size, uint8_t *_addr) { - // Dprintf("xxx vstrack_plugin:setProgramChunk: 1\n"); + Dprintf("xxx vstrack_plugin:setProgramChunk: ENTER\n"); setGlobals(); - // Dprintf("xxx vstrack_plugin:setProgramChunk: 2\n"); + rack::global_ui->app.mtx_param.lock(); lockAudio(); - // Dprintf("xxx vstrack_plugin:setProgramChunk: 3\n"); vst2_set_shared_plugin_tls_globals(); - // Dprintf("xxx vstrack_plugin:setProgramChunk: 4\n"); - // std::lock_guard lock(rack::global->engine.mutex); - std::lock_guard lock(rack::global->engine.mutex); + rack::global->engine.mutex.lock(); #if 0 Dprintf("xxx vstrack_plugin:setProgramChunk: size=%u\n", _size); #endif lglw_glcontext_push(rack::global_ui->window.lglw); - // Dprintf("xxx vstrack_plugin:setProgramChunk: 5\n"); bool r = rack::global_ui->app.gRackWidget->loadPatchFromString((const char*)_addr); - // Dprintf("xxx vstrack_plugin:setProgramChunk: 6\n"); rack::global_ui->ui.gScene->step(); // w/o this the patch is bypassed - // Dprintf("xxx vstrack_plugin:setProgramChunk: 7\n"); lglw_glcontext_pop(rack::global_ui->window.lglw); - // Dprintf("xxx vstrack_plugin:setProgramChunk: 8 r=%d\n", r); + rack::global->engine.mutex.unlock(); unlockAudio(); - // Dprintf("xxx vstrack_plugin:setProgramChunk: 9\n"); + rack::global_ui->app.mtx_param.unlock(); + Dprintf("xxx vstrack_plugin:setProgramChunk: LEAVE\n"); return r; } @@ -1273,11 +1252,14 @@ void VSTPluginProcessReplacingFloat32(VSTPlugin *vstPlugin, // we can get a hold to our C++ class since we stored it in the `object` field (see constructor) VSTPluginWrapper *wrapper = static_cast(vstPlugin->object); // Dprintf("xxx vstrack_plugin: VSTPluginProcessReplacingFloat32: ENTER\n"); - - wrapper->lockAudio(); + wrapper->setGlobals(); vst2_set_shared_plugin_tls_globals(); + vst2_handle_queued_params(); + + wrapper->lockAudio(); + if(wrapper->b_check_offline) { // Check if offline rendering state changed and update resampler when necessary @@ -1287,7 +1269,6 @@ void VSTPluginProcessReplacingFloat32(VSTPlugin *vstPlugin, // // rack::global->engine.vipMutex.lock(); rack::global->engine.mutex.lock(); rack::global->vst2.last_seen_num_frames = sUI(sampleFrames); - vst2_handle_queued_params(); //Dprintf("xxx vstrack_plugin: VSTPluginProcessReplacingFloat32: lockAudio done\n"); @@ -2131,9 +2112,13 @@ float VSTPluginGetParameter(VSTPlugin *vstPlugin, // we can get a hold to our C++ class since we stored it in the `object` field (see constructor) VSTPluginWrapper *wrapper = static_cast(vstPlugin->object); - wrapper->lockAudio(); // don't query a param while the module is deleted wrapper->setGlobals(); + wrapper->lockAudio(); + rack::global->engine.mutex.lock(); // don't query a param while a module is being deleted + float r = vst2_get_param(index); + + rack::global->engine.mutex.unlock(); wrapper->unlockAudio(); return r;