Kaydet (Commit) c5cf78e1 authored tarafından Stephan Bergmann's avatar Stephan Bergmann

Properly join spawned GrammarCheckingIterator thread.

It was still running during shutdown of sw_complex's checkFlies test, causing
problems.
For this to work, Desktop::DeInit needs to be called with SolarMutex unlocked,
which looks like the right way, anyway.  Hopefully it does not unearth another
round of bugs...
üst 9bdfd1fa
...@@ -252,15 +252,31 @@ GrammarCheckingIterator::GrammarCheckingIterator( const uno::Reference< lang::XM ...@@ -252,15 +252,31 @@ GrammarCheckingIterator::GrammarCheckingIterator( const uno::Reference< lang::XM
m_aEventListeners( MyMutex::get() ), m_aEventListeners( MyMutex::get() ),
m_aNotifyListeners( MyMutex::get() ) m_aNotifyListeners( MyMutex::get() )
{ {
osl_createThread( workerfunc, this ); m_thread = osl_createThread( workerfunc, this );
} }
GrammarCheckingIterator::~GrammarCheckingIterator() GrammarCheckingIterator::~GrammarCheckingIterator()
{ {
::osl::Guard< ::osl::Mutex > aGuard( MyMutex::get() ); TerminateThread();
} }
void GrammarCheckingIterator::TerminateThread()
{
oslThread t;
{
::osl::Guard< ::osl::Mutex > aGuard( MyMutex::get() );
t = m_thread;
m_thread = 0;
m_bEnd = sal_True;
m_aWakeUpThread.set();
}
if (t != 0)
{
osl_joinWithThread(t);
osl_destroyThread(t);
}
}
sal_Int32 GrammarCheckingIterator::NextDocId() sal_Int32 GrammarCheckingIterator::NextDocId()
{ {
...@@ -489,19 +505,16 @@ void GrammarCheckingIterator::DequeueAndCheck() ...@@ -489,19 +505,16 @@ void GrammarCheckingIterator::DequeueAndCheck()
uno::Sequence< sal_Int32 > aLangPortions; uno::Sequence< sal_Int32 > aLangPortions;
uno::Sequence< lang::Locale > aLangPortionsLocale; uno::Sequence< lang::Locale > aLangPortionsLocale;
// ---- THREAD SAFE START ---- for (;;)
bool bEnd = false;
{
::osl::Guard< ::osl::Mutex > aGuard( MyMutex::get() );
bEnd = m_bEnd;
}
// ---- THREAD SAFE END ----
while (!bEnd)
{ {
// ---- THREAD SAFE START ---- // ---- THREAD SAFE START ----
bool bQueueEmpty = false; bool bQueueEmpty = false;
{ {
::osl::Guard< ::osl::Mutex > aGuard( MyMutex::get() ); ::osl::Guard< ::osl::Mutex > aGuard( MyMutex::get() );
if (m_bEnd)
{
break;
}
bQueueEmpty = m_aFPEntriesQueue.empty(); bQueueEmpty = m_aFPEntriesQueue.empty();
} }
// ---- THREAD SAFE END ---- // ---- THREAD SAFE END ----
...@@ -605,6 +618,10 @@ void GrammarCheckingIterator::DequeueAndCheck() ...@@ -605,6 +618,10 @@ void GrammarCheckingIterator::DequeueAndCheck()
// ---- THREAD SAFE START ---- // ---- THREAD SAFE START ----
{ {
::osl::Guard< ::osl::Mutex > aGuard( MyMutex::get() ); ::osl::Guard< ::osl::Mutex > aGuard( MyMutex::get() );
if (m_bEnd)
{
break;
}
// Check queue state again // Check queue state again
if (m_aFPEntriesQueue.empty()) if (m_aFPEntriesQueue.empty())
m_aWakeUpThread.reset(); m_aWakeUpThread.reset();
...@@ -618,17 +635,7 @@ void GrammarCheckingIterator::DequeueAndCheck() ...@@ -618,17 +635,7 @@ void GrammarCheckingIterator::DequeueAndCheck()
// safe implemented. // safe implemented.
m_aWakeUpThread.wait(); m_aWakeUpThread.wait();
} }
// ---- THREAD SAFE START ----
{
::osl::Guard< ::osl::Mutex > aGuard( MyMutex::get() );
bEnd = m_bEnd;
}
// ---- THREAD SAFE END ----
} }
//!! This one must be the very last statement to call in this function !!
m_aRequestEndThread.set();
} }
...@@ -901,19 +908,7 @@ throw (uno::RuntimeException) ...@@ -901,19 +908,7 @@ throw (uno::RuntimeException)
lang::EventObject aEvt( (linguistic2::XProofreadingIterator *) this ); lang::EventObject aEvt( (linguistic2::XProofreadingIterator *) this );
m_aEventListeners.disposeAndClear( aEvt ); m_aEventListeners.disposeAndClear( aEvt );
// now end the thread... TerminateThread();
m_aRequestEndThread.reset();
// ---- THREAD SAFE START ----
{
::osl::Guard< ::osl::Mutex > aGuard( MyMutex::get() );
m_bEnd = sal_True;
}
// ---- THREAD SAFE END ----
m_aWakeUpThread.set();
const TimeValue aTime = { 3, 0 }; // wait 3 seconds...
m_aRequestEndThread.wait( &aTime );
// if the call ends because of time-out we will end anyway...
// ---- THREAD SAFE START ---- // ---- THREAD SAFE START ----
{ {
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <cppuhelper/weakref.hxx> #include <cppuhelper/weakref.hxx>
#include <osl/mutex.hxx> #include <osl/mutex.hxx>
#include <osl/conditn.hxx> #include <osl/conditn.hxx>
#include <osl/thread.h>
#include <rtl/instance.hxx> #include <rtl/instance.hxx>
#include <map> #include <map>
...@@ -122,7 +123,7 @@ class GrammarCheckingIterator: ...@@ -122,7 +123,7 @@ class GrammarCheckingIterator:
sal_Int32 m_nDocIdCounter; sal_Int32 m_nDocIdCounter;
sal_Int32 m_nLastEndOfSentencePos; sal_Int32 m_nLastEndOfSentencePos;
osl::Condition m_aWakeUpThread; osl::Condition m_aWakeUpThread;
osl::Condition m_aRequestEndThread; oslThread m_thread;
//! beware of initilization order ! //! beware of initilization order !
struct MyMutex : public rtl::Static< osl::Mutex, MyMutex > {}; struct MyMutex : public rtl::Static< osl::Mutex, MyMutex > {};
...@@ -132,6 +133,8 @@ class GrammarCheckingIterator: ...@@ -132,6 +133,8 @@ class GrammarCheckingIterator:
::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator > m_xBreakIterator; ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator > m_xBreakIterator;
mutable ::com::sun::star::uno::Reference< ::com::sun::star::util::XChangesBatch > m_xUpdateAccess; mutable ::com::sun::star::uno::Reference< ::com::sun::star::util::XChangesBatch > m_xUpdateAccess;
void TerminateThread();
sal_Int32 NextDocId(); sal_Int32 NextDocId();
::rtl::OUString GetOrCreateDocId( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > &xComp ); ::rtl::OUString GetOrCreateDocId( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > &xComp );
......
...@@ -489,10 +489,14 @@ void DeInitVCL() ...@@ -489,10 +489,14 @@ void DeInitVCL()
pSVData->maAppData.mxMSF.clear(); pSVData->maAppData.mxMSF.clear();
if( pSVData->mpApp ) if( pSVData->mpApp )
{
sal_uLong nCount = Application::ReleaseSolarMutex();
// call deinit to deinitialize application class // call deinit to deinitialize application class
// soffice/sfx implementation disposes the global service manager // soffice/sfx implementation disposes the global service manager
// Warning: After this call you can't call uno services // Warning: After this call you can't call uno services
pSVData->mpApp->DeInit(); pSVData->mpApp->DeInit();
Application::AcquireSolarMutex(nCount);
}
if ( pSVData->maAppData.mpSettings ) if ( pSVData->maAppData.mpSettings )
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment