Unify SolarMutex implementations

All backends implement the SolarMutex in mostly the same way.
So this consolidates this code into a GenericSolarMutex.

We still need the abstract SolarMutex class for the fake AKA
fascade implementation in dbaccess.

The patch also replaces various places of direct mutex usage with
either SolarMutexGuard or SolarMutexReleaser objects.

Change-Id: Ia0146dd6c51a3b9a513cc6af34a66def58aad831
Reviewed-on: https://gerrit.libreoffice.org/42325
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
This commit is contained in:
Jan-Marek Glogowski 2017-08-15 08:05:51 +02:00
parent 10b49dfb39
commit 3840aede59
31 changed files with 336 additions and 570 deletions

View File

@ -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: */

View File

@ -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 >

View File

@ -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;

View File

@ -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 );
}
#endif
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 // INCLUDED_COMPHELPER_SOLARMUTEX_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -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();

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 );

View File

@ -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; }
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& );

View File

@ -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;
/**

View File

@ -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; }
};
/*
@ -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,

View File

@ -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 );

View File

@ -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;

View File

@ -84,6 +84,9 @@ public:
bool mbValid;
protected:
void DoEndDoc(HDC hDC);
public:
WinSalPrinter();
virtual ~WinSalPrinter() override;

View File

@ -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;
}

View File

@ -223,13 +223,8 @@ static AquaSalFrame* getMouseContainerFrame()
{
if( GetSalData() && GetSalData()->mpFirstInstance )
{
comphelper::SolarMutex* pMutex = GetSalData()->mpFirstInstance->GetYieldMutex();
if( pMutex )
{
pMutex->acquire();
SolarMutexGuard aGuard;
[super displayIfNeeded];
pMutex->release();
}
}
}

View File

@ -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()
sal_uInt32 AquaSalInstance::ReleaseYieldMutex( bool bUnlockAll )
{
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;
return mpSalYieldMutex->release( bUnlockAll );
}
void AquaSalInstance::AcquireYieldMutex( sal_uLong nCount )
void AquaSalInstance::AcquireYieldMutex( sal_uInt32 nCount )
{
SalYieldMutex* pYieldMutex = mpSalYieldMutex;
while ( nCount )
{
pYieldMutex->acquire();
nCount--;
}
}
bool AquaSalInstance::CheckYieldMutex()
{
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() );

View File

@ -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()

View File

@ -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 );

View File

@ -39,48 +39,13 @@
SalYieldMutex::SalYieldMutex()
{
mnCount = 0;
mnThreadId = 0;
::comphelper::SolarMutex::setSolarMutex( this );
#if HAVE_FEATURE_OPENGL
SetBeforeReleaseHandler( &OpenGLContext::prepareForYield );
#endif
}
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();
#endif
mnThreadId = 0;
}
mnCount--;
m_mutex.release();
}
bool SalYieldMutex::tryToAcquire()
{
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;
return mpSalYieldMutex.get()->release( bUnlockAll );
}
void SalGenericInstance::AcquireYieldMutex( sal_uLong nCount )
void SalGenericInstance::AcquireYieldMutex( sal_uInt32 nCount )
{
SalYieldMutex* pYieldMutex = mpSalYieldMutex.get();
while ( nCount )
{
pYieldMutex->acquire();
nCount--;
}
}
bool SalGenericInstance::CheckYieldMutex()
{
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()

View File

@ -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

View File

@ -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 );

View File

@ -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 )

View File

@ -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)
{

View File

@ -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();

View File

@ -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)
{

View File

@ -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();
}

View File

@ -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;

View File

@ -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 ) );

View File

@ -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;
protected:
virtual void doAcquire( sal_uInt32 nLockCount ) override;
virtual sal_uInt32 doRelease( bool bUnlockAll ) override;
static void BeforeReleaseHandler();
public:
explicit SalYieldMutex( WinSalInstance* pInstData );
explicit SalYieldMutex();
virtual void acquire() override;
virtual void release() override;
virtual bool tryToAcquire() override;
sal_uLong GetAcquireCount( sal_uLong nThreadId );
virtual bool IsCurrentThread() const override;
};
SalYieldMutex::SalYieldMutex( WinSalInstance* pInstData )
SalYieldMutex::SalYieldMutex()
{
mpInstData = pInstData;
mnCount = 0;
mnThreadId = 0;
SetBeforeReleaseHandler( &SalYieldMutex::BeforeReleaseHandler );
}
void SalYieldMutex::acquire()
void SalYieldMutex::BeforeReleaseHandler()
{
m_mutex.acquire();
mnCount++;
mnThreadId = GetCurrentThreadId();
}
void SalYieldMutex::release()
{
DWORD nThreadId = GetCurrentThreadId();
assert(mnThreadId == nThreadId);
bool const isRelease(1 == mnCount);
if ( isRelease )
{
OpenGLContext::prepareForYield();
SalData* pSalData = GetSalData();
if ( pSalData->mnAppThreadId != nThreadId )
if ( GetSalData()->mnAppThreadId != GetCurrentThreadId() )
{
// 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()
}
}
bool SalYieldMutex::tryToAcquire()
{
if( m_mutex.tryToAcquire() )
{
mnCount++;
mnThreadId = GetCurrentThreadId();
return true;
}
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())
m_condition.reset();
if (m_aMutex.tryToAcquire())
break;
// wait for SalYieldMutex::release() to set the condition
osl::Condition::Result res = rCondition.wait();
osl::Condition::Result res = m_condition.wait();
assert(osl::Condition::Result::result_ok == res);
}
while ( true );
--nCount;
}
}
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;
}

View File

@ -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;
}