Browse Source

Alternative approach to thread-safe Application::quit

Signed-off-by: falkTX <falktx@falktx.com>
pull/292/head
falkTX 4 years ago
parent
commit
84437dfbe4
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
3 changed files with 38 additions and 4 deletions
  1. +1
    -1
      dgl/src/Application.cpp
  2. +25
    -3
      dgl/src/ApplicationPrivateData.cpp
  3. +12
    -0
      dgl/src/ApplicationPrivateData.hpp

+ 1
- 1
dgl/src/Application.cpp View File

@@ -50,7 +50,7 @@ void Application::quit()


bool Application::isQuiting() const noexcept bool Application::isQuiting() const noexcept
{ {
return pData->isQuitting;
return pData->isQuitting || pData->isQuittingInNextCycle;
} }


void Application::addIdleCallback(IdleCallback* const callback) void Application::addIdleCallback(IdleCallback* const callback)


+ 25
- 3
dgl/src/ApplicationPrivateData.cpp View File

@@ -25,6 +25,24 @@ START_NAMESPACE_DGL


typedef std::list<DGL_NAMESPACE::Window*>::reverse_iterator WindowListReverseIterator; 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) Application::PrivateData::PrivateData(const bool standalone)
@@ -35,6 +53,7 @@ Application::PrivateData::PrivateData(const bool standalone)
isQuittingInNextCycle(false), isQuittingInNextCycle(false),
isStarting(true), isStarting(true),
visibleWindows(0), visibleWindows(0),
mainThreadHandle(getCurrentThreadHandle()),
windows(), windows(),
idleCallbacks() idleCallbacks()
{ {
@@ -108,10 +127,13 @@ void Application::PrivateData::quit()
{ {
DISTRHO_SAFE_ASSERT_RETURN(isStandalone,); DISTRHO_SAFE_ASSERT_RETURN(isStandalone,);


if (! isQuittingInNextCycle)
if (! isThisMainThread(mainThreadHandle))
{ {
isQuittingInNextCycle = true;
return;
if (! isQuittingInNextCycle)
{
isQuittingInNextCycle = true;
return;
}
} }


isQuitting = true; isQuitting = true;


+ 12
- 0
dgl/src/ApplicationPrivateData.hpp View File

@@ -21,6 +21,15 @@


#include <list> #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; typedef struct PuglWorldImpl PuglWorld;


START_NAMESPACE_DGL START_NAMESPACE_DGL
@@ -49,6 +58,9 @@ struct Application::PrivateData {
If 0->1, application is starting. If 1->0, application is quitting/stopping. */ If 0->1, application is starting. If 1->0, application is quitting/stopping. */
uint visibleWindows; 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`. */ /** List of windows for this application. Only used during `close`. */
std::list<DGL_NAMESPACE::Window*> windows; std::list<DGL_NAMESPACE::Window*> windows;




Loading…
Cancel
Save