1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: asynceventnotifier.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_fpicker.hxx"
34 //------------------------------------------------------------------------
36 //------------------------------------------------------------------------
37 #include <osl/diagnose.h>
38 #include "asynceventnotifier.hxx"
39 #include <com/sun/star/uno/RuntimeException.hpp>
40 #include <com/sun/star/ui/dialogs/XFilePickerListener.hpp>
44 #include "SolarMutex.hxx"
46 //------------------------------------------------
48 //------------------------------------------------
50 using namespace com::sun::star
;
51 using ::com::sun::star::ui::dialogs::XFilePickerListener
;
53 //------------------------------------------------
55 //------------------------------------------------
57 CAsyncEventNotifier::CAsyncEventNotifier(cppu::OBroadcastHelper
& rBroadcastHelper
) :
61 m_rBroadcastHelper(rBroadcastHelper
),
62 m_NotifyEvent(m_hEvents
[0]),
63 m_ResumeNotifying(m_hEvents
[1])
66 m_hEvents
[0] = CreateEvent(0, /* no security */
67 true, /* manual reset */
68 false, /* initial state not signaled */
69 0); /* automatic name */
72 m_hEvents
[1] = CreateEvent(0, /* no security */
73 true, /* manual reset */
74 false, /* initial state not signaled */
75 0); /* automatic name */
78 //------------------------------------------------
80 //------------------------------------------------
82 CAsyncEventNotifier::~CAsyncEventNotifier()
84 OSL_ENSURE(0 == m_hThread
,"Thread not stopped, destroying this instance leads to desaster");
86 CloseHandle(m_hEvents
[0]);
87 CloseHandle(m_hEvents
[1]);
90 //------------------------------------------------
92 //------------------------------------------------
94 void SAL_CALL
CAsyncEventNotifier::addListener(const uno::Type
& aType
,
95 const uno::Reference
< uno::XInterface
>& xListener
)
97 if ( m_rBroadcastHelper
.bDisposed
)
98 throw lang::DisposedException(
99 ::rtl::OUString::createFromAscii( "FilePicker is already disposed" ),
100 uno::Reference
< uno::XInterface
>() );
102 if ( m_rBroadcastHelper
.bInDispose
)
103 throw lang::DisposedException(
104 ::rtl::OUString::createFromAscii( "FilePicker will be disposed now." ),
105 uno::Reference
< uno::XInterface
>() );
107 m_rBroadcastHelper
.aLC
.addInterface( aType
, xListener
);
110 //------------------------------------------------
112 //------------------------------------------------
114 void SAL_CALL
CAsyncEventNotifier::removeListener(const uno::Type
& aType
,
115 const uno::Reference
< uno::XInterface
>& xListener
)
117 if ( m_rBroadcastHelper
.bDisposed
)
118 throw lang::DisposedException(
119 ::rtl::OUString::createFromAscii( "FilePicker is already disposed." ),
120 uno::Reference
< uno::XInterface
>() );
122 m_rBroadcastHelper
.aLC
.removeInterface( aType
, xListener
);
125 //------------------------------------------------
127 //------------------------------------------------
129 bool SAL_CALL
CAsyncEventNotifier::startup(bool bCreateSuspended
)
131 osl::MutexGuard
aGuard(m_Mutex
);
133 // m_bRun may already be false because of a
134 // call to stop but the thread did not yet
135 // terminate so m_hEventNotifierThread is
136 // yet a valid thread handle that should
137 // not be overwritten
140 if (!bCreateSuspended
)
141 SetEvent(m_ResumeNotifying
);
143 m_hThread
= (HANDLE
)_beginthreadex(
144 NULL
, 0, CAsyncEventNotifier::ThreadProc
, this, 0, &m_ThreadId
);
146 OSL_ASSERT(0 != m_hThread
);
152 OSL_POSTCOND(m_bRun
,"Could not start event notifier!");
157 //------------------------------------------------
159 //------------------------------------------------
161 void SAL_CALL
CAsyncEventNotifier::shutdown()
163 unsigned nThreadId
= GetCurrentThreadId();
165 OSL_PRECOND(nThreadId
!= m_ThreadId
, "Method called in wrong thread context!");
167 osl::ResettableMutexGuard
aGuard(m_Mutex
);
169 OSL_PRECOND(m_bRun
,"Event notifier does not run!");
174 // awake the the notifier thread
175 SetEvent(m_ResumeNotifying
);
176 SetEvent(m_NotifyEvent
);
178 // releas the mutex here because the event
179 // notifier thread may need it to finish
182 // we are waiting infinite, so error will
183 // be better detected in form of deadlocks
184 if (WaitForSingleObject(m_hThread
, INFINITE
) == WAIT_FAILED
) {
185 OSL_ENSURE(false, "Waiting for thread termination failed!");
188 // lock mutex again to reset m_hThread
189 // and prevent a race with start()
192 CloseHandle(m_hThread
);
196 //------------------------------------------------
198 //------------------------------------------------
200 void CAsyncEventNotifier::suspend()
202 ResetEvent(m_ResumeNotifying
);
205 //------------------------------------------------
207 //------------------------------------------------
209 void CAsyncEventNotifier::resume()
211 SetEvent(m_ResumeNotifying
);
214 //------------------------------------------------
216 //------------------------------------------------
218 void SAL_CALL
CAsyncEventNotifier::notifyEvent(CEventNotification
* EventNotification
)
220 osl::MutexGuard
aGuard(m_Mutex
);
222 OSL_ENSURE(m_bRun
,"Event notifier is not running!");
226 m_EventList
.push_back(EventNotification
);
227 SetEvent(m_NotifyEvent
);
231 //------------------------------------------------
233 //------------------------------------------------
235 size_t SAL_CALL
CAsyncEventNotifier::getEventListSize()
237 osl::MutexGuard
aGuard(m_Mutex
);
238 return m_EventList
.size();
241 //------------------------------------------------
243 //------------------------------------------------
245 void SAL_CALL
CAsyncEventNotifier::resetNotifyEvent()
247 osl::MutexGuard
aGuard(m_Mutex
);
248 if (0 == m_EventList
.size())
249 ResetEvent(m_NotifyEvent
);
252 //------------------------------------------------
254 //------------------------------------------------
256 CEventNotification
* SAL_CALL
CAsyncEventNotifier::getNextEventRecord()
258 osl::MutexGuard
aGuard(m_Mutex
);
259 return m_EventList
.front();
262 //------------------------------------------------
264 //------------------------------------------------
266 void SAL_CALL
CAsyncEventNotifier::removeNextEventRecord()
268 osl::MutexGuard
aGuard(m_Mutex
);
269 m_EventList
.pop_front();
272 //------------------------------------------------
274 //------------------------------------------------
276 void SAL_CALL
CAsyncEventNotifier::run()
280 WaitForMultipleObjects(2, m_hEvents
, true, INFINITE
);
284 while (getEventListSize() > 0)
286 std::auto_ptr
<CEventNotification
> EventNotification(getNextEventRecord());
287 removeNextEventRecord();
289 ::cppu::OInterfaceContainerHelper
* pICHelper
=
290 m_rBroadcastHelper
.getContainer(getCppuType((uno::Reference
<XFilePickerListener
>*)0));
294 ::cppu::OInterfaceIteratorHelper
iter(*pICHelper
);
296 while(iter
.hasMoreElements())
300 EventNotification
->notifyEventListener(iter
.next());
302 catch(uno::RuntimeException
&)
304 OSL_ENSURE(sal_False
,"RuntimeException during event dispatching");
309 } // while(getEventListSize() > 0)
318 //------------------------------------------------
320 //------------------------------------------------
322 unsigned int WINAPI
CAsyncEventNotifier::ThreadProc(LPVOID pParam
)
324 CAsyncEventNotifier
* pInst
= reinterpret_cast< CAsyncEventNotifier
* >(pParam
);