From 0888066f1cdca49b3199bb1a5962d07caa6d10f2 Mon Sep 17 00:00:00 2001 From: Tino Rachui Date: Thu, 21 Feb 2002 13:45:39 +0000 Subject: #96112#new asynceventnotifier implementation --- .../source/win32/filepicker/asynceventnotifier.cxx | 180 +++++++++++++++------ .../source/win32/filepicker/asynceventnotifier.hxx | 44 ++--- 2 files changed, 161 insertions(+), 63 deletions(-) (limited to 'fpicker') diff --git a/fpicker/source/win32/filepicker/asynceventnotifier.cxx b/fpicker/source/win32/filepicker/asynceventnotifier.cxx index f3ff8455667c..a680a8f11376 100644 --- a/fpicker/source/win32/filepicker/asynceventnotifier.cxx +++ b/fpicker/source/win32/filepicker/asynceventnotifier.cxx @@ -2,9 +2,9 @@ * * $RCSfile: asynceventnotifier.cxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: tra $ $Date: 2001-12-11 16:35:45 $ + * last change: $Author: tra $ $Date: 2002-02-21 14:45:38 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -75,7 +75,12 @@ #include #endif +#ifndef _COM_SUN_STAR_UI_DIALOGS_XFILEPICKERNOTIFIER_HPP_ +#include +#endif + #include +#include //------------------------------------------------ // @@ -88,81 +93,162 @@ const sal_uInt32 MAX_WAIT_SHUTDOWN = 5000; // msec //------------------------------------------------ using namespace osl; +using namespace com::sun::star::uno; using ::com::sun::star::uno::Reference; using ::com::sun::star::ui::dialogs::XFilePickerListener; +using ::com::sun::star::ui::dialogs::XFilePickerNotifier; using ::com::sun::star::ui::dialogs::FilePickerEvent; using ::cppu::OBroadcastHelper; -using ::com::sun::star::uno::RuntimeException; //------------------------------------------------ // //------------------------------------------------ -CAsyncFilePickerEventNotifier::CAsyncFilePickerEventNotifier( cppu::OBroadcastHelper& rBroadcastHelper ) : - m_bRunFilePickerNotifierThread( true ), - m_rBroadcastHelper( rBroadcastHelper ) +CAsyncEventNotifier::CAsyncEventNotifier(cppu::OBroadcastHelper& rBroadcastHelper) : + m_hEventNotifierThread(0), + m_bRun(false), + m_ThreadId(0), + m_rBroadcastHelper(rBroadcastHelper) +{ +} + +//------------------------------------------------ +// +//------------------------------------------------ + +bool SAL_CALL CAsyncEventNotifier::start() { - unsigned uThreadId; - m_hFilePickerNotifierThread = (HANDLE)_beginthreadex( - NULL, 0, CAsyncFilePickerEventNotifier::ThreadProc, this, 0, &uThreadId ); + MutexGuard aGuard(m_Mutex); + + // m_bRun may already be false because of a + // call to stop but the thread did not yet + // terminate so m_hEventNotifierThread is + // yet a valid thread handle that should + // not be overwritten + if ( !m_bRun && 0==m_hEventNotifierThread ) + { + m_hEventNotifierThread = (HANDLE)_beginthreadex( + NULL, 0, CAsyncEventNotifier::ThreadProc, this, 0, &m_ThreadId); + + OSL_ASSERT(0 != m_hEventNotifierThread); - OSL_ASSERT( NULL != m_hFilePickerNotifierThread ); + if (m_hEventNotifierThread) + m_bRun = true; + } + + return m_bRun; } //------------------------------------------------ // //------------------------------------------------ -CAsyncFilePickerEventNotifier::~CAsyncFilePickerEventNotifier( ) +void SAL_CALL CAsyncEventNotifier::stop() { - m_bRunFilePickerNotifierThread = false; - m_NotifyFilePickerEvent.set( ); + OSL_ENSURE(GetCurrentThreadId() != m_ThreadId, "Method must not be called from EventNotifierThread context"); + + ClearableMutexGuard aGuard(m_Mutex); + + m_bRun = false; + m_EventList.clear(); + m_NotifyEvent.set( ); + + // releas the mutex here because the event + // notifier thread may need it to finish + aGuard.clear(); sal_uInt32 dwResult = WaitForSingleObject( - m_hFilePickerNotifierThread, MAX_WAIT_SHUTDOWN ); + m_hEventNotifierThread, MAX_WAIT_SHUTDOWN ); + + // lock mutex again to reset m_hEventNotifierThread + // and prevent a race with start() + MutexGuard anotherGuard(m_Mutex); + + OSL_ENSURE(WAIT_TIMEOUT != dwResult, "Thread could not end!"); + + if (WAIT_TIMEOUT == dwResult) + TerminateThread(m_hEventNotifierThread, 0); + + CloseHandle(m_hEventNotifierThread); + + m_hEventNotifierThread = 0; +} + +//------------------------------------------------ +// +//------------------------------------------------ + +void SAL_CALL CAsyncEventNotifier::notifyEvent(EventListenerMethod_t aListenerMethod, FilePickerEvent aEvent) +{ + MutexGuard aGuard(m_Mutex); - OSL_ENSURE( dwResult == WAIT_OBJECT_0, "filepicker event notifier thread could not terminate" ); + if ( m_bRun ) + { + m_EventList.push_back(std::make_pair(aListenerMethod, aEvent)); + m_NotifyEvent.set(); + } +} + +//------------------------------------------------ +// +//------------------------------------------------ + +size_t SAL_CALL CAsyncEventNotifier::getEventListSize() +{ + MutexGuard aGuard(m_Mutex); + return m_EventList.size(); +} + +//------------------------------------------------ +// +//------------------------------------------------ - if ( WAIT_TIMEOUT == dwResult ) - TerminateThread( m_hFilePickerNotifierThread, 0 ); +void SAL_CALL CAsyncEventNotifier::resetNotifyEvent() +{ + MutexGuard aGuard(m_Mutex); + if (0 == m_EventList.size()) + m_NotifyEvent.reset(); +} - CloseHandle( m_hFilePickerNotifierThread ); +//------------------------------------------------ +// +//------------------------------------------------ + +CAsyncEventNotifier::EventRecord_t SAL_CALL CAsyncEventNotifier::getNextEventRecord() +{ + MutexGuard aGuard(m_Mutex); + return m_EventList.front(); } //------------------------------------------------ // //------------------------------------------------ -void SAL_CALL CAsyncFilePickerEventNotifier::notifyEvent( FilePickerEventListenerMethod_t aListenerMethod, FilePickerEvent aEvent ) +void SAL_CALL CAsyncEventNotifier::removeNextEventRecord() { - MutexGuard aGuard( m_FilePickerEventListMutex ); - m_FilePickerEventList.push_back( std::make_pair( aListenerMethod, aEvent ) ); - m_NotifyFilePickerEvent.set( ); + MutexGuard aGuard(m_Mutex); + m_EventList.pop_front(); } //------------------------------------------------ // //------------------------------------------------ -void SAL_CALL CAsyncFilePickerEventNotifier::run( ) +void SAL_CALL CAsyncEventNotifier::run() { - while ( m_bRunFilePickerNotifierThread ) + while (m_bRun) { - m_NotifyFilePickerEvent.wait( ); + m_NotifyEvent.wait( ); - if ( !m_rBroadcastHelper.bDisposed ) + if (m_bRun) { - while ( m_FilePickerEventList.size() > 0 ) + while (getEventListSize() > 0) { - ClearableMutexGuard aGuard( m_FilePickerEventListMutex ); - - FilePickerEventRecord_t nextEventRecord = m_FilePickerEventList.front(); - m_FilePickerEventList.pop_front(); - - aGuard.clear(); + EventRecord_t aEventRecord = getNextEventRecord(); + removeNextEventRecord(); ::cppu::OInterfaceContainerHelper* pICHelper = - m_rBroadcastHelper.aLC.getContainer(getCppuType((Reference*)0) ); + m_rBroadcastHelper.aLC.getContainer(getCppuType((Reference*)0)); if ( pICHelper ) { @@ -170,35 +256,39 @@ void SAL_CALL CAsyncFilePickerEventNotifier::run( ) while( iter.hasMoreElements() ) { - Reference< XFilePickerListener > xFPListener( iter.next( ), ::com::sun::star::uno::UNO_QUERY ); + Reference< XFilePickerListener > xFPListener(iter.next( ), UNO_QUERY); try { if ( xFPListener.is() ) - (xFPListener.get()->*nextEventRecord.first)(nextEventRecord.second); + (xFPListener.get()->*aEventRecord.first)(aEventRecord.second); } catch( RuntimeException& ) { - OSL_ENSURE( sal_False, "RuntimeException during event dispatching" ); + OSL_ENSURE(sal_False, "RuntimeException during event dispatching"); } } } - } - } - m_NotifyFilePickerEvent.reset( ); - } + } // while(getEventListSize() > 0) + + resetNotifyEvent(); + + } // if (m_bRun) + + } // while(m_bRun) } //------------------------------------------------ // //------------------------------------------------ -unsigned int WINAPI CAsyncFilePickerEventNotifier::ThreadProc( LPVOID pParam ) +unsigned int WINAPI CAsyncEventNotifier::ThreadProc(LPVOID pParam) { - CAsyncFilePickerEventNotifier* pInst = reinterpret_cast< CAsyncFilePickerEventNotifier* >( pParam ); - OSL_ASSERT( pInst ); - pInst->run( ); + CAsyncEventNotifier* pInst = reinterpret_cast< CAsyncEventNotifier* >(pParam); + OSL_ASSERT(pInst); + + pInst->run(); return 0; } \ No newline at end of file diff --git a/fpicker/source/win32/filepicker/asynceventnotifier.hxx b/fpicker/source/win32/filepicker/asynceventnotifier.hxx index 5d0518649295..0e862305bdbc 100644 --- a/fpicker/source/win32/filepicker/asynceventnotifier.hxx +++ b/fpicker/source/win32/filepicker/asynceventnotifier.hxx @@ -2,9 +2,9 @@ * * $RCSfile: asynceventnotifier.hxx,v $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * - * last change: $Author: tra $ $Date: 2001-11-15 15:51:20 $ + * last change: $Author: tra $ $Date: 2002-02-21 14:45:39 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -91,36 +91,44 @@ // //--------------------------------------------- -class CAsyncFilePickerEventNotifier +class CAsyncEventNotifier { public: - typedef void (SAL_CALL ::com::sun::star::ui::dialogs::XFilePickerListener::*FilePickerEventListenerMethod_t)(const ::com::sun::star::ui::dialogs::FilePickerEvent&); + typedef void (SAL_CALL ::com::sun::star::ui::dialogs::XFilePickerListener::*EventListenerMethod_t)(const ::com::sun::star::ui::dialogs::FilePickerEvent&); public: - CAsyncFilePickerEventNotifier( cppu::OBroadcastHelper& rBroadcastHelper ); - ~CAsyncFilePickerEventNotifier( ); + CAsyncEventNotifier(cppu::OBroadcastHelper& rBroadcastHelper); - void SAL_CALL notifyEvent( FilePickerEventListenerMethod_t aListenerMethod, ::com::sun::star::ui::dialogs::FilePickerEvent aEvent ); + bool SAL_CALL start(); + void SAL_CALL stop(); + + void SAL_CALL notifyEvent( EventListenerMethod_t aListenerMethod, ::com::sun::star::ui::dialogs::FilePickerEvent aEvent ); private: - static unsigned int WINAPI ThreadProc( LPVOID pParam ); + typedef std::pair EventRecord_t; + + size_t SAL_CALL getEventListSize(); + void SAL_CALL resetNotifyEvent(); + EventRecord_t SAL_CALL getNextEventRecord(); + void SAL_CALL removeNextEventRecord(); void SAL_CALL run( ); -private: - typedef std::pair< FilePickerEventListenerMethod_t, ::com::sun::star::ui::dialogs::FilePickerEvent > FilePickerEventRecord_t; + static unsigned int WINAPI ThreadProc( LPVOID pParam ); - std::list< FilePickerEventRecord_t > m_FilePickerEventList; - HANDLE m_hFilePickerNotifierThread; - osl::Condition m_NotifyFilePickerEvent; - osl::Mutex m_FilePickerEventListMutex; - bool m_bRunFilePickerNotifierThread; - ::cppu::OBroadcastHelper& m_rBroadcastHelper; +private: + std::list m_EventList; + HANDLE m_hEventNotifierThread; + bool m_bRun; + unsigned m_ThreadId; + ::cppu::OBroadcastHelper& m_rBroadcastHelper; + osl::Condition m_NotifyEvent; + osl::Mutex m_Mutex; // prevent copy and assignment private: - CAsyncFilePickerEventNotifier( const CAsyncFilePickerEventNotifier& ); - CAsyncFilePickerEventNotifier& operator=( const CAsyncFilePickerEventNotifier& ); + CAsyncEventNotifier( const CAsyncEventNotifier& ); + CAsyncEventNotifier& operator=( const CAsyncEventNotifier& ); }; #endif \ No newline at end of file -- cgit