diff options
31 files changed, 335 insertions, 569 deletions
diff --git a/comphelper/source/misc/solarmutex.cxx b/comphelper/source/misc/solarmutex.cxx index 4b573078dffd..1501228b1bc6 100644 --- a/comphelper/source/misc/solarmutex.cxx +++ b/comphelper/source/misc/solarmutex.cxx @@ -18,9 +18,12 @@ */ #include <sal/config.h> -#include <assert.h> + #include <comphelper/solarmutex.hxx> +#include <assert.h> +#include <cstdlib> + namespace comphelper { SolarMutex::SolarMutex() {} @@ -42,6 +45,67 @@ SolarMutex *SolarMutex::get() return pSolarMutex; } +GenericSolarMutex::GenericSolarMutex() + : m_nCount( 0 ) + , m_nThreadId( 0 ) + , m_aBeforeReleaseHandler( nullptr ) +{ + setSolarMutex( this ); +} + +GenericSolarMutex::~GenericSolarMutex() +{ + setSolarMutex( nullptr ); +} + +void GenericSolarMutex::doAcquire( const sal_uInt32 nLockCount ) +{ + for ( sal_uInt32 n = nLockCount; n ; --n ) + m_aMutex.acquire(); + m_nThreadId = osl::Thread::getCurrentIdentifier(); + m_nCount += nLockCount; +} + +sal_uInt32 GenericSolarMutex::doRelease( bool bUnlockAll ) +{ + if ( m_nCount == 0 ) + std::abort(); + if ( m_nThreadId != osl::Thread::getCurrentIdentifier() ) + std::abort(); + + const sal_uInt32 nCount = bUnlockAll ? m_nCount : 1; + m_nCount -= nCount; + + if ( 0 == m_nCount ) + { + if ( m_aBeforeReleaseHandler ) + m_aBeforeReleaseHandler(); + m_nThreadId = 0; + } + + for ( sal_uInt32 n = nCount ; n ; --n ) + m_aMutex.release(); + + return nCount; +} + +bool GenericSolarMutex::IsCurrentThread() const +{ + return m_nThreadId == osl::Thread::getCurrentIdentifier(); +} + +bool GenericSolarMutex::tryToAcquire() +{ + if ( m_aMutex.tryToAcquire() ) + { + m_nThreadId = osl::Thread::getCurrentIdentifier(); + m_nCount++; + return true; + } + else + return false; +} + } // namespace comphelper /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/dbaccess/source/core/dataaccess/ModelImpl.cxx b/dbaccess/source/core/dataaccess/ModelImpl.cxx index bbbe69d5f52f..3ddffa4caa52 100644 --- a/dbaccess/source/core/dataaccess/ModelImpl.cxx +++ b/dbaccess/source/core/dataaccess/ModelImpl.cxx @@ -92,14 +92,17 @@ VosMutexFacade::VosMutexFacade( ::osl::Mutex& _rMutex ) { } -void VosMutexFacade::acquire() +void VosMutexFacade::doAcquire( sal_uInt32 nLockCount ) { + assert( 1 == nLockCount ); (void) nLockCount; m_rMutex.acquire(); } -void VosMutexFacade::release() +sal_uInt32 VosMutexFacade::doRelease( bool bUnlockAll ) { + assert( !bUnlockAll ); (void) bUnlockAll; m_rMutex.release(); + return 1; } bool VosMutexFacade::tryToAcquire() @@ -107,6 +110,11 @@ bool VosMutexFacade::tryToAcquire() return m_rMutex.tryToAcquire(); } +bool VosMutexFacade::IsCurrentThread() const +{ + return true; +} + // DocumentStorageAccess class DocumentStorageAccess : public ::cppu::WeakImplHelper< XDocumentSubStorageSupplier , XTransactionListener > diff --git a/dbaccess/source/core/dataaccess/ModelImpl.hxx b/dbaccess/source/core/dataaccess/ModelImpl.hxx index 130bb5493a10..034e1bbd4b8d 100644 --- a/dbaccess/source/core/dataaccess/ModelImpl.hxx +++ b/dbaccess/source/core/dataaccess/ModelImpl.hxx @@ -118,7 +118,7 @@ class ODatabaseContext; class OSharedConnectionManager; // VosMutexFacade -/** a class which provides an IMutex interface to an OSL-based mutex +/** a class which provides an SolarMutex interface to an OSL-based mutex */ class VosMutexFacade : public comphelper::SolarMutex { @@ -128,9 +128,12 @@ public: */ explicit VosMutexFacade( ::osl::Mutex& _rMutex ); - virtual void acquire() override; - virtual void release() override; virtual bool tryToAcquire() override; + virtual bool IsCurrentThread() const override; + +protected: + virtual void doAcquire( sal_uInt32 nLockCount ) override; + virtual sal_uInt32 doRelease( bool bUnlockAll ) override; private: ::osl::Mutex& m_rMutex; diff --git a/include/comphelper/solarmutex.hxx b/include/comphelper/solarmutex.hxx index 48453de915e4..76aea3fa336f 100644 --- a/include/comphelper/solarmutex.hxx +++ b/include/comphelper/solarmutex.hxx @@ -22,10 +22,13 @@ #include <sal/config.h> +#include <osl/thread.hxx> +#include <osl/mutex.hxx> #include <comphelper/comphelperdllapi.h> namespace comphelper { + /** * Abstract SolarMutex interface, needed for VCL's * Application::GetSolarMutex(). @@ -37,29 +40,82 @@ namespace comphelper { */ class COMPHELPER_DLLPUBLIC SolarMutex { public: - virtual void acquire() = 0; - - virtual void release() = 0; + void acquire( sal_uInt32 nLockCount = 1 ); + sal_uInt32 release( bool bUnlockAll = false ); virtual bool tryToAcquire() = 0; + // returns true, if the mutex is owned by the current thread + virtual bool IsCurrentThread() const = 0; + /// Help components to get the SolarMutex easily. static SolarMutex *get(); - /// semi-private: allow VCL to push its one-big-lock down here. - static void setSolarMutex( SolarMutex *pMutex ); - protected: SolarMutex(); - virtual ~SolarMutex(); + + /// allow VCL to push its one-big-lock down here. + static void setSolarMutex( SolarMutex *pMutex ); + + virtual sal_uInt32 doRelease( bool bUnlockAll ) = 0; + virtual void doAcquire( sal_uInt32 nLockCount ) = 0; + private: SolarMutex(const SolarMutex&) = delete; SolarMutex& operator=(const SolarMutex&) = delete; }; +inline void SolarMutex::acquire( sal_uInt32 nLockCount ) +{ + assert( nLockCount > 0 ); + doAcquire( nLockCount ); +} + +inline sal_uInt32 SolarMutex::release( bool bUnlockAll ) +{ + return doRelease( bUnlockAll ); +} + + +/** + * Generic implementation of the abstract SolarMutex interface. + * + * Treat this as a singleton, as its constructor calls + * setSolarMutex( this )! + * + * Kept seperately from SolarMutex, so others can implement fascades. + */ +class COMPHELPER_DLLPUBLIC GenericSolarMutex + : public SolarMutex +{ +public: + typedef void (*BeforeReleaseHandler) (); + + void SetBeforeReleaseHandler( const BeforeReleaseHandler& rLink ) + { m_aBeforeReleaseHandler = rLink; } + + virtual bool tryToAcquire() override; + virtual bool IsCurrentThread() const override; + +protected: + osl::Mutex m_aMutex; + sal_uInt32 m_nCount; + oslThreadIdentifier m_nThreadId; + + virtual void doAcquire( sal_uInt32 nLockCount ) override; + virtual sal_uInt32 doRelease( bool bUnlockAll ) override; + +protected: + GenericSolarMutex(); + virtual ~GenericSolarMutex() override; + +private: + BeforeReleaseHandler m_aBeforeReleaseHandler; +}; + } -#endif +#endif // INCLUDED_COMPHELPER_SOLARMUTEX_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx index 7bdb4daccfb6..1d016044335e 100644 --- a/include/vcl/svapp.hxx +++ b/include/vcl/svapp.hxx @@ -28,6 +28,7 @@ #include <vector> #include <comphelper/solarmutex.hxx> +#include <osl/mutex.hxx> #include <rtl/ustring.hxx> #include <osl/thread.hxx> #include <tools/gen.hxx> @@ -531,7 +532,7 @@ public: @see Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex, GetMainThreadIdentifier, AcquireSolarMutex, */ - static sal_uLong ReleaseSolarMutex(); + static sal_uInt32 ReleaseSolarMutex(); /** @brief Acquire Solar Mutex(es) for this thread. @@ -541,7 +542,7 @@ public: @see Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex, GetMainThreadIdentifier, ReleaseSolarMutex, */ - static void AcquireSolarMutex( sal_uLong nCount ); + static void AcquireSolarMutex( sal_uInt32 nCount ); /** Queries whether the application is in "main", i.e. not yet in the event loop @@ -1397,110 +1398,28 @@ private: DECL_STATIC_LINK( Application, PostEventHandler, void*, void ); }; - class VCL_DLLPUBLIC SolarMutexGuard + : public osl::Guard<comphelper::SolarMutex> { -private: - SolarMutexGuard( const SolarMutexGuard& ) = delete; - const SolarMutexGuard& operator = ( const SolarMutexGuard& ) = delete; - comphelper::SolarMutex& m_solarMutex; - public: - /** Acquires the object specified as parameter. - */ - SolarMutexGuard() : - m_solarMutex(Application::GetSolarMutex()) - { - m_solarMutex.acquire(); - } - - /** Releases the mutex or interface. */ - ~SolarMutexGuard() - { - m_solarMutex.release(); - } + SolarMutexGuard() + : osl::Guard<comphelper::SolarMutex>( Application::GetSolarMutex() ) {} }; -class VCL_DLLPUBLIC SolarMutexClearableGuard final +class VCL_DLLPUBLIC SolarMutexClearableGuard + : public osl::ClearableGuard<comphelper::SolarMutex> { - SolarMutexClearableGuard( const SolarMutexClearableGuard& ) = delete; - const SolarMutexClearableGuard& operator = ( const SolarMutexClearableGuard& ) = delete; - bool m_bCleared; - comphelper::SolarMutex& m_solarMutex; public: - /** Acquires mutex - */ SolarMutexClearableGuard() - : m_bCleared(false) - , m_solarMutex( Application::GetSolarMutex() ) - { - m_solarMutex.acquire(); - } - - /** Releases mutex. */ - ~SolarMutexClearableGuard() - { - if( !m_bCleared ) - { - m_solarMutex.release(); - } - } - - /** Releases mutex. */ - void SAL_CALL clear() - { - if( !m_bCleared ) - { - m_solarMutex.release(); - m_bCleared = true; - } - } + : osl::ClearableGuard<comphelper::SolarMutex>( Application::GetSolarMutex() ) {} }; -class VCL_DLLPUBLIC SolarMutexResettableGuard final +class VCL_DLLPUBLIC SolarMutexResettableGuard + : public osl::ResettableGuard<comphelper::SolarMutex> { - SolarMutexResettableGuard( const SolarMutexResettableGuard& ) = delete; - const SolarMutexResettableGuard& operator = ( const SolarMutexResettableGuard& ) = delete; - bool m_bCleared; - comphelper::SolarMutex& m_solarMutex; public: - /** Acquires mutex - */ SolarMutexResettableGuard() - : m_bCleared(false) - , m_solarMutex( Application::GetSolarMutex() ) - { - m_solarMutex.acquire(); - } - - /** Releases mutex. */ - ~SolarMutexResettableGuard() - { - if( !m_bCleared ) - { - m_solarMutex.release(); - } - } - - /** Releases mutex. */ - void SAL_CALL clear() - { - if( !m_bCleared) - { - m_solarMutex.release(); - m_bCleared = true; - } - } - - /** Re-acquires mutex. */ - void SAL_CALL reset() - { - if( m_bCleared) - { - m_solarMutex.acquire(); - m_bCleared = false; - } - } + : osl::ResettableGuard<comphelper::SolarMutex>( Application::GetSolarMutex() ) {} }; namespace vcl @@ -1559,15 +1478,10 @@ public: */ class SolarMutexReleaser { - sal_uLong mnReleased; - + const sal_uInt32 mnReleased; public: SolarMutexReleaser(): mnReleased(Application::ReleaseSolarMutex()) {} - - ~SolarMutexReleaser() - { - Application::ReAcquireSolarMutex(mnReleased); - } + ~SolarMutexReleaser() { Application::ReAcquireSolarMutex(mnReleased); } }; VCL_DLLPUBLIC Application* GetpApp(); diff --git a/vcl/android/androidinst.cxx b/vcl/android/androidinst.cxx index a2cb49cb60aa..afb919a2e4e9 100644 --- a/vcl/android/androidinst.cxx +++ b/vcl/android/androidinst.cxx @@ -191,13 +191,13 @@ SalInstance *CreateSalInstance() LOGI("Android: CreateSalInstance!"); AndroidSalInstance* pInstance = new AndroidSalInstance( new SalYieldMutex() ); new AndroidSalData( pInstance ); - pInstance->AcquireYieldMutex(1); + pInstance->AcquireYieldMutex(); return pInstance; } void DestroySalInstance( SalInstance *pInst ) { - pInst->ReleaseYieldMutex(); + pInst->ReleaseYieldMutex( true ); delete pInst; } diff --git a/vcl/headless/headlessinst.cxx b/vcl/headless/headlessinst.cxx index e6f5cf03f5b3..69027f3ccb3c 100644 --- a/vcl/headless/headlessinst.cxx +++ b/vcl/headless/headlessinst.cxx @@ -92,13 +92,13 @@ SalInstance *CreateSalInstance() { HeadlessSalInstance* pInstance = new HeadlessSalInstance( new SalYieldMutex() ); new HeadlessSalData( pInstance ); - pInstance->AcquireYieldMutex(1); + pInstance->AcquireYieldMutex(); return pInstance; } void DestroySalInstance( SalInstance *pInst ) { - pInst->ReleaseYieldMutex(); + pInst->ReleaseYieldMutex( true ); delete pInst; } diff --git a/vcl/headless/svpinst.cxx b/vcl/headless/svpinst.cxx index 20d92e55c82e..d64d944a8802 100644 --- a/vcl/headless/svpinst.cxx +++ b/vcl/headless/svpinst.cxx @@ -389,7 +389,7 @@ void SvpSalInstance::DoReleaseYield( int nTimeoutMS ) aPoll.revents = 0; // release yield mutex - sal_uLong nAcquireCount = ReleaseYieldMutex(); + sal_uInt32 nAcquireCount = ReleaseYieldMutex( true ); (void)poll( &aPoll, 1, nTimeoutMS ); diff --git a/vcl/inc/osx/salinst.h b/vcl/inc/osx/salinst.h index bd02608d4d45..263b9027b956 100644 --- a/vcl/inc/osx/salinst.h +++ b/vcl/inc/osx/salinst.h @@ -37,19 +37,15 @@ class ApplicationEvent; class Image; enum class SalEvent; -class SalYieldMutex : public comphelper::SolarMutex +class SalYieldMutex : public comphelper::GenericSolarMutex { - osl::Mutex m_mutex; - sal_uLong mnCount; - oslThreadIdentifier mnThreadId; +protected: + virtual void doAcquire( sal_uInt32 nLockCount ) override; + virtual sal_uInt32 doRelease( bool bUnlockAll ) override; public: - SalYieldMutex(); - virtual void acquire() override; - virtual void release() override; - virtual bool tryToAcquire() override; - sal_uLong GetAcquireCount() const { return mnCount; } - oslThreadIdentifier GetThreadId() const { return mnThreadId; } + SalYieldMutex(); + virtual ~SalYieldMutex(); }; class AquaSalInstance : public SalInstance @@ -105,9 +101,8 @@ public: virtual SalSystem* CreateSalSystem() override; virtual SalBitmap* CreateSalBitmap() override; virtual comphelper::SolarMutex* GetYieldMutex() override; - virtual sal_uLong ReleaseYieldMutex() override; - virtual void AcquireYieldMutex( sal_uLong nCount ) override; - virtual bool CheckYieldMutex() override; + virtual sal_uInt32 ReleaseYieldMutex( bool bUnlockAll = false ) override; + virtual void AcquireYieldMutex( sal_uInt32 nCount = 1 ) override; virtual bool DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong nReleased) override; virtual bool AnyInput( VclInputFlags nType ) override; @@ -159,15 +154,6 @@ public: static NSMenu* GetDynamicDockMenu(); }; -// helper class: inverted solar guard -class YieldMutexReleaser -{ - sal_uLong mnCount; - public: - YieldMutexReleaser(); - ~YieldMutexReleaser(); -}; - CGImageRef CreateCGImage( const Image& ); NSImage* CreateNSImage( const Image& ); diff --git a/vcl/inc/salinst.hxx b/vcl/inc/salinst.hxx index 03491553c62a..12959cc44280 100644 --- a/vcl/inc/salinst.hxx +++ b/vcl/inc/salinst.hxx @@ -25,6 +25,7 @@ #include <tools/solar.h> #include <vcl/dllapi.h> #include <vcl/salgtype.hxx> +#include <osl/thread.hxx> #include "displayconnectiondispatch.hxx" @@ -121,10 +122,9 @@ public: // YieldMutex virtual comphelper::SolarMutex* GetYieldMutex() = 0; - virtual sal_uLong ReleaseYieldMutex() = 0; - virtual void AcquireYieldMutex( sal_uLong nCount ) = 0; + virtual sal_uInt32 ReleaseYieldMutex( bool bUnlockAll = false ) = 0; + virtual void AcquireYieldMutex( sal_uInt32 nCount = 1 ) = 0; // return true, if yield mutex is owned by this thread, else false - virtual bool CheckYieldMutex() = 0; virtual bool IsMainThread() const = 0; /** diff --git a/vcl/inc/unx/geninst.h b/vcl/inc/unx/geninst.h index 2c99a7b3e0a1..c432dbecabfb 100644 --- a/vcl/inc/unx/geninst.h +++ b/vcl/inc/unx/geninst.h @@ -28,42 +28,11 @@ #include <saldatabasic.hxx> #include "unx/genprn.h" -class VCL_DLLPUBLIC SalYieldMutexReleaser +class VCL_DLLPUBLIC SalYieldMutex : public comphelper::GenericSolarMutex { - sal_uLong m_nYieldCount; public: - inline SalYieldMutexReleaser(); - inline ~SalYieldMutexReleaser(); -}; - -inline SalYieldMutexReleaser::SalYieldMutexReleaser() -{ - m_nYieldCount = GetSalData()->m_pInstance->ReleaseYieldMutex(); -} - -inline SalYieldMutexReleaser::~SalYieldMutexReleaser() -{ - GetSalData()->m_pInstance->AcquireYieldMutex( m_nYieldCount ); -} - -class VCL_DLLPUBLIC SalYieldMutex : public comphelper::SolarMutex -{ - osl::Mutex m_mutex; - -protected: - sal_uIntPtr mnCount; - oslThreadIdentifier mnThreadId; - -public: - SalYieldMutex(); - virtual ~SalYieldMutex() override; - - virtual void acquire() override; - virtual void release() override; - virtual bool tryToAcquire() override; - - sal_uIntPtr GetAcquireCount() const { return mnCount; } - oslThreadIdentifier GetThreadId() const { return mnThreadId; } + SalYieldMutex(); + virtual ~SalYieldMutex() override; }; /* @@ -84,9 +53,8 @@ public: // Yield mutex virtual comphelper::SolarMutex* GetYieldMutex() override; - virtual sal_uIntPtr ReleaseYieldMutex() override; - virtual void AcquireYieldMutex( sal_uIntPtr nCount ) override; - virtual bool CheckYieldMutex() override; + virtual sal_uInt32 ReleaseYieldMutex( bool bUnlockAll = false ) override; + virtual void AcquireYieldMutex( sal_uInt32 nCount = 1 ) override; // Printing virtual SalInfoPrinter* CreateInfoPrinter ( SalPrinterQueueInfo* pQueueInfo, diff --git a/vcl/inc/win/saldata.hxx b/vcl/inc/win/saldata.hxx index 4d8361d57325..bc5b9c5db1eb 100644 --- a/vcl/inc/win/saldata.hxx +++ b/vcl/inc/win/saldata.hxx @@ -172,11 +172,9 @@ bool ImplLoadSalIcon( int nId, HICON& rIcon, HICON& rSmallIcon ); void ImplInitSalGDI(); void ImplFreeSalGDI(); -void ImplSalYieldMutexAcquireWithWait( sal_uLong nCount = 1 ); +void ImplSalYieldMutexAcquireWithWait( sal_uInt32 nCount = 1 ); bool ImplSalYieldMutexTryToAcquire(); void ImplSalYieldMutexRelease(); -sal_uLong ImplSalReleaseYieldMutex(); -void ImplSalAcquireYieldMutex( sal_uLong nCount ); LRESULT CALLBACK SalFrameWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ); diff --git a/vcl/inc/win/salinst.h b/vcl/inc/win/salinst.h index 03ba573c523b..6efecbd6bd5e 100644 --- a/vcl/inc/win/salinst.h +++ b/vcl/inc/win/salinst.h @@ -59,9 +59,8 @@ public: virtual SalSystem* CreateSalSystem() override; virtual SalBitmap* CreateSalBitmap() override; virtual comphelper::SolarMutex* GetYieldMutex() override; - virtual sal_uIntPtr ReleaseYieldMutex() override; - virtual void AcquireYieldMutex( sal_uIntPtr nCount ) override; - virtual bool CheckYieldMutex() override; + virtual sal_uInt32 ReleaseYieldMutex( bool bUnlockAll = false ) override; + virtual void AcquireYieldMutex( sal_uInt32 nCount = 1 ) override; virtual bool IsMainThread() const override; virtual bool DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong nReleased) override; diff --git a/vcl/inc/win/salprn.h b/vcl/inc/win/salprn.h index a483e2502cc7..ed6005283661 100644 --- a/vcl/inc/win/salprn.h +++ b/vcl/inc/win/salprn.h @@ -84,6 +84,9 @@ public: bool mbValid; +protected: + void DoEndDoc(HDC hDC); + public: WinSalPrinter(); virtual ~WinSalPrinter() override; diff --git a/vcl/ios/iosinst.cxx b/vcl/ios/iosinst.cxx index b4b6f1f9f0bd..fb2d79b2fd59 100644 --- a/vcl/ios/iosinst.cxx +++ b/vcl/ios/iosinst.cxx @@ -172,13 +172,13 @@ SalInstance *CreateSalInstance() { IosSalInstance* pInstance = new IosSalInstance( new SalYieldMutex() ); new IosSalData( pInstance ); - pInstance->AcquireYieldMutex(1); + pInstance->AcquireYieldMutex(); return pInstance; } void DestroySalInstance( SalInstance *pInst ) { - pInst->ReleaseYieldMutex(); + pInst->ReleaseYieldMutex( true ); delete pInst; } diff --git a/vcl/osx/salframeview.mm b/vcl/osx/salframeview.mm index 35f55c6e2f17..184c5bc15b70 100644 --- a/vcl/osx/salframeview.mm +++ b/vcl/osx/salframeview.mm @@ -223,13 +223,8 @@ static AquaSalFrame* getMouseContainerFrame() { if( GetSalData() && GetSalData()->mpFirstInstance ) { - comphelper::SolarMutex* pMutex = GetSalData()->mpFirstInstance->GetYieldMutex(); - if( pMutex ) - { - pMutex->acquire(); - [super displayIfNeeded]; - pMutex->release(); - } + SolarMutexGuard aGuard; + [super displayIfNeeded]; } } diff --git a/vcl/osx/salinst.cxx b/vcl/osx/salinst.cxx index e16e73945c2d..aa274e8292f3 100644 --- a/vcl/osx/salinst.cxx +++ b/vcl/osx/salinst.cxx @@ -259,41 +259,20 @@ void InitSalMain() SalYieldMutex::SalYieldMutex() { - mnCount = 0; - mnThreadId = 0; } -void SalYieldMutex::acquire() +SalYieldMutex::~SalYieldMutex() { - m_mutex.acquire(); - mnThreadId = osl::Thread::getCurrentIdentifier(); - mnCount++; } -void SalYieldMutex::release() +void SalYieldMutex::doAcquire( sal_uInt32 nLockCount ) { - if ( mnThreadId == osl::Thread::getCurrentIdentifier() ) - { - if ( mnCount == 1 ) - { - // TODO: add OpenGLContext::prepareForYield with vcl OpenGL support - mnThreadId = 0; - } - mnCount--; - } - m_mutex.release(); + comphelper::GenericSolarMutex::doAcquire( nLockCount ); } -bool SalYieldMutex::tryToAcquire() +sal_uInt32 SalYieldMutex::doRelease( const bool bUnlockAll ) { - if ( m_mutex.tryToAcquire() ) - { - mnThreadId = osl::Thread::getCurrentIdentifier(); - mnCount++; - return true; - } - else - return false; + return comphelper::GenericSolarMutex::doRelease( bUnlockAll ); } // some convenience functions regarding the yield mutex, aka solar mutex @@ -351,7 +330,6 @@ AquaSalInstance::AquaSalInstance() { mpSalYieldMutex = new SalYieldMutex; mpSalYieldMutex->acquire(); - ::comphelper::SolarMutex::setSolarMutex( mpSalYieldMutex ); maMainThread = osl::Thread::getCurrentIdentifier(); mbWaitingYield = false; mnActivePrintJobs = 0; @@ -359,7 +337,6 @@ AquaSalInstance::AquaSalInstance() AquaSalInstance::~AquaSalInstance() { - ::comphelper::SolarMutex::setSolarMutex( nullptr ); mpSalYieldMutex->release(); delete mpSalYieldMutex; } @@ -386,47 +363,14 @@ comphelper::SolarMutex* AquaSalInstance::GetYieldMutex() return mpSalYieldMutex; } -sal_uLong AquaSalInstance::ReleaseYieldMutex() -{ - SalYieldMutex* pYieldMutex = mpSalYieldMutex; - if ( pYieldMutex->GetThreadId() == - osl::Thread::getCurrentIdentifier() ) - { - sal_uLong nCount = pYieldMutex->GetAcquireCount(); - sal_uLong n = nCount; - while ( n ) - { - pYieldMutex->release(); - n--; - } - - return nCount; - } - else - return 0; -} - -void AquaSalInstance::AcquireYieldMutex( sal_uLong nCount ) +sal_uInt32 AquaSalInstance::ReleaseYieldMutex( bool bUnlockAll ) { - SalYieldMutex* pYieldMutex = mpSalYieldMutex; - while ( nCount ) - { - pYieldMutex->acquire(); - nCount--; - } + return mpSalYieldMutex->release( bUnlockAll ); } -bool AquaSalInstance::CheckYieldMutex() +void AquaSalInstance::AcquireYieldMutex( sal_uInt32 nCount ) { - bool bRet = true; - - SalYieldMutex* pYieldMutex = mpSalYieldMutex; - if ( pYieldMutex->GetThreadId() != osl::Thread::getCurrentIdentifier()) - { - bRet = false; - } - - return bRet; + mpSalYieldMutex->acquire( nCount ); } bool AquaSalInstance::IsMainThread() const @@ -596,7 +540,7 @@ bool AquaSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLon NSEvent* pEvent = nil; do { - sal_uLong nCount = ReleaseYieldMutex(); + SolarMutexReleaser aReleaser; SAL_WNODEPRECATED_DECLARATIONS_PUSH // 'NSAnyEventMask' is deprecated: first deprecated in macOS 10.12 @@ -610,15 +554,15 @@ SAL_WNODEPRECATED_DECLARATIONS_POP [NSApp sendEvent: pEvent]; bHadEvent = true; } - [NSApp updateWindows]; - AcquireYieldMutex( nCount ); - } while( bHandleAllCurrentEvents && pEvent ); + [NSApp updateWindows]; + } + while( bHandleAllCurrentEvents && pEvent ); // if we had no event yet, wait for one if requested if( bWait && ! bHadEvent ) { - sal_uLong nCount = ReleaseYieldMutex(); + SolarMutexReleaser aReleaser; NSDate* pDt = AquaSalTimer::pRunningTimer ? [AquaSalTimer::pRunningTimer fireDate] : [NSDate distantFuture]; SAL_WNODEPRECATED_DECLARATIONS_PUSH @@ -631,8 +575,6 @@ SAL_WNODEPRECATED_DECLARATIONS_POP if( pEvent ) [NSApp sendEvent: pEvent]; [NSApp updateWindows]; - - AcquireYieldMutex( nCount ); } mbWaitingYield = bOldWaitingYield; @@ -656,9 +598,8 @@ SAL_WNODEPRECATED_DECLARATIONS_POP // has dispatched an event, cop out at 200 ms maWaitingYieldCond.reset(); TimeValue aVal = { 0, 200000000 }; - sal_uLong nCount = ReleaseYieldMutex(); + SolarMutexReleaser aReleaser; maWaitingYieldCond.wait( &aVal ); - AcquireYieldMutex( nCount ); } // we get some apple events way too early @@ -982,23 +923,6 @@ OUString AquaSalInstance::getOSVersion() return aVersion; } -// YieldMutexReleaser -YieldMutexReleaser::YieldMutexReleaser() : mnCount( 0 ) -{ - SalData* pSalData = GetSalData(); - if( ! pSalData->mpFirstInstance->IsMainThread() ) - { - SalData::ensureThreadAutoreleasePool(); - mnCount = pSalData->mpFirstInstance->ReleaseYieldMutex(); - } -} - -YieldMutexReleaser::~YieldMutexReleaser() -{ - if( mnCount != 0 ) - GetSalData()->mpFirstInstance->AcquireYieldMutex( mnCount ); -} - CGImageRef CreateCGImage( const Image& rImage ) { BitmapEx aBmpEx( rImage.GetBitmapEx() ); diff --git a/vcl/source/app/dbggui.cxx b/vcl/source/app/dbggui.cxx index b191ae9a5b9d..f2ebc5117ddd 100644 --- a/vcl/source/app/dbggui.cxx +++ b/vcl/source/app/dbggui.cxx @@ -44,7 +44,7 @@ using namespace ::com::sun::star; void ImplDbgTestSolarMutex() { - assert(ImplGetSVData()->mpDefInst->CheckYieldMutex() && "SolarMutex not locked"); + assert(ImplGetSVData()->mpDefInst->GetYieldMutex()->IsCurrentThread() && "SolarMutex not owned!"); } void DbgGUIInitSolarMutexCheck() diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index 9e5a47097093..3107e88d3c91 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -581,13 +581,13 @@ oslThreadIdentifier Application::GetMainThreadIdentifier() return ImplGetSVData()->mnMainThreadId; } -sal_uLong Application::ReleaseSolarMutex() +sal_uInt32 Application::ReleaseSolarMutex() { ImplSVData* pSVData = ImplGetSVData(); - return pSVData->mpDefInst->ReleaseYieldMutex(); + return pSVData->mpDefInst->ReleaseYieldMutex( true ); } -void Application::AcquireSolarMutex( sal_uLong nCount ) +void Application::AcquireSolarMutex( sal_uInt32 nCount ) { ImplSVData* pSVData = ImplGetSVData(); pSVData->mpDefInst->AcquireYieldMutex( nCount ); diff --git a/vcl/unx/generic/app/geninst.cxx b/vcl/unx/generic/app/geninst.cxx index 29b4c754da84..d80c0499554c 100644 --- a/vcl/unx/generic/app/geninst.cxx +++ b/vcl/unx/generic/app/geninst.cxx @@ -39,48 +39,13 @@ SalYieldMutex::SalYieldMutex() { - mnCount = 0; - mnThreadId = 0; - ::comphelper::SolarMutex::setSolarMutex( this ); -} - -SalYieldMutex::~SalYieldMutex() -{ - ::comphelper::SolarMutex::setSolarMutex( nullptr ); -} - -void SalYieldMutex::acquire() -{ - m_mutex.acquire(); - mnThreadId = osl::Thread::getCurrentIdentifier(); - mnCount++; -} - -void SalYieldMutex::release() -{ - assert(mnCount != 0); - assert(mnThreadId == osl::Thread::getCurrentIdentifier()); - if ( mnCount == 1 ) - { #if HAVE_FEATURE_OPENGL - OpenGLContext::prepareForYield(); + SetBeforeReleaseHandler( &OpenGLContext::prepareForYield ); #endif - mnThreadId = 0; - } - mnCount--; - m_mutex.release(); } -bool SalYieldMutex::tryToAcquire() +SalYieldMutex::~SalYieldMutex() { - if ( m_mutex.tryToAcquire() ) - { - mnThreadId = osl::Thread::getCurrentIdentifier(); - mnCount++; - return true; - } - else - return false; } comphelper::SolarMutex* SalGenericInstance::GetYieldMutex() @@ -88,48 +53,14 @@ comphelper::SolarMutex* SalGenericInstance::GetYieldMutex() return mpSalYieldMutex.get(); } -sal_uLong SalGenericInstance::ReleaseYieldMutex() +sal_uInt32 SalGenericInstance::ReleaseYieldMutex( bool bUnlockAll ) { - SalYieldMutex* pYieldMutex = mpSalYieldMutex.get(); - if ( pYieldMutex->GetThreadId() == - osl::Thread::getCurrentIdentifier() ) - { - sal_uLong nCount = pYieldMutex->GetAcquireCount(); - sal_uLong n = nCount; - while ( n ) - { - pYieldMutex->release(); - n--; - } - - return nCount; - } - else - return 0; -} - -void SalGenericInstance::AcquireYieldMutex( sal_uLong nCount ) -{ - SalYieldMutex* pYieldMutex = mpSalYieldMutex.get(); - while ( nCount ) - { - pYieldMutex->acquire(); - nCount--; - } + return mpSalYieldMutex.get()->release( bUnlockAll ); } -bool SalGenericInstance::CheckYieldMutex() +void SalGenericInstance::AcquireYieldMutex( sal_uInt32 nCount ) { - bool bRet = true; - - SalYieldMutex* pYieldMutex = mpSalYieldMutex.get(); - if ( pYieldMutex->GetThreadId() != osl::Thread::getCurrentIdentifier() ) - { - SAL_WARN("vcl", "CheckYieldMutex: " << pYieldMutex->GetThreadId() << "!=" << osl::Thread::getCurrentIdentifier() ); - bRet = false; - } - - return bRet; + mpSalYieldMutex.get()->acquire( nCount ); } SalGenericInstance::~SalGenericInstance() diff --git a/vcl/unx/generic/app/saldata.cxx b/vcl/unx/generic/app/saldata.cxx index e753184b0bef..b8d6de519ff0 100644 --- a/vcl/unx/generic/app/saldata.cxx +++ b/vcl/unx/generic/app/saldata.cxx @@ -709,7 +709,7 @@ SalXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) { // release YieldMutex (and re-acquire at block end) - SalYieldMutexReleaser aReleaser; + SolarMutexReleaser aReleaser; nFound = select( nFDs, &ReadFDS, nullptr, &ExceptionFDS, pTimeout ); } if( nFound < 0 ) // error diff --git a/vcl/unx/generic/app/saldisp.cxx b/vcl/unx/generic/app/saldisp.cxx index d6958f9c407a..e5980e5f9e43 100644 --- a/vcl/unx/generic/app/saldisp.cxx +++ b/vcl/unx/generic/app/saldisp.cxx @@ -378,9 +378,8 @@ static int DisplayHasEvent( int fd, void * data ) bool result; - GetSalData()->m_pInstance->GetYieldMutex()->acquire(); + SolarMutexGuard aGuard; result = pDisplay->IsEvent(); - GetSalData()->m_pInstance->GetYieldMutex()->release(); return int(result); } static int DisplayQueue( int fd, void * data ) @@ -390,11 +389,9 @@ static int DisplayQueue( int fd, void * data ) "wrong fd in DisplayHasEvent" ); int result; - GetSalData()->m_pInstance->GetYieldMutex()->acquire(); + SolarMutexGuard aGuard; result = XEventsQueued( pDisplay->GetDisplay(), QueuedAfterReading ); - GetSalData()->m_pInstance->GetYieldMutex()->release(); - return result; } static int DisplayYield( int fd, void * data ) @@ -403,9 +400,8 @@ static int DisplayYield( int fd, void * data ) SAL_WARN_IF( ConnectionNumber( pDisplay->GetDisplay() ) != fd, "vcl", "wrong fd in DisplayHasEvent" ); - GetSalData()->m_pInstance->GetYieldMutex()->acquire(); + SolarMutexGuard aGuard; pDisplay->Yield(); - GetSalData()->m_pInstance->GetYieldMutex()->release(); return 1; } @@ -1911,8 +1907,7 @@ void SalX11Display::Yield() return; XEvent aEvent; - DBG_ASSERT( static_cast<SalYieldMutex*>(GetSalData()->m_pInstance->GetYieldMutex())->GetThreadId() == - osl::Thread::getCurrentIdentifier(), + DBG_ASSERT( GetSalData()->m_pInstance->GetYieldMutex()->IsCurrentThread(), "will crash soon since solar mutex not locked in SalDisplay::Yield" ); XNextEvent( pDisp_, &aEvent ); diff --git a/vcl/unx/generic/plugadapt/salplug.cxx b/vcl/unx/generic/plugadapt/salplug.cxx index 71061742a7d7..441f16ddb113 100644 --- a/vcl/unx/generic/plugadapt/salplug.cxx +++ b/vcl/unx/generic/plugadapt/salplug.cxx @@ -256,7 +256,7 @@ SalInstance *CreateSalInstance() } // acquire SolarMutex - pInst->AcquireYieldMutex( 1 ); + pInst->AcquireYieldMutex(); return pInst; } @@ -264,7 +264,7 @@ SalInstance *CreateSalInstance() void DestroySalInstance( SalInstance *pInst ) { // release SolarMutex - pInst->ReleaseYieldMutex(); + pInst->ReleaseYieldMutex( true ); delete pInst; if( pCloseModule ) diff --git a/vcl/unx/gtk/gtkdata.cxx b/vcl/unx/gtk/gtkdata.cxx index 4eb6b6c2de8f..a8a0322856df 100644 --- a/vcl/unx/gtk/gtkdata.cxx +++ b/vcl/unx/gtk/gtkdata.cxx @@ -471,7 +471,7 @@ bool GtkData::Yield( bool bWait, bool bHandleAllCurrentEvents ) bool bWasEvent = false; { // release YieldMutex (and re-acquire at block end) - SalYieldMutexReleaser aReleaser; + SolarMutexReleaser aReleaser; if( m_aDispatchMutex.tryToAcquire() ) bDispatchThread = true; else if( ! bWait ) @@ -726,9 +726,7 @@ extern "C" { if( !pTSource->pInstance ) return FALSE; - GtkData *pSalData = static_cast< GtkData* >( GetSalData()); - - osl::Guard< comphelper::SolarMutex > aGuard( pSalData->m_pInstance->GetYieldMutex() ); + SolarMutexGuard aGuard; sal_gtk_timeout_defer( pTSource ); @@ -822,7 +820,7 @@ gboolean GtkData::userEventFn( gpointer data ) gboolean bContinue = FALSE; GtkData *pThis = static_cast<GtkData *>(data); SalGenericData *pData = GetGenericData(); - osl::Guard< comphelper::SolarMutex > aGuard( pData->m_pInstance->GetYieldMutex() ); + SolarMutexGuard aGuard; const SalGenericDisplay *pDisplay = pData->GetDisplay(); if (pDisplay) { diff --git a/vcl/unx/gtk/gtkinst.cxx b/vcl/unx/gtk/gtkinst.cxx index 8a45c62abc8b..eabae272c1d1 100644 --- a/vcl/unx/gtk/gtkinst.cxx +++ b/vcl/unx/gtk/gtkinst.cxx @@ -318,8 +318,8 @@ void GtkYieldMutex::ThreadsEnter() void GtkYieldMutex::ThreadsLeave() { - assert(mnCount != 0); - auto n = mnCount - 1; + assert(m_nCount != 0); + auto n = m_nCount - 1; yieldCounts.push(n); for (sal_uIntPtr i = 0; i != n + 1; ++i) { release(); diff --git a/vcl/unx/gtk3/gtk3gtkdata.cxx b/vcl/unx/gtk3/gtk3gtkdata.cxx index efa2e7fa3cf6..0690db4c1de1 100644 --- a/vcl/unx/gtk3/gtk3gtkdata.cxx +++ b/vcl/unx/gtk3/gtk3gtkdata.cxx @@ -447,7 +447,7 @@ bool GtkData::Yield( bool bWait, bool bHandleAllCurrentEvents ) bool bWasEvent = false; { // release YieldMutex (and re-acquire at block end) - SalYieldMutexReleaser aReleaser; + SolarMutexReleaser aReleaser; if( m_aDispatchMutex.tryToAcquire() ) bDispatchThread = true; else if( ! bWait ) @@ -688,9 +688,7 @@ extern "C" { if( !pTSource->pInstance ) return FALSE; - GtkData *pSalData = static_cast< GtkData* >( GetSalData()); - - osl::Guard< comphelper::SolarMutex > aGuard( pSalData->m_pInstance->GetYieldMutex() ); + SolarMutexGuard aGuard; sal_gtk_timeout_defer( pTSource ); @@ -784,7 +782,7 @@ gboolean GtkData::userEventFn( gpointer data ) gboolean bContinue = FALSE; GtkData *pThis = static_cast<GtkData *>(data); SalGenericData *pData = GetGenericData(); - osl::Guard< comphelper::SolarMutex > aGuard( pData->m_pInstance->GetYieldMutex() ); + SolarMutexGuard aGuard; const SalGenericDisplay *pDisplay = pData->GetDisplay(); if (pDisplay) { diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx index 133975da36f1..c004ef8d4a69 100644 --- a/vcl/unx/kde4/KDE4FilePicker.cxx +++ b/vcl/unx/kde4/KDE4FilePicker.cxx @@ -200,7 +200,7 @@ KDE4FilePicker::~KDE4FilePicker() void KDE4FilePicker::cleanupProxy() { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser aReleaser; + SolarMutexReleaser aReleaser; return Q_EMIT cleanupProxySignal(); } delete _dialog; @@ -221,7 +221,7 @@ void SAL_CALL KDE4FilePicker::removeFilePickerListener( const uno::Reference<XFi void SAL_CALL KDE4FilePicker::setTitle( const OUString &title ) { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser aReleaser; + SolarMutexReleaser aReleaser; return Q_EMIT setTitleSignal( title ); } @@ -231,7 +231,7 @@ void SAL_CALL KDE4FilePicker::setTitle( const OUString &title ) sal_Int16 SAL_CALL KDE4FilePicker::execute() { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser aReleaser; + SolarMutexReleaser aReleaser; return Q_EMIT executeSignal(); } @@ -267,7 +267,7 @@ sal_Int16 SAL_CALL KDE4FilePicker::execute() void SAL_CALL KDE4FilePicker::setMultiSelectionMode( sal_Bool multiSelect ) { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT setMultiSelectionModeSignal( multiSelect ); } @@ -290,7 +290,7 @@ void SAL_CALL KDE4FilePicker::setMultiSelectionMode( sal_Bool multiSelect ) void SAL_CALL KDE4FilePicker::setDefaultName( const OUString &name ) { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT setDefaultNameSignal( name ); } @@ -301,7 +301,7 @@ void SAL_CALL KDE4FilePicker::setDefaultName( const OUString &name ) void SAL_CALL KDE4FilePicker::setDisplayDirectory( const OUString &dir ) { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT setDisplayDirectorySignal( dir ); } @@ -312,7 +312,7 @@ void SAL_CALL KDE4FilePicker::setDisplayDirectory( const OUString &dir ) OUString SAL_CALL KDE4FilePicker::getDisplayDirectory() { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT getDisplayDirectorySignal(); } @@ -323,7 +323,7 @@ OUString SAL_CALL KDE4FilePicker::getDisplayDirectory() uno::Sequence< OUString > SAL_CALL KDE4FilePicker::getFiles() { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT getFilesSignal(); } uno::Sequence< OUString > seq = getSelectedFiles(); @@ -335,7 +335,7 @@ uno::Sequence< OUString > SAL_CALL KDE4FilePicker::getFiles() uno::Sequence< OUString > SAL_CALL KDE4FilePicker::getSelectedFiles() { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT getSelectedFilesSignal(); } KUrl::List urls = _dialog->selectedUrls(); @@ -349,7 +349,7 @@ uno::Sequence< OUString > SAL_CALL KDE4FilePicker::getSelectedFiles() void SAL_CALL KDE4FilePicker::appendFilter( const OUString &title, const OUString &filter ) { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT appendFilterSignal( title, filter ); } @@ -375,7 +375,7 @@ void SAL_CALL KDE4FilePicker::appendFilter( const OUString &title, const OUStrin void SAL_CALL KDE4FilePicker::setCurrentFilter( const OUString &title ) { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT setCurrentFilterSignal( title ); } @@ -385,7 +385,7 @@ void SAL_CALL KDE4FilePicker::setCurrentFilter( const OUString &title ) OUString SAL_CALL KDE4FilePicker::getCurrentFilter() { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT getCurrentFilterSignal(); } @@ -405,7 +405,7 @@ OUString SAL_CALL KDE4FilePicker::getCurrentFilter() void SAL_CALL KDE4FilePicker::appendFilterGroup( const OUString& rGroupTitle, const uno::Sequence<beans::StringPair>& filters) { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT appendFilterGroupSignal( rGroupTitle, filters ); } @@ -420,7 +420,7 @@ void SAL_CALL KDE4FilePicker::appendFilterGroup( const OUString& rGroupTitle, co void SAL_CALL KDE4FilePicker::setValue( sal_Int16 controlId, sal_Int16 nControlAction, const uno::Any &value ) { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT setValueSignal( controlId, nControlAction, value ); } @@ -444,7 +444,7 @@ uno::Any SAL_CALL KDE4FilePicker::getValue( sal_Int16 controlId, sal_Int16 nCont return uno::Any( false ); if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT getValueSignal( controlId, nControlAction ); } @@ -463,7 +463,7 @@ uno::Any SAL_CALL KDE4FilePicker::getValue( sal_Int16 controlId, sal_Int16 nCont void SAL_CALL KDE4FilePicker::enableControl( sal_Int16 controlId, sal_Bool enable ) { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT enableControlSignal( controlId, enable ); } @@ -476,7 +476,7 @@ void SAL_CALL KDE4FilePicker::enableControl( sal_Int16 controlId, sal_Bool enabl void SAL_CALL KDE4FilePicker::setLabel( sal_Int16 controlId, const OUString &label ) { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT setLabelSignal( controlId, label ); } @@ -492,7 +492,7 @@ void SAL_CALL KDE4FilePicker::setLabel( sal_Int16 controlId, const OUString &lab OUString SAL_CALL KDE4FilePicker::getLabel(sal_Int16 controlId) { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT getLabelSignal( controlId ); } @@ -607,7 +607,7 @@ void KDE4FilePicker::addCustomControl(sal_Int16 controlId) void SAL_CALL KDE4FilePicker::initialize( const uno::Sequence<uno::Any> &args ) { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT initializeSignal( args ); } @@ -767,7 +767,7 @@ uno::Sequence< OUString > SAL_CALL KDE4FilePicker::getSupportedServiceNames() void KDE4FilePicker::checkProtocol() { if( qApp->thread() != QThread::currentThread() ) { - SalYieldMutexReleaser rel; + SolarMutexReleaser aReleaser; return Q_EMIT checkProtocolSignal(); } diff --git a/vcl/unx/kde4/KDESalDisplay.cxx b/vcl/unx/kde4/KDESalDisplay.cxx index 7c30c7aa40c9..4647b3d111c8 100644 --- a/vcl/unx/kde4/KDESalDisplay.cxx +++ b/vcl/unx/kde4/KDESalDisplay.cxx @@ -54,8 +54,7 @@ void SalKDEDisplay::Yield() if (XEventsQueued( pDisp_, QueuedAfterReading ) == 0) return; - DBG_ASSERT( static_cast<SalYieldMutex*>(GetSalData()->m_pInstance->GetYieldMutex())->GetThreadId() == - osl::Thread::getCurrentIdentifier(), + DBG_ASSERT( GetSalData()->m_pInstance->GetYieldMutex()->IsCurrentThread(), "will crash soon since solar mutex not locked in SalKDEDisplay::Yield" ); XEvent event; diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx index a44b9f1a3233..d9e049142c1a 100644 --- a/vcl/unx/kde4/KDEXLib.cxx +++ b/vcl/unx/kde4/KDEXLib.cxx @@ -208,7 +208,7 @@ static GPollFunc old_gpoll = nullptr; static gint gpoll_wrapper( GPollFD* ufds, guint nfds, gint timeout ) { - SalYieldMutexReleaser release; // release YieldMutex (and re-acquire at block end) + SolarMutexReleaser aReleaser; return old_gpoll( ufds, nfds, timeout ); } #endif @@ -292,7 +292,7 @@ bool KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) // release the yield lock to prevent deadlock with the main thread // (it's ok to release it here, since even normal processYield() would // temporarily do it while checking for new events) - SalYieldMutexReleaser aReleaser; + SolarMutexReleaser aReleaser; Q_EMIT processYieldSignal( bWait, bHandleAllCurrentEvents ); return false; } @@ -382,7 +382,7 @@ uno::Reference< ui::dialogs::XFilePicker2 > KDEXLib::createFilePicker( { #if KDE4_HAVE_GLIB if( qApp->thread() != QThread::currentThread()) { - SalYieldMutexReleaser aReleaser; + SolarMutexReleaser aReleaser; return Q_EMIT createFilePickerSignal( xMSF ); } return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF ) ); diff --git a/vcl/win/app/salinst.cxx b/vcl/win/app/salinst.cxx index 97a5b6c55ad4..2f4e0b669689 100644 --- a/vcl/win/app/salinst.cxx +++ b/vcl/win/app/salinst.cxx @@ -96,99 +96,47 @@ void SalAbort( const OUString& rErrorText, bool ) LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ); -class SalYieldMutex : public comphelper::SolarMutex +class SalYieldMutex : public comphelper::GenericSolarMutex { public: // for ImplSalYield() and ImplSalYieldMutexAcquireWithWait() - osl::Mutex m_mutex; - osl::Condition m_condition; /// for MsgWaitForMultipleObjects() - WinSalInstance* mpInstData; - sal_uLong mnCount; - DWORD mnThreadId; + osl::Condition m_condition; /// for MsgWaitForMultipleObjects() -public: - explicit SalYieldMutex( WinSalInstance* pInstData ); +protected: + virtual void doAcquire( sal_uInt32 nLockCount ) override; + virtual sal_uInt32 doRelease( bool bUnlockAll ) override; - virtual void acquire() override; - virtual void release() override; - virtual bool tryToAcquire() override; + static void BeforeReleaseHandler(); - sal_uLong GetAcquireCount( sal_uLong nThreadId ); -}; +public: + explicit SalYieldMutex(); -SalYieldMutex::SalYieldMutex( WinSalInstance* pInstData ) -{ - mpInstData = pInstData; - mnCount = 0; - mnThreadId = 0; -} + virtual bool IsCurrentThread() const override; +}; -void SalYieldMutex::acquire() +SalYieldMutex::SalYieldMutex() { - m_mutex.acquire(); - mnCount++; - mnThreadId = GetCurrentThreadId(); + SetBeforeReleaseHandler( &SalYieldMutex::BeforeReleaseHandler ); } -void SalYieldMutex::release() +void SalYieldMutex::BeforeReleaseHandler() { - DWORD nThreadId = GetCurrentThreadId(); - assert(mnThreadId == nThreadId); - - bool const isRelease(1 == mnCount); - if ( isRelease ) - { - OpenGLContext::prepareForYield(); - - SalData* pSalData = GetSalData(); - if ( pSalData->mnAppThreadId != nThreadId ) - { - // If we don't call these message, the Output from the - // Java clients doesn't come in the right order - GdiFlush(); - - } - mnThreadId = 0; - } - - mnCount--; - m_mutex.release(); - - if ( isRelease ) - { // do this *after* release - m_condition.set(); // wake up ImplSalYieldMutexAcquireWithWait() - } -} + OpenGLContext::prepareForYield(); -bool SalYieldMutex::tryToAcquire() -{ - if( m_mutex.tryToAcquire() ) + if ( GetSalData()->mnAppThreadId != GetCurrentThreadId() ) { - mnCount++; - mnThreadId = GetCurrentThreadId(); - return true; + // If we don't call these message, the Output from the + // Java clients doesn't come in the right order + GdiFlush(); } - else - return false; -} - -sal_uLong SalYieldMutex::GetAcquireCount( sal_uLong nThreadId ) -{ - if ( nThreadId == mnThreadId ) - return mnCount; - else - return 0; } /// note: while VCL is fully up and running (other threads started and /// before shutdown), the main thread must acquire SolarMutex only via /// this function to avoid deadlock -void ImplSalYieldMutexAcquireWithWait( sal_uLong nCount ) +void SalYieldMutex::doAcquire( sal_uInt32 nLockCount ) { WinSalInstance* pInst = GetSalData()->mpFirstInstance; - if ( !pInst ) - return; - - if ( pInst->IsMainThread() ) + if ( pInst && pInst->IsMainThread() ) { // tdf#96887 If this is the main thread, then we must wait for two things: // - the mpSalYieldMutex being freed @@ -197,26 +145,41 @@ void ImplSalYieldMutexAcquireWithWait( sal_uLong nCount ) // needed because if we don't reschedule, then we create deadlocks if a // Window's create/destroy is called via SendMessage() from another thread. // Have a look at the osl_waitCondition implementation for more info. - SalYieldMutex * const pYieldMutex = pInst->mpSalYieldMutex; - osl::Condition &rCondition = pYieldMutex->m_condition; - while ( nCount ) - { - do { - // reset condition *before* acquiring! - rCondition.reset(); - if (pYieldMutex->tryToAcquire()) - break; - // wait for SalYieldMutex::release() to set the condition - osl::Condition::Result res = rCondition.wait(); - assert(osl::Condition::Result::result_ok == res); - } - while ( true ); - --nCount; + do { + // reset condition *before* acquiring! + m_condition.reset(); + if (m_aMutex.tryToAcquire()) + break; + // wait for SalYieldMutex::release() to set the condition + osl::Condition::Result res = m_condition.wait(); + assert(osl::Condition::Result::result_ok == res); } + while ( true ); } else - // If this is not the main thread, call acquire directly. - ImplSalAcquireYieldMutex( nCount ); + m_aMutex.acquire(); + ++m_nCount; + --nLockCount; + + comphelper::GenericSolarMutex::doAcquire( nLockCount ); +} + +sal_uInt32 SalYieldMutex::doRelease( const bool bUnlockAll ) +{ + sal_uInt32 nCount = comphelper::GenericSolarMutex::doRelease( bUnlockAll ); + + // wake up ImplSalYieldMutexAcquireWithWait() after release + if ( 0 == m_nCount ) + m_condition.set(); + + return nCount; +} + +void ImplSalYieldMutexAcquireWithWait( sal_uLong nCount ) +{ + WinSalInstance* pInst = GetSalData()->mpFirstInstance; + if ( pInst ) + pInst->mpSalYieldMutex->acquire( nCount ); } bool ImplSalYieldMutexTryToAcquire() @@ -238,47 +201,10 @@ void ImplSalYieldMutexRelease() } } -sal_uLong ImplSalReleaseYieldMutex() +bool SalYieldMutex::IsCurrentThread() const { - WinSalInstance* pInst = GetSalData()->mpFirstInstance; - if ( !pInst ) - return 0; - - SalYieldMutex* pYieldMutex = pInst->mpSalYieldMutex; - const sal_uLong nCount = pYieldMutex->GetAcquireCount( GetCurrentThreadId() ); - sal_uLong n = nCount; - while ( n ) - { - pYieldMutex->release(); - n--; - } - - return nCount; -} - -void ImplSalAcquireYieldMutex( sal_uLong nCount ) -{ - WinSalInstance* pInst = GetSalData()->mpFirstInstance; - if ( !pInst ) - return; - - SalYieldMutex* pYieldMutex = pInst->mpSalYieldMutex; - while ( nCount ) - { - pYieldMutex->acquire(); - nCount--; - } -} - -bool WinSalInstance::CheckYieldMutex() -{ - SalData* pSalData = GetSalData(); - if ( pSalData->mpFirstInstance ) - { - SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->mpSalYieldMutex; - return (pYieldMutex->mnThreadId == (GetCurrentThreadId())); - } - return true; + // For the Windows backend, the LO identifier is the system thread ID + return m_nThreadId == GetCurrentThreadId(); } void SalData::initKeyCodeMap() @@ -520,14 +446,12 @@ void DestroySalInstance( SalInstance* pInst ) WinSalInstance::WinSalInstance() { mhComWnd = nullptr; - mpSalYieldMutex = new SalYieldMutex( this ); + mpSalYieldMutex = new SalYieldMutex(); mpSalYieldMutex->acquire(); - ::comphelper::SolarMutex::setSolarMutex( mpSalYieldMutex ); } WinSalInstance::~WinSalInstance() { - ::comphelper::SolarMutex::setSolarMutex( nullptr ); mpSalYieldMutex->release(); delete mpSalYieldMutex; DestroyWindow( mhComWnd ); @@ -538,14 +462,14 @@ comphelper::SolarMutex* WinSalInstance::GetYieldMutex() return mpSalYieldMutex; } -sal_uLong WinSalInstance::ReleaseYieldMutex() +sal_uInt32 WinSalInstance::ReleaseYieldMutex( bool bUnlockAll ) { - return ImplSalReleaseYieldMutex(); + return mpSalYieldMutex->release( bUnlockAll ); } -void WinSalInstance::AcquireYieldMutex( sal_uLong nCount ) +void WinSalInstance::AcquireYieldMutex( sal_uInt32 nCount ) { - ImplSalAcquireYieldMutex( nCount ); + mpSalYieldMutex->acquire( nCount ); } static void ImplSalDispatchMessage( MSG* pMsg ) @@ -615,8 +539,8 @@ bool WinSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong bool bDidWork = false; // NOTE: if nReleased != 0 this will be called without SolarMutex // so don't do anything dangerous before releasing it here - sal_uLong const nCount = (nReleased != 0) - ? nReleased : ImplSalReleaseYieldMutex(); + sal_uInt32 const nCount = (nReleased != 0) + ? nReleased : mpSalYieldMutex->release( true ); if ( !IsMainThread() ) { // #97739# A SendMessage call blocks until the called thread (here: the main thread) @@ -635,16 +559,13 @@ bool WinSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong // If you change the SendMessageW function, you might need to update // the PeekMessage( ... PM_QS_POSTMESSAGE) calls! bDidWork = SendMessageW( mhComWnd, SAL_MSG_THREADYIELD, (WPARAM)bWait, (LPARAM)bHandleAllCurrentEvents ); - - ImplSalAcquireYieldMutex( nCount ); } else { if (nReleased == 0) // tdf#99383 ReAcquireSolarMutex shouldn't Yield bDidWork = ImplSalYield( bWait, bHandleAllCurrentEvents ); - - ImplSalYieldMutexAcquireWithWait( nCount ); } + mpSalYieldMutex->acquire( nCount ); return bDidWork; } diff --git a/vcl/win/gdi/salprn.cxx b/vcl/win/gdi/salprn.cxx index 365bf44c06e4..4775e804f2f9 100644 --- a/vcl/win/gdi/salprn.cxx +++ b/vcl/win/gdi/salprn.cxx @@ -396,16 +396,17 @@ static bool ImplUpdateSalJobSetup( WinSalInfoPrinter const * pPrinter, ImplJobSe } // Release mutex, in the other case we don't get paints and so on - sal_uLong nMutexCount=0; - if ( pVisibleDlgParent ) - nMutexCount = ImplSalReleaseYieldMutex(); + sal_uInt32 nMutexCount = 0; + WinSalInstance* pInst = GetSalData()->mpFirstInstance; + if ( pInst && pVisibleDlgParent ) + nMutexCount = pInst->ReleaseYieldMutex( true ); BYTE* pOutDevMode = (reinterpret_cast<BYTE*>(pOutBuffer) + pOutBuffer->mnDriverOffset); nRet = DocumentPropertiesW( hWnd, hPrn, pPrinterNameW, reinterpret_cast<LPDEVMODEW>(pOutDevMode), reinterpret_cast<LPDEVMODEW>(const_cast<BYTE *>(pInBuffer)), nMode ); - if ( pVisibleDlgParent ) - ImplSalAcquireYieldMutex( nMutexCount ); + if ( pInst && pVisibleDlgParent ) + pInst->AcquireYieldMutex( nMutexCount ); ClosePrinter( hPrn ); if( (nRet < 0) || (pVisibleDlgParent && (nRet == IDCANCEL)) ) @@ -1522,6 +1523,14 @@ bool WinSalPrinter::StartJob( const OUString* pFileName, return TRUE; } +void WinSalPrinter::DoEndDoc(HDC hDC) +{ + CATCH_DRIVER_EX_BEGIN; + if( ::EndDoc( hDC ) <= 0 ) + GetLastError(); + CATCH_DRIVER_EX_END( "exception in EndDoc", this ); +} + bool WinSalPrinter::EndJob() { HDC hDC = mhDC; @@ -1540,13 +1549,10 @@ bool WinSalPrinter::EndJob() // it should be safe to release the yield mutex over the EndDoc // call, however the real solution is supposed to be the threading // framework yet to come. - volatile sal_uLong nAcquire = GetSalData()->mpFirstInstance->ReleaseYieldMutex(); - CATCH_DRIVER_EX_BEGIN; - if( ::EndDoc( hDC ) <= 0 ) - GetLastError(); - CATCH_DRIVER_EX_END( "exception in EndDoc", this ); - - GetSalData()->mpFirstInstance->AcquireYieldMutex( nAcquire ); + { + SolarMutexReleaser aReleaser; + DoEndDoc( hDC ); + } DeleteDC( hDC ); mhDC = nullptr; } |