merged tag ooo/DEV300_m102
[LibreOffice.git] / fpicker / source / win32 / filepicker / asynceventnotifier.cxx
blob592c9e0c0e47cbc14893b84e80d40b882913c948
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_fpicker.hxx"
31 //------------------------------------------------------------------------
32 // includes
33 //------------------------------------------------------------------------
34 #include <osl/diagnose.h>
35 #include "asynceventnotifier.hxx"
36 #include <com/sun/star/uno/RuntimeException.hpp>
37 #include <com/sun/star/ui/dialogs/XFilePickerListener.hpp>
39 #include <process.h>
40 #include <memory>
41 #include "SolarMutex.hxx"
43 //------------------------------------------------
45 //------------------------------------------------
47 using namespace com::sun::star;
48 using ::com::sun::star::ui::dialogs::XFilePickerListener;
50 //------------------------------------------------
52 //------------------------------------------------
54 CAsyncEventNotifier::CAsyncEventNotifier(cppu::OBroadcastHelper& rBroadcastHelper) :
55 m_hThread(0),
56 m_bRun(false),
57 m_ThreadId(0),
58 m_rBroadcastHelper(rBroadcastHelper),
59 m_NotifyEvent(m_hEvents[0]),
60 m_ResumeNotifying(m_hEvents[1])
62 // m_NotifyEvent
63 m_hEvents[0] = CreateEvent(0, /* no security */
64 true, /* manual reset */
65 false, /* initial state not signaled */
66 0); /* automatic name */
68 // m_ResumeNotifying
69 m_hEvents[1] = CreateEvent(0, /* no security */
70 true, /* manual reset */
71 false, /* initial state not signaled */
72 0); /* automatic name */
75 //------------------------------------------------
77 //------------------------------------------------
79 CAsyncEventNotifier::~CAsyncEventNotifier()
81 OSL_ENSURE(0 == m_hThread,"Thread not stopped, destroying this instance leads to desaster");
83 CloseHandle(m_hEvents[0]);
84 CloseHandle(m_hEvents[1]);
87 //------------------------------------------------
89 //------------------------------------------------
91 void SAL_CALL CAsyncEventNotifier::addListener(const uno::Type& aType ,
92 const uno::Reference< uno::XInterface >& xListener)
94 if ( m_rBroadcastHelper.bDisposed )
95 throw lang::DisposedException(
96 ::rtl::OUString::createFromAscii( "FilePicker is already disposed" ),
97 uno::Reference< uno::XInterface >() );
99 if ( m_rBroadcastHelper.bInDispose )
100 throw lang::DisposedException(
101 ::rtl::OUString::createFromAscii( "FilePicker will be disposed now." ),
102 uno::Reference< uno::XInterface >() );
104 m_rBroadcastHelper.aLC.addInterface( aType, xListener );
107 //------------------------------------------------
109 //------------------------------------------------
111 void SAL_CALL CAsyncEventNotifier::removeListener(const uno::Type& aType ,
112 const uno::Reference< uno::XInterface >& xListener)
114 if ( m_rBroadcastHelper.bDisposed )
115 throw lang::DisposedException(
116 ::rtl::OUString::createFromAscii( "FilePicker is already disposed." ),
117 uno::Reference< uno::XInterface >() );
119 m_rBroadcastHelper.aLC.removeInterface( aType, xListener );
122 //------------------------------------------------
124 //------------------------------------------------
126 bool SAL_CALL CAsyncEventNotifier::startup(bool bCreateSuspended)
128 osl::MutexGuard aGuard(m_Mutex);
130 // m_bRun may already be false because of a
131 // call to stop but the thread did not yet
132 // terminate so m_hEventNotifierThread is
133 // yet a valid thread handle that should
134 // not be overwritten
135 if (!m_bRun)
137 if (!bCreateSuspended)
138 SetEvent(m_ResumeNotifying);
140 m_hThread = (HANDLE)_beginthreadex(
141 NULL, 0, CAsyncEventNotifier::ThreadProc, this, 0, &m_ThreadId);
143 OSL_ASSERT(0 != m_hThread);
145 if (m_hThread)
146 m_bRun = true;
149 OSL_POSTCOND(m_bRun,"Could not start event notifier!");
151 return m_bRun;
154 //------------------------------------------------
156 //------------------------------------------------
158 void SAL_CALL CAsyncEventNotifier::shutdown()
160 unsigned nThreadId = GetCurrentThreadId();
162 OSL_PRECOND(nThreadId != m_ThreadId, "Method called in wrong thread context!");
164 osl::ResettableMutexGuard aGuard(m_Mutex);
166 OSL_PRECOND(m_bRun,"Event notifier does not run!");
168 m_bRun = false;
169 m_EventList.clear();
171 // awake the the notifier thread
172 SetEvent(m_ResumeNotifying);
173 SetEvent(m_NotifyEvent);
175 // releas the mutex here because the event
176 // notifier thread may need it to finish
177 aGuard.clear();
179 // we are waiting infinite, so error will
180 // be better detected in form of deadlocks
181 if (WaitForSingleObject(m_hThread, INFINITE) == WAIT_FAILED) {
182 OSL_ENSURE(false, "Waiting for thread termination failed!");
185 // lock mutex again to reset m_hThread
186 // and prevent a race with start()
187 aGuard.reset();
189 CloseHandle(m_hThread);
190 m_hThread = 0;
193 //------------------------------------------------
195 //------------------------------------------------
197 void CAsyncEventNotifier::suspend()
199 ResetEvent(m_ResumeNotifying);
202 //------------------------------------------------
204 //------------------------------------------------
206 void CAsyncEventNotifier::resume()
208 SetEvent(m_ResumeNotifying);
211 //------------------------------------------------
213 //------------------------------------------------
215 void SAL_CALL CAsyncEventNotifier::notifyEvent(CEventNotification* EventNotification)
217 osl::MutexGuard aGuard(m_Mutex);
219 OSL_ENSURE(m_bRun,"Event notifier is not running!");
221 if (m_bRun)
223 m_EventList.push_back(EventNotification);
224 SetEvent(m_NotifyEvent);
228 //------------------------------------------------
230 //------------------------------------------------
232 size_t SAL_CALL CAsyncEventNotifier::getEventListSize()
234 osl::MutexGuard aGuard(m_Mutex);
235 return m_EventList.size();
238 //------------------------------------------------
240 //------------------------------------------------
242 void SAL_CALL CAsyncEventNotifier::resetNotifyEvent()
244 osl::MutexGuard aGuard(m_Mutex);
245 if (0 == m_EventList.size())
246 ResetEvent(m_NotifyEvent);
249 //------------------------------------------------
251 //------------------------------------------------
253 CEventNotification* SAL_CALL CAsyncEventNotifier::getNextEventRecord()
255 osl::MutexGuard aGuard(m_Mutex);
256 return m_EventList.front();
259 //------------------------------------------------
261 //------------------------------------------------
263 void SAL_CALL CAsyncEventNotifier::removeNextEventRecord()
265 osl::MutexGuard aGuard(m_Mutex);
266 m_EventList.pop_front();
269 //------------------------------------------------
271 //------------------------------------------------
273 void SAL_CALL CAsyncEventNotifier::run()
275 while (m_bRun)
277 WaitForMultipleObjects(2, m_hEvents, true, INFINITE);
279 if (m_bRun)
281 while (getEventListSize() > 0)
283 std::auto_ptr<CEventNotification> EventNotification(getNextEventRecord());
284 removeNextEventRecord();
286 ::cppu::OInterfaceContainerHelper* pICHelper =
287 m_rBroadcastHelper.getContainer(getCppuType((uno::Reference<XFilePickerListener>*)0));
289 if (pICHelper)
291 ::cppu::OInterfaceIteratorHelper iter(*pICHelper);
293 while(iter.hasMoreElements())
297 EventNotification->notifyEventListener(iter.next());
299 catch(uno::RuntimeException&)
301 OSL_ENSURE(sal_False,"RuntimeException during event dispatching");
306 } // while(getEventListSize() > 0)
308 resetNotifyEvent();
310 } // if (m_bRun)
312 } // while(m_bRun)
315 //------------------------------------------------
317 //------------------------------------------------
319 unsigned int WINAPI CAsyncEventNotifier::ThreadProc(LPVOID pParam)
321 CAsyncEventNotifier* pInst = reinterpret_cast< CAsyncEventNotifier* >(pParam);
322 OSL_ASSERT(pInst);
324 pInst->run();
326 return 0;