DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

commit 84437dfbe44a78f7cd945cfefb6093dc0ead5c7e
parent b3864114d8df9134e860da3c157d9c2658bbd0b6
Author: falkTX <falktx@falktx.com>
Date:   Sun, 13 Jun 2021 21:27:19 +0100

Alternative approach to thread-safe Application::quit

Signed-off-by: falkTX <falktx@falktx.com>

Diffstat:
Mdgl/src/Application.cpp | 2+-
Mdgl/src/ApplicationPrivateData.cpp | 28+++++++++++++++++++++++++---
Mdgl/src/ApplicationPrivateData.hpp | 12++++++++++++
3 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/dgl/src/Application.cpp b/dgl/src/Application.cpp @@ -50,7 +50,7 @@ void Application::quit() bool Application::isQuiting() const noexcept { - return pData->isQuitting; + return pData->isQuitting || pData->isQuittingInNextCycle; } void Application::addIdleCallback(IdleCallback* const callback) diff --git a/dgl/src/ApplicationPrivateData.cpp b/dgl/src/ApplicationPrivateData.cpp @@ -25,6 +25,24 @@ START_NAMESPACE_DGL typedef std::list<DGL_NAMESPACE::Window*>::reverse_iterator WindowListReverseIterator; +static ThreadHandle getCurrentThreadHandle() noexcept +{ +#ifdef DISTRHO_OS_WINDOWS + return GetCurrentThread(); +#else + return pthread_self(); +#endif +} + +static bool isThisMainThread(const ThreadHandle mainThreadHandle) noexcept +{ +#ifdef DISTRHO_OS_WINDOWS + return GetCurrentThread() == mainThreadHandle; // IsGUIThread ? +#else + return pthread_equal(getCurrentThreadHandle(), mainThreadHandle) != 0; +#endif +} + // -------------------------------------------------------------------------------------------------------------------- Application::PrivateData::PrivateData(const bool standalone) @@ -35,6 +53,7 @@ Application::PrivateData::PrivateData(const bool standalone) isQuittingInNextCycle(false), isStarting(true), visibleWindows(0), + mainThreadHandle(getCurrentThreadHandle()), windows(), idleCallbacks() { @@ -108,10 +127,13 @@ void Application::PrivateData::quit() { DISTRHO_SAFE_ASSERT_RETURN(isStandalone,); - if (! isQuittingInNextCycle) + if (! isThisMainThread(mainThreadHandle)) { - isQuittingInNextCycle = true; - return; + if (! isQuittingInNextCycle) + { + isQuittingInNextCycle = true; + return; + } } isQuitting = true; diff --git a/dgl/src/ApplicationPrivateData.hpp b/dgl/src/ApplicationPrivateData.hpp @@ -21,6 +21,15 @@ #include <list> +#ifdef DISTRHO_OS_WINDOWS +# include <winsock2.h> +# include <windows.h> +typedef HANDLE ThreadHandle; +#else +# include <pthread.h> +typedef pthread_t ThreadHandle; +#endif + typedef struct PuglWorldImpl PuglWorld; START_NAMESPACE_DGL @@ -49,6 +58,9 @@ struct Application::PrivateData { If 0->1, application is starting. If 1->0, application is quitting/stopping. */ uint visibleWindows; + /** Handle that identifies the main thread. Used to check if calls belong to current thread or not. */ + ThreadHandle mainThreadHandle; + /** List of windows for this application. Only used during `close`. */ std::list<DGL_NAMESPACE::Window*> windows;