diff --git a/CMakeLists.txt b/CMakeLists.txt index 88aefadae8d..dc2552bc7a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -483,6 +483,17 @@ ENDIF(WANT_DEBUG_FPE) # check for libsamplerate FIND_PACKAGE(Samplerate 0.1.8 MODULE REQUIRED) +#check for presence of mutex +SET(CMAKE_REQUIRED_FLAGS "-std=c++11") + +CHECK_CXX_SOURCE_COMPILES(" +#include +int main(int argc, const char* argv[]) { + std::mutex m; + return 0; +} +" HAS_STD_MUTEX) + # set compiler flags IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") SET(WERROR_FLAGS "-Wall -Werror=unused-function -Wno-sign-compare -Wno-strict-overflow") diff --git a/include/RemotePlugin.h b/include/RemotePlugin.h index 99160a96704..3aa75d3c41d 100644 --- a/include/RemotePlugin.h +++ b/include/RemotePlugin.h @@ -49,7 +49,6 @@ #include #endif - #ifdef LMMS_HAVE_SYS_SHM_H #include @@ -93,6 +92,13 @@ typedef int32_t key_t; #include #include +#ifdef USE_MINGW_THREADS_REPLACEMENT +# include +#else +# include +# include +#endif + #ifndef SYNC_WITH_SHM_FIFO #include #include @@ -649,7 +655,7 @@ class LMMS_EXPORT RemotePluginBase } #endif - inline void invalidate() + virtual void invalidate() { #ifdef SYNC_WITH_SHM_FIFO m_in->invalidate(); @@ -805,27 +811,34 @@ class LMMS_EXPORT RemotePlugin : public QObject, public RemotePluginBase void updateSampleRate( sample_rate_t _sr ) { - lock(); - sendMessage( message( IdSampleRateInformation ).addInt( _sr ) ); - waitForMessage( IdInformationUpdated, true ); - unlock(); + if (try_lock()) + { + sendMessage(message(IdSampleRateInformation).addInt(_sr)); + waitForMessage(IdInformationUpdated, true); + unlock(); + } } virtual void toggleUI() { - lock(); - sendMessage( IdToggleUI ); - unlock(); + if (try_lock()) + { + sendMessage(IdToggleUI); + unlock(); + } } int isUIVisible() { - lock(); - sendMessage( IdIsUIVisible ); - unlock(); - message m = waitForMessage( IdIsUIVisible ); - return m.id != IdIsUIVisible ? -1 : m.getInt() ? 1 : 0; + if (try_lock()) { + sendMessage(IdIsUIVisible); + unlock(); + message m = waitForMessage(IdIsUIVisible); + return m.id != IdIsUIVisible ? -1 : m.getInt() ? 1 : 0; + } + + return 0; } inline bool failed() const @@ -833,9 +846,21 @@ class LMMS_EXPORT RemotePlugin : public QObject, public RemotePluginBase return m_failed; } - inline void lock() + inline bool try_lock() { - m_commMutex.lock(); + if (!m_disconnected) + { + if (!m_commMutex.try_lock_for(std::chrono::milliseconds(1000))) + { + m_failed = true; + m_disconnected = true; + invalidate(); + return false; + } + return true; + } + else + return false; } inline void unlock() @@ -848,6 +873,13 @@ public slots: virtual void hideUI(); protected: + virtual void invalidate() override + { + m_watcher.quit(); + m_process.kill(); + RemotePluginBase::invalidate(); + } + inline void setSplittedChannels( bool _on ) { m_splitChannels = _on; @@ -857,12 +889,12 @@ public slots: bool m_failed; private: void resizeSharedProcessingMemory(); - + bool m_disconnected; QProcess m_process; ProcessWatcher m_watcher; - QMutex m_commMutex; + std::recursive_timed_mutex m_commMutex; bool m_splitChannels; #ifdef USE_QT_SHMEM QSharedMemory m_shmObj; diff --git a/plugins/VstEffect/CMakeLists.txt b/plugins/VstEffect/CMakeLists.txt index 68ef141d984..1771efccdbf 100644 --- a/plugins/VstEffect/CMakeLists.txt +++ b/plugins/VstEffect/CMakeLists.txt @@ -12,6 +12,11 @@ ENDIF() BUILD_PLUGIN(vsteffect VstEffect.cpp VstEffectControls.cpp VstEffectControlDialog.cpp VstSubPluginFeatures.cpp VstEffect.h VstEffectControls.h VstEffectControlDialog.h VstSubPluginFeatures.h MOCFILES VstEffectControlDialog.h VstEffectControls.h EMBEDDED_RESOURCES *.png) TARGET_LINK_LIBRARIES(vsteffect vstbase) - +IF(NOT HAS_STD_MUTEX) + target_include_directories(vsteffect PRIVATE + "${PROJECT_SOURCE_DIR}/src/3rdparty/mingw-std-threads") + target_compile_definitions(vsteffect PRIVATE + -DUSE_MINGW_THREADS_REPLACEMENT) +ENDIF() ENDIF(LMMS_SUPPORT_VST) diff --git a/plugins/vestige/CMakeLists.txt b/plugins/vestige/CMakeLists.txt index 823c032020a..5386589203c 100644 --- a/plugins/vestige/CMakeLists.txt +++ b/plugins/vestige/CMakeLists.txt @@ -10,5 +10,12 @@ IF(LMMS_SUPPORT_VST) ENDIF() BUILD_PLUGIN(vestige vestige.cpp vestige.h MOCFILES vestige.h EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png") TARGET_LINK_LIBRARIES(vestige vstbase) + + IF(NOT HAS_STD_MUTEX) + target_include_directories(vestige PRIVATE + "${PROJECT_SOURCE_DIR}/src/3rdparty/mingw-std-threads") + target_compile_definitions(vestige PRIVATE + -DUSE_MINGW_THREADS_REPLACEMENT) + ENDIF() ENDIF(LMMS_SUPPORT_VST) diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 5138a58a69d..093bb3e0668 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -193,11 +193,11 @@ void VstPlugin::tryLoad( const QString &remoteVstPluginExecutable ) return; } - lock(); - - VstHostLanguages hlang = LanguageEnglish; - switch( QLocale::system().language() ) + if (try_lock()) { + VstHostLanguages hlang = LanguageEnglish; + switch (QLocale::system().language()) + { case QLocale::French: hlang = LanguageFrench; break; case QLocale::German: hlang = LanguageGerman; break; case QLocale::Italian: hlang = LanguageItalian; break; @@ -205,13 +205,14 @@ void VstPlugin::tryLoad( const QString &remoteVstPluginExecutable ) case QLocale::Korean: hlang = LanguageKorean; break; case QLocale::Spanish: hlang = LanguageSpanish; break; default: break; - } - sendMessage( message( IdVstSetLanguage ).addInt( hlang ) ); - sendMessage( message( IdVstLoadPlugin ).addString( QSTR_TO_STDSTR( m_plugin ) ) ); + } + sendMessage(message(IdVstSetLanguage).addInt(hlang)); + sendMessage(message(IdVstLoadPlugin).addString(QSTR_TO_STDSTR(m_plugin))); - waitForInitDone(); + waitForInitDone(); - unlock(); + unlock(); + } } @@ -305,9 +306,11 @@ void VstPlugin::toggleUI() void VstPlugin::setTempo( bpm_t _bpm ) { - lock(); - sendMessage( message( IdVstSetTempo ).addInt( _bpm ) ); - unlock(); + if (try_lock()) + { + sendMessage(message(IdVstSetTempo).addInt(_bpm)); + unlock(); + } } @@ -315,11 +318,13 @@ void VstPlugin::setTempo( bpm_t _bpm ) void VstPlugin::updateSampleRate() { - lock(); - sendMessage( message( IdSampleRateInformation ). - addInt( Engine::mixer()->processingSampleRate() ) ); - waitForMessage( IdInformationUpdated, true ); - unlock(); + if (try_lock()) + { + sendMessage(message(IdSampleRateInformation). + addInt(Engine::mixer()->processingSampleRate())); + waitForMessage(IdInformationUpdated, true); + unlock(); + } } @@ -327,11 +332,12 @@ void VstPlugin::updateSampleRate() int VstPlugin::currentProgram() { - lock(); - sendMessage( message( IdVstCurrentProgram ) ); - waitForMessage( IdVstCurrentProgram, true ); - unlock(); - + if (try_lock()) + { + sendMessage(message(IdVstCurrentProgram)); + waitForMessage(IdVstCurrentProgram, true); + unlock(); + } return m_currentProgram; } @@ -339,11 +345,12 @@ int VstPlugin::currentProgram() const QMap & VstPlugin::parameterDump() { - lock(); - sendMessage( IdVstGetParameterDump ); - waitForMessage( IdVstParameterDump, true ); - unlock(); - + if (try_lock()) + { + sendMessage(IdVstGetParameterDump); + waitForMessage(IdVstParameterDump, true); + unlock(); + } return m_parameterDump; } @@ -367,9 +374,11 @@ void VstPlugin::setParameterDump( const QMap & _pdump ) m.addString( item.shortLabel ); m.addFloat( item.value ); } - lock(); - sendMessage( m ); - unlock(); + if (try_lock()) + { + sendMessage(m); + unlock(); + } } QWidget *VstPlugin::pluginWidget() @@ -391,9 +400,9 @@ bool VstPlugin::processMessage( const message & _m ) #ifdef LMMS_BUILD_WIN32 // We're changing the owner, not the parent, // so this is legal despite MSDN's warning - SetWindowLongPtr( (HWND)(intptr_t) m_pluginWindowID, - GWLP_HWNDPARENT, - (LONG_PTR) gui->mainWindow()->winId() ); + //SetWindowLongPtr( (HWND)(intptr_t) m_pluginWindowID, + // GWLP_HWNDPARENT, + // (LONG_PTR) gui->mainWindow()->winId() ); #endif #ifdef LMMS_BUILD_LINUX @@ -483,14 +492,16 @@ void VstPlugin::openPreset( ) if( ofd.exec () == QDialog::Accepted && !ofd.selectedFiles().isEmpty() ) { - lock(); - sendMessage( message( IdLoadPresetFile ). - addString( - QSTR_TO_STDSTR( - QDir::toNativeSeparators( ofd.selectedFiles()[0] ) ) ) + if (try_lock()) + { + sendMessage(message(IdLoadPresetFile). + addString( + QSTR_TO_STDSTR( + QDir::toNativeSeparators(ofd.selectedFiles()[0]))) ); - waitForMessage( IdLoadPresetFile, true ); - unlock(); + waitForMessage(IdLoadPresetFile, true); + unlock(); + } } } @@ -499,10 +510,12 @@ void VstPlugin::openPreset( ) void VstPlugin::setProgram( int index ) { - lock(); - sendMessage( message( IdVstSetProgram ).addInt( index ) ); - waitForMessage( IdVstSetProgram, true ); - unlock(); + if (try_lock()) + { + sendMessage(message(IdVstSetProgram).addInt(index)); + waitForMessage(IdVstSetProgram, true); + unlock(); + } } @@ -510,10 +523,12 @@ void VstPlugin::setProgram( int index ) void VstPlugin::rotateProgram( int offset ) { - lock(); - sendMessage( message( IdVstRotateProgram ).addInt( offset ) ); - waitForMessage( IdVstRotateProgram, true ); - unlock(); + if (try_lock()) + { + sendMessage(message(IdVstRotateProgram).addInt(offset)); + waitForMessage(IdVstRotateProgram, true); + unlock(); + } } @@ -521,10 +536,12 @@ void VstPlugin::rotateProgram( int offset ) void VstPlugin::loadProgramNames() { - lock(); - sendMessage( message( IdVstProgramNames ) ); - waitForMessage( IdVstProgramNames, true ); - unlock(); + if (try_lock()) + { + sendMessage(message(IdVstProgramNames)); + waitForMessage(IdVstProgramNames, true); + unlock(); + } } @@ -554,14 +571,16 @@ void VstPlugin::savePreset( ) if ((fns.toUpper().indexOf(tr(".FXP")) == -1) && (fns.toUpper().indexOf(tr(".FXB")) == -1)) fns = fns + tr(".fxb"); else fns = fns.left(fns.length() - 4) + (fns.right( 4 )).toLower(); - lock(); - sendMessage( message( IdSavePresetFile ). - addString( - QSTR_TO_STDSTR( - QDir::toNativeSeparators( fns ) ) ) + if (try_lock()) + { + sendMessage(message(IdSavePresetFile). + addString( + QSTR_TO_STDSTR( + QDir::toNativeSeparators(fns))) ); - waitForMessage( IdSavePresetFile, true ); - unlock(); + waitForMessage(IdSavePresetFile, true); + unlock(); + } } } @@ -570,19 +589,23 @@ void VstPlugin::savePreset( ) void VstPlugin::setParam( int i, float f ) { - lock(); - sendMessage( message( IdVstSetParameter ).addInt( i ).addFloat( f ) ); - //waitForMessage( IdVstSetParameter, true ); - unlock(); + if (try_lock()) + { + sendMessage(message(IdVstSetParameter).addInt(i).addFloat(f)); + //waitForMessage( IdVstSetParameter, true ); + unlock(); + } } void VstPlugin::idleUpdate() { - lock(); - sendMessage( message( IdVstIdleUpdate ) ); - unlock(); + if (try_lock()) + { + sendMessage(message(IdVstIdleUpdate)); + unlock(); + } } void VstPlugin::showUI() @@ -615,13 +638,13 @@ void VstPlugin::hideUI() // X11Embed only void VstPlugin::handleClientEmbed() { - lock(); - sendMessage( IdShowUI ); - unlock(); + if (try_lock()) + { + sendMessage(IdShowUI); + unlock(); + } } - - void VstPlugin::loadChunk( const QByteArray & _chunk ) { QTemporaryFile tf; @@ -630,14 +653,16 @@ void VstPlugin::loadChunk( const QByteArray & _chunk ) tf.write( _chunk ); tf.flush(); - lock(); - sendMessage( message( IdLoadSettingsFromFile ). + if (try_lock()) + { + sendMessage(message(IdLoadSettingsFromFile). addString( QSTR_TO_STDSTR( - QDir::toNativeSeparators( tf.fileName() ) ) ). - addInt( _chunk.size() ) ); - waitForMessage( IdLoadSettingsFromFile, true ); - unlock(); + QDir::toNativeSeparators(tf.fileName()))). + addInt(_chunk.size())); + waitForMessage(IdLoadSettingsFromFile, true); + unlock(); + } } } @@ -650,14 +675,16 @@ QByteArray VstPlugin::saveChunk() QTemporaryFile tf; if( tf.open() ) { - lock(); - sendMessage( message( IdSaveSettingsToFile ). + if (try_lock()) + { + sendMessage(message(IdSaveSettingsToFile). addString( QSTR_TO_STDSTR( - QDir::toNativeSeparators( tf.fileName() ) ) ) ); - waitForMessage( IdSaveSettingsToFile, true ); - unlock(); - a = tf.readAll(); + QDir::toNativeSeparators(tf.fileName())))); + waitForMessage(IdSaveSettingsToFile, true); + unlock(); + a = tf.readAll(); + } } return a; diff --git a/plugins/vst_base/vstbase/CMakeLists.txt b/plugins/vst_base/vstbase/CMakeLists.txt index 28c09edb380..50e58e42f0b 100644 --- a/plugins/vst_base/vstbase/CMakeLists.txt +++ b/plugins/vst_base/vstbase/CMakeLists.txt @@ -4,10 +4,15 @@ BUILD_PLUGIN(vstbase EXPORT_BASE_NAME vstbase LINK SHARED ) - TARGET_INCLUDE_DIRECTORIES(vstbase PUBLIC ../ ) +IF(NOT HAS_STD_MUTEX) + target_include_directories(vstbase PRIVATE + "${PROJECT_SOURCE_DIR}/src/3rdparty/mingw-std-threads") + target_compile_definitions(vstbase PRIVATE + -DUSE_MINGW_THREADS_REPLACEMENT) +ENDIF() IF(LMMS_BUILD_LINUX) TARGET_LINK_LIBRARIES(vstbase qx11embedcontainer) diff --git a/plugins/zynaddsubfx/CMakeLists.txt b/plugins/zynaddsubfx/CMakeLists.txt index e083a30a976..63cfd3696da 100644 --- a/plugins/zynaddsubfx/CMakeLists.txt +++ b/plugins/zynaddsubfx/CMakeLists.txt @@ -147,6 +147,13 @@ BUILD_PLUGIN(zynaddsubfx ZynAddSubFx.cpp ZynAddSubFx.h MOCFILES ZynAddSubFx.h EM TARGET_LINK_LIBRARIES(zynaddsubfx -lZynAddSubFxCore) ADD_DEPENDENCIES(zynaddsubfx ZynAddSubFxCore) +IF(NOT HAS_STD_MUTEX) + target_include_directories(zynaddsubfx PRIVATE + "${PROJECT_SOURCE_DIR}/src/3rdparty/mingw-std-threads") + target_compile_definitions(zynaddsubfx PRIVATE + -DUSE_MINGW_THREADS_REPLACEMENT) +ENDIF() + IF(WIN32) SET(WINRC "${CMAKE_CURRENT_BINARY_DIR}/zynaddsubfxrc.obj") ADD_CUSTOM_COMMAND(OUTPUT "${WINRC}" diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index ad8d9a78c83..6441e76b75e 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -192,10 +192,12 @@ void ZynAddSubFxInstrument::saveSettings( QDomDocument & _doc, m_pluginMutex.lock(); if( m_remotePlugin ) { - m_remotePlugin->lock(); - m_remotePlugin->sendMessage( RemotePlugin::message( IdSaveSettingsToFile ).addString( fn ) ); - m_remotePlugin->waitForMessage( IdSaveSettingsToFile ); - m_remotePlugin->unlock(); + if(m_remotePlugin->try_lock()) + { + m_remotePlugin->sendMessage( RemotePlugin::message( IdSaveSettingsToFile ).addString( fn ) ); + m_remotePlugin->waitForMessage( IdSaveSettingsToFile ); + m_remotePlugin->unlock(); + } } else { @@ -250,10 +252,12 @@ void ZynAddSubFxInstrument::loadSettings( const QDomElement & _this ) m_pluginMutex.lock(); if( m_remotePlugin ) { - m_remotePlugin->lock(); - m_remotePlugin->sendMessage( RemotePlugin::message( IdLoadSettingsFromFile ).addString( fn ) ); - m_remotePlugin->waitForMessage( IdLoadSettingsFromFile ); - m_remotePlugin->unlock(); + if(m_remotePlugin->try_lock()) + { + m_remotePlugin->sendMessage( RemotePlugin::message( IdLoadSettingsFromFile ).addString( fn ) ); + m_remotePlugin->waitForMessage( IdLoadSettingsFromFile ); + m_remotePlugin->unlock(); + } } else { @@ -293,10 +297,12 @@ void ZynAddSubFxInstrument::loadFile( const QString & _file ) const std::string fn = QSTR_TO_STDSTR( _file ); if( m_remotePlugin ) { - m_remotePlugin->lock(); - m_remotePlugin->sendMessage( RemotePlugin::message( IdLoadPresetFile ).addString( fn ) ); - m_remotePlugin->waitForMessage( IdLoadPresetFile ); - m_remotePlugin->unlock(); + if(m_remotePlugin->try_lock()) + { + m_remotePlugin->sendMessage( RemotePlugin::message( IdLoadPresetFile ).addString( fn ) ); + m_remotePlugin->waitForMessage( IdLoadPresetFile ); + m_remotePlugin->unlock(); + } } else { @@ -432,29 +438,31 @@ void ZynAddSubFxInstrument::initPlugin() if( m_hasGUI ) { m_remotePlugin = new ZynAddSubFxRemotePlugin(); - m_remotePlugin->lock(); - m_remotePlugin->waitForInitDone( false ); - - m_remotePlugin->sendMessage( - RemotePlugin::message( IdZasfLmmsWorkingDirectory ). - addString( - QSTR_TO_STDSTR( - QString( ConfigManager::inst()->workingDir() ) ) ) ); - m_remotePlugin->sendMessage( - RemotePlugin::message( IdZasfPresetDirectory ). - addString( - QSTR_TO_STDSTR( - QDir( ConfigManager::inst()->factoryPresetsDir() + - "/ZynAddSubFX" ).absolutePath() ) ) ); - - m_remotePlugin->updateSampleRate( Engine::mixer()->processingSampleRate() ); - - // temporary workaround until the VST synchronization feature gets stripped out of the RemotePluginClient class - // causing not to send buffer size information requests - m_remotePlugin->sendMessage( RemotePlugin::message( IdBufferSizeInformation ).addInt( Engine::mixer()->framesPerPeriod() ) ); - - m_remotePlugin->showUI(); - m_remotePlugin->unlock(); + if(m_remotePlugin->try_lock()) + { + m_remotePlugin->waitForInitDone( false ); + + m_remotePlugin->sendMessage( + RemotePlugin::message( IdZasfLmmsWorkingDirectory ). + addString( + QSTR_TO_STDSTR( + QString( ConfigManager::inst()->workingDir() ) ) ) ); + m_remotePlugin->sendMessage( + RemotePlugin::message( IdZasfPresetDirectory ). + addString( + QSTR_TO_STDSTR( + QDir( ConfigManager::inst()->factoryPresetsDir() + + "/ZynAddSubFX" ).absolutePath() ) ) ); + + m_remotePlugin->updateSampleRate( Engine::mixer()->processingSampleRate() ); + + // temporary workaround until the VST synchronization feature gets stripped out of the RemotePluginClient class + // causing not to send buffer size information requests + m_remotePlugin->sendMessage( RemotePlugin::message( IdBufferSizeInformation ).addInt( Engine::mixer()->framesPerPeriod() ) ); + + m_remotePlugin->showUI(); + m_remotePlugin->unlock(); + } } else { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 37da8f414f9..03f57935d94 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -103,6 +103,13 @@ ADD_LIBRARY(lmmsobjs OBJECT ${LMMS_RCC_OUT} ) +if(NOT HAS_STD_MUTEX) + target_include_directories(lmmsobjs PRIVATE + "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/mingw-std-threads") + target_compile_definitions(lmmsobjs PRIVATE + -DUSE_MINGW_THREADS_REPLACEMENT) +endif() + GENERATE_EXPORT_HEADER(lmmsobjs BASE_NAME lmms ) diff --git a/src/core/RemotePlugin.cpp b/src/core/RemotePlugin.cpp index d68f6aa6533..8b1d1d3a93f 100644 --- a/src/core/RemotePlugin.cpp +++ b/src/core/RemotePlugin.cpp @@ -80,8 +80,8 @@ RemotePlugin::RemotePlugin() : RemotePluginBase(), #endif m_failed( true ), + m_disconnected( false ), m_watcher( this ), - m_commMutex( QMutex::Recursive ), m_splitChannels( false ), #ifdef USE_QT_SHMEM m_shmObj(), @@ -140,16 +140,18 @@ RemotePlugin::~RemotePlugin() { if( isRunning() ) { - lock(); - sendMessage( IdQuit ); - - m_process.waitForFinished( 1000 ); - if( m_process.state() != QProcess::NotRunning ) + if (try_lock()) { - m_process.terminate(); - m_process.kill(); + sendMessage(IdQuit); + + m_process.waitForFinished(1000); + if (m_process.state() != QProcess::NotRunning) + { + m_process.terminate(); + m_process.kill(); + } + unlock(); } - unlock(); } #ifndef USE_QT_SHMEM @@ -173,90 +175,91 @@ RemotePlugin::~RemotePlugin() bool RemotePlugin::init(const QString &pluginExecutable, bool waitForInitDoneMsg , QStringList extraArgs) { - lock(); - if( m_failed ) + if (try_lock()) { + if (m_failed) + { #ifdef SYNC_WITH_SHM_FIFO - reset( new shmFifo(), new shmFifo() ); + reset(new shmFifo(), new shmFifo()); #endif - m_failed = false; - } - QString exec = QFileInfo(QDir("plugins:"), pluginExecutable).absoluteFilePath(); + m_failed = false; + } + QString exec = QFileInfo(QDir("plugins:"), pluginExecutable).absoluteFilePath(); #ifdef LMMS_BUILD_APPLE - // search current directory first - QString curDir = QCoreApplication::applicationDirPath() + "/" + pluginExecutable; - if( QFile( curDir ).exists() ) - { - exec = curDir; - } + // search current directory first + QString curDir = QCoreApplication::applicationDirPath() + "/" + pluginExecutable; + if (QFile(curDir).exists()) + { + exec = curDir; + } #endif #ifdef LMMS_BUILD_WIN32 - if( ! exec.endsWith( ".exe", Qt::CaseInsensitive ) ) - { - exec += ".exe"; - } + if (!exec.endsWith(".exe", Qt::CaseInsensitive)) + { + exec += ".exe"; + } #endif - if( ! QFile( exec ).exists() ) - { - qWarning( "Remote plugin '%s' not found.", - exec.toUtf8().constData() ); - m_failed = true; - invalidate(); - unlock(); - return failed(); - } + if (!QFile(exec).exists()) + { + qWarning("Remote plugin '%s' not found.", + exec.toUtf8().constData()); + m_failed = true; + invalidate(); + unlock(); + return failed(); + } - QStringList args; + QStringList args; #ifdef SYNC_WITH_SHM_FIFO - // swap in and out for bidirectional communication - args << QString::number( out()->shmKey() ); - args << QString::number( in()->shmKey() ); + // swap in and out for bidirectional communication + args << QString::number(out()->shmKey()); + args << QString::number(in()->shmKey()); #else - args << m_socketFile; + args << m_socketFile; #endif - args << extraArgs; + args << extraArgs; #ifndef DEBUG_REMOTE_PLUGIN - m_process.setProcessChannelMode( QProcess::ForwardedChannels ); - m_process.setWorkingDirectory( QCoreApplication::applicationDirPath() ); - m_process.start( exec, args ); - m_watcher.start( QThread::LowestPriority ); + m_process.setProcessChannelMode(QProcess::ForwardedChannels); + m_process.setWorkingDirectory(QCoreApplication::applicationDirPath()); + m_process.start(exec, args); + m_watcher.start(QThread::LowestPriority); #else - qDebug() << exec << args; + qDebug() << exec << args; #endif #ifndef SYNC_WITH_SHM_FIFO - struct pollfd pollin; - pollin.fd = m_server; - pollin.events = POLLIN; + struct pollfd pollin; + pollin.fd = m_server; + pollin.events = POLLIN; - switch ( poll( &pollin, 1, 30000 ) ) - { + switch (poll(&pollin, 1, 30000)) + { case -1: - qWarning( "Unexpected poll error." ); + qWarning("Unexpected poll error."); break; case 0: - qWarning( "Remote plugin did not connect." ); + qWarning("Remote plugin did not connect."); break; default: - m_socket = accept( m_server, NULL, NULL ); - if ( m_socket == -1 ) + m_socket = accept(m_server, NULL, NULL); + if (m_socket == -1) { - qWarning( "Unexpected socket error." ); + qWarning("Unexpected socket error."); } - } + } #endif - resizeSharedProcessingMemory(); + resizeSharedProcessingMemory(); - if( waitForInitDoneMsg ) - { - waitForInitDone(); + if (waitForInitDoneMsg) + { + waitForInitDone(); + } + unlock(); } - unlock(); - return failed(); } @@ -285,9 +288,11 @@ bool RemotePlugin::process( const sampleFrame * _in_buf, // in a later stage of this procedure if( m_shmSize == 0 ) { - lock(); - fetchAndProcessAllMessages(); - unlock(); + if (try_lock()) + { + fetchAndProcessAllMessages(); + unlock(); + } } if( _out_buf != NULL ) { @@ -330,18 +335,19 @@ bool RemotePlugin::process( const sampleFrame * _in_buf, } } - lock(); - sendMessage( IdStartProcessing ); - - if( m_failed || _out_buf == NULL || m_outputCount == 0 ) + if (try_lock()) { - unlock(); - return false; - } + sendMessage(IdStartProcessing); - waitForMessage( IdProcessingDone ); - unlock(); + if (m_failed || _out_buf == NULL || m_outputCount == 0) + { + unlock(); + return false; + } + waitForMessage(IdProcessingDone); + unlock(); + } const ch_cnt_t outputs = qMin( m_outputCount, DEFAULT_CHANNELS ); if( m_splitChannels ) @@ -392,23 +398,29 @@ void RemotePlugin::processMidiEvent( const MidiEvent & _e, m.addInt( _e.param( 0 ) ); m.addInt( _e.param( 1 ) ); m.addInt( _offset ); - lock(); - sendMessage( m ); - unlock(); + if (try_lock()) + { + sendMessage(m); + unlock(); + } } void RemotePlugin::showUI() { - lock(); - sendMessage( IdShowUI ); - unlock(); + if (try_lock()) + { + sendMessage(IdShowUI); + unlock(); + } } void RemotePlugin::hideUI() { - lock(); - sendMessage( IdHideUI ); - unlock(); + if (try_lock()) + { + sendMessage(IdHideUI); + unlock(); + } } @@ -480,11 +492,12 @@ void RemotePlugin::processErrored( QProcess::ProcessError err ) bool RemotePlugin::processMessage( const message & _m ) { - lock(); - message reply_message( _m.id ); - bool reply = false; - switch( _m.id ) + if (try_lock()) { + message reply_message(_m.id); + bool reply = false; + switch (_m.id) + { case IdUndefined: unlock(); return false; @@ -495,45 +508,45 @@ bool RemotePlugin::processMessage( const message & _m ) case IdSampleRateInformation: reply = true; - reply_message.addInt( Engine::mixer()->processingSampleRate() ); + reply_message.addInt(Engine::mixer()->processingSampleRate()); break; case IdBufferSizeInformation: reply = true; - reply_message.addInt( Engine::mixer()->framesPerPeriod() ); + reply_message.addInt(Engine::mixer()->framesPerPeriod()); break; case IdChangeInputCount: - m_inputCount = _m.getInt( 0 ); + m_inputCount = _m.getInt(0); resizeSharedProcessingMemory(); break; case IdChangeOutputCount: - m_outputCount = _m.getInt( 0 ); + m_outputCount = _m.getInt(0); resizeSharedProcessingMemory(); break; case IdChangeInputOutputCount: - m_inputCount = _m.getInt( 0 ); - m_outputCount = _m.getInt( 1 ); + m_inputCount = _m.getInt(0); + m_outputCount = _m.getInt(1); resizeSharedProcessingMemory(); break; case IdDebugMessage: - fprintf( stderr, "RemotePlugin::DebugMessage: %s", - _m.getString( 0 ).c_str() ); + fprintf(stderr, "RemotePlugin::DebugMessage: %s", + _m.getString(0).c_str()); break; case IdProcessingDone: case IdQuit: default: break; + } + if (reply) + { + sendMessage(reply_message); + } + unlock(); } - if( reply ) - { - sendMessage( reply_message ); - } - unlock(); - return true; }