From c8e570797f1e7c76750b4a8f24d4fb97c612f7e6 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sun, 31 Jul 2016 12:32:37 -0400 Subject: [PATCH] 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. --- mac/wxMac_additions/eventloops.patch | 76 ++++++++++++++++++++-- src/effects/VST/VSTEffect.cpp | 8 +++ src/effects/audiounits/AudioUnitEffect.cpp | 13 ++++ src/effects/lv2/LV2Effect.cpp | 13 ++++ 4 files changed, 105 insertions(+), 5 deletions(-) diff --git a/mac/wxMac_additions/eventloops.patch b/mac/wxMac_additions/eventloops.patch index 9be6564d7..7b321c980 100644 --- a/mac/wxMac_additions/eventloops.patch +++ b/mac/wxMac_additions/eventloops.patch @@ -1,13 +1,79 @@ +From aed0a3ed0df16f04dc39c8366d9c399fcc172009 Mon Sep 17 00:00:00 2001 +From: Paul Licameli +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() diff --git a/src/effects/VST/VSTEffect.cpp b/src/effects/VST/VSTEffect.cpp index f5430253b..4dc9583c4 100644 --- a/src/effects/VST/VSTEffect.cpp +++ b/src/effects/VST/VSTEffect.cpp @@ -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; } diff --git a/src/effects/audiounits/AudioUnitEffect.cpp b/src/effects/audiounits/AudioUnitEffect.cpp index d0d79f394..b29364613 100644 --- a/src/effects/audiounits/AudioUnitEffect.cpp +++ b/src/effects/audiounits/AudioUnitEffect.cpp @@ -22,6 +22,11 @@ #include #include #include + +#ifdef __WXMAC__ +#include +#endif + #include #include #include @@ -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; diff --git a/src/effects/lv2/LV2Effect.cpp b/src/effects/lv2/LV2Effect.cpp index 6dd9a6a37..91b4e921f 100644 --- a/src/effects/lv2/LV2Effect.cpp +++ b/src/effects/lv2/LV2Effect.cpp @@ -18,6 +18,11 @@ #include #include #include + +#ifdef __WXMAC__ +#include +#endif + #include #include #include @@ -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; }