vcl/android/androidinst.cxx   |    2 
 vcl/headless/headlessinst.cxx |    2 
 vcl/headless/svpinst.cxx      |  316 +++++++++++++++++++++++++++++++++---------
 vcl/inc/headless/svpinst.hxx  |  101 +++++--------
 vcl/ios/iosinst.cxx           |    2 
 vcl/source/app/salplug.cxx    |    2 
 6 files changed, 295 insertions(+), 130 deletions(-)

New commits:
commit 07295115f5742e0d06a21d280610903ad55a75f0
Author:     Stephan Bergmann <sberg...@redhat.com>
AuthorDate: Wed Jun 22 22:26:04 2022 +0200
Commit:     Stephan Bergmann <sberg...@redhat.com>
CommitDate: Thu Jun 23 07:55:06 2022 +0200

    Revert "svp: don't directly yield in main thread"
    
    This reverts commit d2de55c93f94bbccff51fa7715b613341f1f4ae6 for now, 
because it
    appears to have caused a massive uptick in hung UITest_impress_tests
    (sd/qa/uitest/impress_tests/save_readonly_with_password.py, line 95) and
    UITest_writer_test6 
(sw/qa/uitest/writer_tests6/save_readonly_with_password.py,
    line 54) tests across Jenkins, see the comments starting at
    
<https://gerrit.libreoffice.org/c/core/+/117900/8#message-e439f5f2b9ed7a24d6f47fd640defe14dc392eb5>
    "svp: don't directly yield in main thread".
    
    Change-Id: Id114a0d904580024352e4acf37e2558f9f0ae6f5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136250
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sberg...@redhat.com>

diff --git a/vcl/android/androidinst.cxx b/vcl/android/androidinst.cxx
index 56497db19270..ca130fb1b19f 100644
--- a/vcl/android/androidinst.cxx
+++ b/vcl/android/androidinst.cxx
@@ -157,7 +157,7 @@ SalFrame *AndroidSalInstance::CreateFrame( SalFrame* 
pParent, SalFrameStyleFlags
 extern "C" SalInstance *create_SalInstance()
 {
     LOGI("Android: create_SalInstance!");
-    AndroidSalInstance* pInstance = new AndroidSalInstance( 
std::make_unique<SalYieldMutex>() );
+    AndroidSalInstance* pInstance = new AndroidSalInstance( 
std::make_unique<SvpSalYieldMutex>() );
     new SvpSalData();
     return pInstance;
 }
diff --git a/vcl/headless/headlessinst.cxx b/vcl/headless/headlessinst.cxx
index 162fd5bd865b..abe3e1cf92c7 100644
--- a/vcl/headless/headlessinst.cxx
+++ b/vcl/headless/headlessinst.cxx
@@ -47,7 +47,7 @@ SalSystem *HeadlessSalInstance::CreateSalSystem()
 
 extern "C" SalInstance *create_SalInstance()
 {
-    HeadlessSalInstance* pInstance = new 
HeadlessSalInstance(std::make_unique<SalYieldMutex>());
+    HeadlessSalInstance* pInstance = new 
HeadlessSalInstance(std::make_unique<SvpSalYieldMutex>());
     new SvpSalData();
     return pInstance;
 }
diff --git a/vcl/headless/svpinst.cxx b/vcl/headless/svpinst.cxx
index 10beeeb58fbd..bf53dc24faf3 100644
--- a/vcl/headless/svpinst.cxx
+++ b/vcl/headless/svpinst.cxx
@@ -56,55 +56,138 @@
 #include <unx/salunxtime.h>
 #include <comphelper/lok.hxx>
 #include <tools/debug.hxx>
-#include <tools/time.hxx>
 
 SvpSalInstance* SvpSalInstance::s_pDefaultInstance = nullptr;
 
+#ifndef NDEBUG
+static bool g_CheckedMutex = false;
+
+#define DBG_TESTSVPYIELDMUTEX() \
+do { \
+    if (!g_CheckedMutex) \
+    { \
+        assert(dynamic_cast<SvpSalYieldMutex*>(GetYieldMutex()) != nullptr \
+            && "This SvpSalInstance function requires use of 
SvpSalYieldMutex"); \
+        g_CheckedMutex = true; \
+    } \
+} while(false)
+
+#else // NDEBUG
+#define DBG_TESTSVPYIELDMUTEX() ((void)0)
+#endif
+
+#if !defined(ANDROID) && !defined(IOS)
+
+static void atfork_child()
+{
+    if (SvpSalInstance::s_pDefaultInstance != nullptr)
+    {
+        SvpSalInstance::s_pDefaultInstance->CloseWakeupPipe(false);
+        SvpSalInstance::s_pDefaultInstance->CreateWakeupPipe(false);
+    }
+}
+
+#endif
+
 SvpSalInstance::SvpSalInstance( std::unique_ptr<SalYieldMutex> pMutex )
     : SalGenericInstance( std::move(pMutex) )
-    , m_WaitCondition(m_NonMainYieldMutex)
-    , m_EventCondition(m_NonMainYieldMutex)
-    , m_MainYieldCondition(m_MainYieldMutex)
 {
     m_aTimeout.tv_sec       = 0;
     m_aTimeout.tv_usec      = 0;
     m_nTimeoutMS            = 0;
 
     m_MainThread = osl::Thread::getCurrentIdentifier();
+    CreateWakeupPipe(true);
     if( s_pDefaultInstance == nullptr )
         s_pDefaultInstance = this;
-
-    m_bSupportsOpenGL = false;
+#if !defined(ANDROID) && !defined(IOS)
+    pthread_atfork(nullptr, nullptr, atfork_child);
+#endif
 }
 
 SvpSalInstance::~SvpSalInstance()
 {
     if( s_pDefaultInstance == this )
         s_pDefaultInstance = nullptr;
+    CloseWakeupPipe(true);
 }
 
-void SvpSalInstance::TriggerUserEventProcessing()
+void SvpSalInstance::CloseWakeupPipe(bool log)
 {
-    Wakeup();
+    SvpSalYieldMutex *const 
pMutex(dynamic_cast<SvpSalYieldMutex*>(GetYieldMutex()));
+    if (!pMutex)
+        return;
+    if (pMutex->m_FeedbackFDs[0] != -1)
+    {
+        if (log)
+        {
+            SAL_INFO("vcl.headless", "CloseWakeupPipe: Closing inherited 
feedback pipe: [" << pMutex->m_FeedbackFDs[0] << "," << 
pMutex->m_FeedbackFDs[1] << "]");
+        }
+        close (pMutex->m_FeedbackFDs[0]);
+        close (pMutex->m_FeedbackFDs[1]);
+        pMutex->m_FeedbackFDs[0] = pMutex->m_FeedbackFDs[1] = -1;
+    }
 }
 
-void SvpSalInstance::Wakeup()
+void SvpSalInstance::CreateWakeupPipe(bool log)
 {
-    if (IsMainThread())
+    SvpSalYieldMutex *const 
pMutex(dynamic_cast<SvpSalYieldMutex*>(GetYieldMutex()));
+    if (!pMutex)
         return;
-
-    if (vcl::lok::isUnipoll())
+    if (pipe (pMutex->m_FeedbackFDs) == -1)
     {
-        ImplSVData* pSVData = ImplGetSVData();
-        if (pSVData->mpWakeCallback && pSVData->mpPollClosure)
-            pSVData->mpWakeCallback(pSVData->mpPollClosure);
+        if (log)
+        {
+            SAL_WARN("vcl.headless", "Could not create feedback pipe: " << 
strerror(errno));
+            std::abort();
+        }
     }
     else
     {
-        m_MainYieldCondition.notify_all();
+        if (log)
+        {
+            SAL_INFO("vcl.headless", "CreateWakeupPipe: Created feedback pipe: 
[" << pMutex->m_FeedbackFDs[0] << "," << pMutex->m_FeedbackFDs[1] << "]");
+        }
+
+        int flags;
+
+        // set close-on-exec descriptor flag.
+        if ((flags = fcntl (pMutex->m_FeedbackFDs[0], F_GETFD)) != -1)
+        {
+            flags |= FD_CLOEXEC;
+            (void) fcntl(pMutex->m_FeedbackFDs[0], F_SETFD, flags);
+        }
+        if ((flags = fcntl (pMutex->m_FeedbackFDs[1], F_GETFD)) != -1)
+        {
+            flags |= FD_CLOEXEC;
+            (void) fcntl(pMutex->m_FeedbackFDs[1], F_SETFD, flags);
+        }
+
+        // retain the default blocking I/O for feedback pipe
     }
 }
 
+void SvpSalInstance::TriggerUserEventProcessing()
+{
+    Wakeup();
+}
+
+void SvpSalInstance::Wakeup(SvpRequest const request)
+{
+    DBG_TESTSVPYIELDMUTEX();
+
+    ImplSVData* pSVData = ImplGetSVData();
+    if (pSVData->mpWakeCallback && pSVData->mpPollClosure)
+        pSVData->mpWakeCallback(pSVData->mpPollClosure);
+
+    SvpSalYieldMutex *const 
pMutex(static_cast<SvpSalYieldMutex*>(GetYieldMutex()));
+    std::scoped_lock<std::mutex> g(pMutex->m_WakeUpMainMutex);
+    if (request != SvpRequest::NONE)
+        pMutex->m_Request = request;
+    pMutex->m_wakeUpMain = true;
+    pMutex->m_WakeUpMainCond.notify_one();
+}
+
 bool SvpSalInstance::CheckTimeout( bool bExecuteTimers )
 {
     bool bRet = false;
@@ -121,6 +204,8 @@ bool SvpSalInstance::CheckTimeout( bool bExecuteTimers )
                 m_aTimeout = aTimeOfDay;
                 m_aTimeout += m_nTimeoutMS;
 
+                osl::Guard< comphelper::SolarMutex > aGuard( GetYieldMutex() );
+
                 // notify
                 ImplSVData* pSVData = ImplGetSVData();
                 if( pSVData->maSchedCtx.mpSalTimer )
@@ -226,6 +311,8 @@ std::shared_ptr<SalBitmap> SvpSalInstance::CreateSalBitmap()
 
 void SvpSalInstance::ProcessEvent( SalUserEvent aEvent )
 {
+    DBG_TESTSVPYIELDMUTEX();
+
     aEvent.m_pFrame->CallCallback( aEvent.m_nEvent, aEvent.m_pData );
     if( aEvent.m_nEvent == SalEvent::Resize )
     {
@@ -233,6 +320,109 @@ void SvpSalInstance::ProcessEvent( SalUserEvent aEvent )
         const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>( 
aEvent.m_pFrame);
         pSvpFrame->PostPaint();
     }
+
+    SvpSalYieldMutex *const 
pMutex(static_cast<SvpSalYieldMutex*>(GetYieldMutex()));
+    pMutex->m_NonMainWaitingYieldCond.set();
+}
+
+SvpSalYieldMutex::SvpSalYieldMutex()
+{
+#ifndef IOS
+    m_FeedbackFDs[0] = m_FeedbackFDs[1] = -1;
+#endif
+}
+
+SvpSalYieldMutex::~SvpSalYieldMutex()
+{
+}
+
+void SvpSalYieldMutex::doAcquire(sal_uInt32 const nLockCount)
+{
+    auto *const pInst = static_cast<SvpSalInstance*>(GetSalInstance());
+    if (pInst && pInst->IsMainThread())
+    {
+        if (m_bNoYieldLock)
+            return;
+
+        do
+        {
+            SvpRequest request = SvpRequest::NONE;
+            {
+                std::unique_lock<std::mutex> g(m_WakeUpMainMutex);
+                if (m_aMutex.tryToAcquire()) {
+                    // if there's a request, the other thread holds m_aMutex
+                    assert(m_Request == SvpRequest::NONE);
+                    m_wakeUpMain = false;
+                    break;
+                }
+                m_WakeUpMainCond.wait(g, [this]() { return m_wakeUpMain; });
+                m_wakeUpMain = false;
+                std::swap(m_Request, request);
+            }
+            if (request != SvpRequest::NONE)
+            {
+                // nested Yield on behalf of another thread
+                assert(!m_bNoYieldLock);
+                m_bNoYieldLock = true;
+                bool const bEvents = pInst->DoYield(false, request == 
SvpRequest::MainThreadDispatchAllEvents);
+                m_bNoYieldLock = false;
+                if (write(m_FeedbackFDs[1], &bEvents, sizeof(bool)) != 
sizeof(bool))
+                {
+                    SAL_WARN("vcl.headless", "Could not write: " << 
strerror(errno));
+                    std::abort();
+                }
+            }
+        }
+        while (true);
+    }
+    else
+    {
+        m_aMutex.acquire();
+    }
+    ++m_nCount;
+    SalYieldMutex::doAcquire(nLockCount - 1);
+}
+
+sal_uInt32 SvpSalYieldMutex::doRelease(bool const bUnlockAll)
+{
+    auto *const pInst = static_cast<SvpSalInstance*>(GetSalInstance());
+    if (pInst && pInst->IsMainThread())
+    {
+        if (m_bNoYieldLock)
+            return 1;
+        else
+            return SalYieldMutex::doRelease(bUnlockAll);
+    }
+    sal_uInt32 nCount;
+    {
+        // read m_nCount before doRelease
+        bool const isReleased(bUnlockAll || m_nCount == 1);
+        nCount = comphelper::SolarMutex::doRelease( bUnlockAll );
+
+        if (isReleased)
+        {
+            if (vcl::lok::isUnipoll())
+            {
+                if (pInst)
+                    pInst->Wakeup();
+            }
+            else
+            {
+                std::scoped_lock<std::mutex> g(m_WakeUpMainMutex);
+                m_wakeUpMain = true;
+                m_WakeUpMainCond.notify_one();
+            }
+        }
+    }
+    return nCount;
+}
+
+bool SvpSalYieldMutex::IsCurrentThread() const
+{
+    if (GetSalInstance()->IsMainThread() && m_bNoYieldLock)
+        return true;
+    else
+        return SalYieldMutex::IsCurrentThread();
 }
 
 bool SvpSalInstance::IsMainThread() const
@@ -249,17 +439,25 @@ void SvpSalInstance::updateMainThread()
     }
 }
 
-bool SvpSalInstance::ImplYield(bool bWait)
+bool SvpSalInstance::ImplYield(bool bWait, bool bHandleAllCurrentEvents)
 {
+    DBG_TESTSVPYIELDMUTEX();
     DBG_TESTSOLARMUTEX();
     assert(IsMainThread());
 
-    bool bWasEvent = DispatchUserEvents(true);
-    const bool bTimeout = CheckTimeout();
-    bWasEvent = bTimeout || bWasEvent;
+    bool bWasEvent = DispatchUserEvents(bHandleAllCurrentEvents);
+    if (!bHandleAllCurrentEvents && bWasEvent)
+        return true;
 
-    sal_Int64 nTimeoutMicroS = 0;
+    bWasEvent = CheckTimeout() || bWasEvent;
     const bool bMustSleep = bWait && !bWasEvent;
+
+    // This is wrong and must be removed!
+    // We always want to drop the SolarMutex on yield; that is the whole point 
of yield.
+    if (!bMustSleep)
+        return bWasEvent;
+
+    sal_Int64 nTimeoutMicroS = 0;
     if (bMustSleep)
     {
         if (m_aTimeout.tv_sec) // Timer is started.
@@ -276,21 +474,13 @@ bool SvpSalInstance::ImplYield(bool bWait)
     }
 
     SolarMutexReleaser aReleaser;
-    m_bWasEvent = bWasEvent;
 
     if (vcl::lok::isUnipoll())
     {
         ImplSVData* pSVData = ImplGetSVData();
         if (pSVData->mpPollClosure)
         {
-            int nPollResult = 0;
-            if (!bMustSleep || (nTimeoutMicroS != 0))
-                nPollResult = pSVData->mpPollCallback(pSVData->mpPollClosure, 
0);
-            if (bMustSleep && nPollResult == 0)
-            {
-                m_EventCondition.notify_all();
-                nPollResult = pSVData->mpPollCallback(pSVData->mpPollClosure, 
nTimeoutMicroS);
-            }
+            int nPollResult = pSVData->mpPollCallback(pSVData->mpPollClosure, 
nTimeoutMicroS);
             if (nPollResult < 0)
                 pSVData->maAppData.mbAppQuit = true;
             bWasEvent = bWasEvent || (nPollResult != 0);
@@ -298,63 +488,59 @@ bool SvpSalInstance::ImplYield(bool bWait)
     }
     else if (bMustSleep)
     {
-        assert(!bWasEvent);
-        if (nTimeoutMicroS == 0)
+        SvpSalYieldMutex *const 
pMutex(static_cast<SvpSalYieldMutex*>(GetYieldMutex()));
+        std::unique_lock<std::mutex> g(pMutex->m_WakeUpMainMutex);
+        // wait for doRelease() or Wakeup() to set the condition
+        if (nTimeoutMicroS == -1)
         {
-            m_EventCondition.notify_all();
-            return bWasEvent;
+            pMutex->m_WakeUpMainCond.wait(g,
+                    [pMutex]() { return pMutex->m_wakeUpMain; });
         }
-
-        auto wakeup = [this]() { m_EventCondition.notify_all(); return false; 
};
-
-        if (nTimeoutMicroS == -1)
-            m_MainYieldCondition.wait(wakeup);
         else
         {
             int nTimeoutMS = nTimeoutMicroS / 1000;
             if (nTimeoutMicroS % 1000)
                 nTimeoutMS += 1;
-            
m_MainYieldCondition.wait_for(std::chrono::milliseconds(nTimeoutMS), wakeup);
+            pMutex->m_WakeUpMainCond.wait_for(g,
+                    std::chrono::milliseconds(nTimeoutMS),
+                    [pMutex]() { return pMutex->m_wakeUpMain; });
         }
+        // here no need to check m_Request because Acquire will do it
     }
 
-    if (bWasEvent)
-        m_WaitCondition.notify_all();
-    m_EventCondition.notify_all();
-
     return bWasEvent;
 }
 
-bool SvpSalInstance::DoYield(bool bWait, bool)
+bool SvpSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents)
 {
+    DBG_TESTSVPYIELDMUTEX();
     DBG_TESTSOLARMUTEX();
 
     bool bWasEvent(false);
+    SvpSalYieldMutex *const 
pMutex(static_cast<SvpSalYieldMutex*>(GetYieldMutex()));
 
     if (IsMainThread())
-        bWasEvent = ImplYield(bWait);
+    {
+        bWasEvent = ImplYield(bWait, bHandleAllCurrentEvents);
+        if (bWasEvent)
+            pMutex->m_NonMainWaitingYieldCond.set(); // wake up other threads
+    }
     else
     {
-        SolarMutexReleaser aReleaser;
-        if (bWait)
-        {
-            m_WaitCondition.wait();
-            bWasEvent = true;
-        }
-        else
+        // TODO: use a SolarMutexReleaser here and drop the m_bNoYieldLock 
usage
+        Wakeup(bHandleAllCurrentEvents
+                ? SvpRequest::MainThreadDispatchAllEvents
+                : SvpRequest::MainThreadDispatchOneEvent);
+
+        // blocking read (for synchronisation)
+        auto const nRet = read(pMutex->m_FeedbackFDs[0], &bWasEvent, 
sizeof(bool));
+        assert(nRet == 1); (void) nRet;
+        if (!bWasEvent && bWait)
         {
-            // prevent ABBA deadlock
-            std::unique_lock<std::mutex> g(m_MainYieldCondition.mutex());
-            const bool bIsSleeping = m_MainYieldCondition.isSleeping();
-            m_EventCondition.wait([bIsSleeping, &g]()
-            {
-                g.unlock();
-                return bIsSleeping;
-            });
-            if (bIsSleeping)
-                bWasEvent = false;
-            else
-                bWasEvent = m_bWasEvent;
+            // block & release YieldMutex until the main thread does something
+            pMutex->m_NonMainWaitingYieldCond.reset();
+            SolarMutexReleaser aReleaser;
+            pMutex->m_NonMainWaitingYieldCond.wait();
         }
     }
 
diff --git a/vcl/inc/headless/svpinst.hxx b/vcl/inc/headless/svpinst.hxx
index 9bba1bec57cd..874ce672d97a 100644
--- a/vcl/inc/headless/svpinst.hxx
+++ b/vcl/inc/headless/svpinst.hxx
@@ -29,9 +29,6 @@
 #include <unx/genprn.h>
 
 #include <condition_variable>
-#include <mutex>
-#include <functional>
-#include <chrono>
 
 #include <sys/time.h>
 
@@ -42,56 +39,10 @@
 #define SvpSalInstance AquaSalInstance
 #endif
 
-class SvpYieldCondition final
-{
-    bool m_bReady = false;
-    bool m_bSleeping = false;
-    std::mutex& m_rMutex;
-    std::condition_variable m_Conditional;
-
-public:
-    SvpYieldCondition(std::mutex& rMutex) : m_rMutex(rMutex) {}
-
-    void notify_all()
-    {
-        {
-            std::lock_guard<std::mutex> g(m_rMutex);
-            m_bReady = true;
-        }
-        m_Conditional.notify_all();
-    }
-
-    void wait(std::function<bool()> func = [](){ return false; })
-    {
-        std::unique_lock<std::mutex> g(m_rMutex);
-        if (func())
-            return;
-        m_bSleeping = true;
-        m_Conditional.wait(g, [this]() { return m_bReady; });
-        m_bSleeping = false;
-        m_bReady = false;
-    }
-
-    void wait_for(std::chrono::milliseconds rel_time, std::function<bool()> 
func = [](){ return false; })
-    {
-        std::unique_lock<std::mutex> g(m_rMutex);
-        if (func())
-            return;
-        m_bSleeping = true;
-        m_Conditional.wait_for(g, rel_time, [this]() { return m_bReady; });
-        m_bSleeping = false;
-        m_bReady = false;
-    }
-
-    std::mutex& mutex() const { return m_rMutex; }
-    bool isSleeping() const { return m_bSleeping; }
-};
-
 class SvpSalInstance;
 class SvpSalTimer final : public SalTimer
 {
     SvpSalInstance* m_pInstance;
-
 public:
     SvpSalTimer( SvpSalInstance* pInstance ) : m_pInstance( pInstance ) {}
     virtual ~SvpSalTimer() override;
@@ -104,25 +55,51 @@ public:
 class SvpSalFrame;
 class GenPspGraphics;
 
+enum class SvpRequest
+{
+    NONE,
+    MainThreadDispatchOneEvent,
+    MainThreadDispatchAllEvents,
+};
+
+class SvpSalYieldMutex final : public SalYieldMutex
+{
+private:
+    // note: these members might as well live in SvpSalInstance, but there is
+    // at least one subclass of SvpSalInstance (GTK3) that doesn't use them.
+    friend class SvpSalInstance;
+    // members for communication from main thread to non-main thread
+    int                     m_FeedbackFDs[2];
+    osl::Condition          m_NonMainWaitingYieldCond;
+    // members for communication from non-main thread to main thread
+    bool                    m_bNoYieldLock = false; // accessed only on main 
thread
+    std::mutex              m_WakeUpMainMutex; // guard m_wakeUpMain & 
m_Request
+    std::condition_variable m_WakeUpMainCond;
+    bool                    m_wakeUpMain = false;
+    SvpRequest              m_Request = SvpRequest::NONE;
+
+    virtual void            doAcquire( sal_uInt32 nLockCount ) override;
+    virtual sal_uInt32      doRelease( bool bUnlockAll ) override;
+
+public:
+    SvpSalYieldMutex();
+    virtual ~SvpSalYieldMutex() override;
+
+    virtual bool IsCurrentThread() const override;
+};
+
+// NOTE: the functions IsMainThread, DoYield and Wakeup *require* the use of
+// SvpSalYieldMutex; if a subclass uses something else it must override these
+// (Wakeup is only called by SvpSalTimer and SvpSalFrame)
 class VCL_DLLPUBLIC SvpSalInstance : public SalGenericInstance, public 
SalUserEventList
 {
     timeval                 m_aTimeout;
     sal_uLong               m_nTimeoutMS;
     oslThreadIdentifier     m_MainThread;
 
-    // members for communication from main thread to non-main thread
-    std::mutex m_NonMainYieldMutex;
-    SvpYieldCondition m_WaitCondition;
-    SvpYieldCondition m_EventCondition;
-    bool m_bWasEvent;
-
-    // members for communication from non-main thread to main thread
-    std::mutex m_MainYieldMutex;
-    SvpYieldCondition m_MainYieldCondition;
-
     virtual void            TriggerUserEventProcessing() override;
     virtual void            ProcessEvent( SalUserEvent aEvent ) override;
-    bool ImplYield(bool bWait);
+    bool ImplYield(bool bWait, bool bHandleAllCurrentEvents);
 
 public:
     static SvpSalInstance*  s_pDefaultInstance;
@@ -130,7 +107,9 @@ public:
     SvpSalInstance( std::unique_ptr<SalYieldMutex> pMutex );
     virtual ~SvpSalInstance() override;
 
-    void                    Wakeup();
+    void                    CloseWakeupPipe(bool log);
+    void                    CreateWakeupPipe(bool log);
+    void                    Wakeup(SvpRequest request = SvpRequest::NONE);
 
     void                    StartTimer( sal_uInt64 nMS );
     void                    StopTimer();
diff --git a/vcl/ios/iosinst.cxx b/vcl/ios/iosinst.cxx
index 0a0a11594dfe..a9fa27e5ea82 100644
--- a/vcl/ios/iosinst.cxx
+++ b/vcl/ios/iosinst.cxx
@@ -146,7 +146,7 @@ void SalData::ensureThreadAutoreleasePool() {}
 
 extern "C" SalInstance *create_SalInstance()
 {
-    IosSalInstance* pInstance = new IosSalInstance( 
std::make_unique<SalYieldMutex>() );
+    IosSalInstance* pInstance = new IosSalInstance( 
std::make_unique<SvpSalYieldMutex>() );
     new SvpSalData(pInstance);
     return pInstance;
 }
diff --git a/vcl/source/app/salplug.cxx b/vcl/source/app/salplug.cxx
index bf0815567ca2..378187dbfedc 100644
--- a/vcl/source/app/salplug.cxx
+++ b/vcl/source/app/salplug.cxx
@@ -82,7 +82,7 @@ namespace {
 #if ENABLE_HEADLESS
 SalInstance* svp_create_SalInstance()
 {
-    SvpSalInstance* pInstance = new 
SvpSalInstance(std::make_unique<SalYieldMutex>());
+    SvpSalInstance* pInstance = new 
SvpSalInstance(std::make_unique<SvpSalYieldMutex>());
     new SvpSalData();
     return pInstance;
 }

Reply via email to