merge the formfield patch from ooo-build
[ooovba.git] / fpicker / source / win32 / filepicker / asynceventnotifier.cxx
blobba847f15ebf004da8a14dd89d21ecae679649fbd
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: asynceventnotifier.cxx,v $
10 * $Revision: 1.16 $
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 //------------------------------------------------------------------------
35 // includes
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>
42 #include <process.h>
43 #include <memory>
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) :
58 m_hThread(0),
59 m_bRun(false),
60 m_ThreadId(0),
61 m_rBroadcastHelper(rBroadcastHelper),
62 m_NotifyEvent(m_hEvents[0]),
63 m_ResumeNotifying(m_hEvents[1])
65 // m_NotifyEvent
66 m_hEvents[0] = CreateEvent(0, /* no security */
67 true, /* manual reset */
68 false, /* initial state not signaled */
69 0); /* automatic name */
71 // m_ResumeNotifying
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
138 if (!m_bRun)
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);
148 if (m_hThread)
149 m_bRun = true;
152 OSL_POSTCOND(m_bRun,"Could not start event notifier!");
154 return m_bRun;
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!");
171 m_bRun = false;
172 m_EventList.clear();
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
180 aGuard.clear();
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()
190 aGuard.reset();
192 CloseHandle(m_hThread);
193 m_hThread = 0;
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!");
224 if (m_bRun)
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()
278 while (m_bRun)
280 WaitForMultipleObjects(2, m_hEvents, true, INFINITE);
282 if (m_bRun)
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));
292 if (pICHelper)
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)
311 resetNotifyEvent();
313 } // if (m_bRun)
315 } // while(m_bRun)
318 //------------------------------------------------
320 //------------------------------------------------
322 unsigned int WINAPI CAsyncEventNotifier::ThreadProc(LPVOID pParam)
324 CAsyncEventNotifier* pInst = reinterpret_cast< CAsyncEventNotifier* >(pParam);
325 OSL_ASSERT(pInst);
327 pInst->run();
329 return 0;