Bug1338 fixed again, with fewer Mac busy-waits; CHANGES WX BUILD...

... Busy-waiting will happen on Mac when modal dialogs are open, and a LADSPA,
VST, or AudioUnits effect is also open with "fancy" interface.

Busy-waiting will not happen for modal dialogs at other times.
This commit is contained in:
Paul Licameli 2016-07-31 12:32:37 -04:00
parent e05d8aedd5
commit c8e570797f
4 changed files with 105 additions and 5 deletions

View File

@ -1,13 +1,79 @@
From aed0a3ed0df16f04dc39c8366d9c399fcc172009 Mon Sep 17 00:00:00 2001
From: Paul Licameli <paul.licameli@audacityteam.org>
Date: Sun, 31 Jul 2016 11:55:29 -0400
Subject: [PATCH 1/3] Mac modal loops won't hang when other code uses old
Mutiprocessing...
... if you call the new wxEventLoopBase::SetBusyWaiting(true).
But this has the undesirable consequence of high CPU usage while the loop idles,
so this fix must be turned on only as needed by the application.
See the Audacity bug report that motivated this change:
http://bugzilla.audacityteam.org/show_bug.cgi?id=1338
---
include/wx/evtloop.h | 9 +++++++++
src/common/evtloopcmn.cpp | 14 ++++++++++++++
src/osx/core/evtloop_cf.cpp | 3 ++-
3 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/include/wx/evtloop.h b/include/wx/evtloop.h
index 1133473..db87431 100644
--- a/include/wx/evtloop.h
+++ b/include/wx/evtloop.h
@@ -177,6 +177,15 @@ public:
// set currently active (running) event loop
static void SetActive(wxEventLoopBase* loop);
+#ifdef __WXMAC__
+ static bool GetBusyWaiting();
+
+ // If the argument is true, cause modal dialogs to busy-wait for events,
+ // which seems to be necessary to avoid hanging when other code is using
+ // the old Multiprocessing API
+ static void SetBusyWaiting(bool busyWaiting);
+#endif
+
protected:
// real implementation of Run()
diff --git a/src/common/evtloopcmn.cpp b/src/common/evtloopcmn.cpp
index f7b5138..325fd54 100644
--- a/src/common/evtloopcmn.cpp
+++ b/src/common/evtloopcmn.cpp
@@ -56,6 +56,20 @@ void wxEventLoopBase::SetActive(wxEventLoopBase* loop)
wxTheApp->OnEventLoopEnter(loop);
}
+static bool g_busyWaiting = false;
+
+/* static */
+bool wxEventLoopBase::GetBusyWaiting()
+{
+ return g_busyWaiting;
+}
+
+/* static */
+void wxEventLoopBase::SetBusyWaiting(bool busyWaiting)
+{
+ g_busyWaiting = busyWaiting;
+}
+
int wxEventLoopBase::Run()
{
// event loops are not recursive, you need to create another loop!
diff --git a/src/osx/core/evtloop_cf.cpp b/src/osx/core/evtloop_cf.cpp
index 7e70dec..37b22b5 100644
--- src/osx/core/evtloop_cf.cpp
+++ src/osx/core/evtloop_cf.cpp
@@ -243,7 +243,7 @@ int wxCFEventLoop::DoProcessEvents()
index 7e70dec..510af80 100644
--- a/src/osx/core/evtloop_cf.cpp
+++ b/src/osx/core/evtloop_cf.cpp
@@ -243,7 +243,8 @@ int wxCFEventLoop::DoProcessEvents()
}
else
#endif
- return DispatchTimeout( m_isInsideYield ? 0 : 1000 );
+ return DispatchTimeout( 0 );
+ return DispatchTimeout
+ (m_isInsideYield || wxEventLoopBase::GetBusyWaiting() ? 0 : 1000 );
}
bool wxCFEventLoop::Dispatch()

View File

@ -1787,6 +1787,10 @@ bool VSTEffect::HideUI()
bool VSTEffect::CloseUI()
{
#ifdef __WXMAC__
wxEventLoop::SetBusyWaiting(false);
#endif
mParent->RemoveEventHandler(this);
PowerOff();
@ -2835,6 +2839,10 @@ void VSTEffect::BuildFancy()
mDialog->Connect(wxEVT_SIZE, wxSizeEventHandler(VSTEffect::OnSize));
#ifdef __WXMAC__
wxEventLoop::SetBusyWaiting(true);
#endif
return;
}

View File

@ -22,6 +22,11 @@
#include <wx/button.h>
#include <wx/control.h>
#include <wx/dir.h>
#ifdef __WXMAC__
#include <wx/evtloop.h>
#endif
#include <wx/filename.h>
#include <wx/frame.h>
#include <wx/listctrl.h>
@ -1792,6 +1797,10 @@ bool AudioUnitEffect::PopulateUI(wxWindow *parent)
}
mParent->SetMinSize(wxDefaultSize);
#ifdef __WXMAC__
wxEventLoop::SetBusyWaiting(true);
#endif
}
mParent->PushEventHandler(this);
@ -1838,6 +1847,10 @@ bool AudioUnitEffect::HideUI()
bool AudioUnitEffect::CloseUI()
{
#ifdef __WXMAC__
wxEventLoop::SetBusyWaiting(false);
#endif
mParent->RemoveEventHandler(this);
mUIHost = NULL;

View File

@ -18,6 +18,11 @@
#include <wx/dcbuffer.h>
#include <wx/dialog.h>
#include <wx/dynarray.h>
#ifdef __WXMAC__
#include <wx/evtloop.h>
#endif
#include <wx/math.h>
#include <wx/msgdlg.h>
#include <wx/sizer.h>
@ -1133,6 +1138,10 @@ bool LV2Effect::HideUI()
bool LV2Effect::CloseUI()
{
#ifdef __WXMAC__
wxEventLoop::SetBusyWaiting(false);
#endif
mParent->RemoveEventHandler(this);
if (mSliders)
@ -1561,6 +1570,10 @@ bool LV2Effect::BuildFancy()
TransferDataToWindow();
#ifdef __WXMAC__
wxEventLoop::SetBusyWaiting(true);
#endif
return true;
}