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 //------------------------------------------------------------------------
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>
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
) :
58 m_rBroadcastHelper(rBroadcastHelper
),
59 m_NotifyEvent(m_hEvents
[0]),
60 m_ResumeNotifying(m_hEvents
[1])
63 m_hEvents
[0] = CreateEvent(0, /* no security */
64 true, /* manual reset */
65 false, /* initial state not signaled */
66 0); /* automatic name */
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
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
);
149 OSL_POSTCOND(m_bRun
,"Could not start event notifier!");
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!");
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
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()
189 CloseHandle(m_hThread
);
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!");
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()
277 WaitForMultipleObjects(2, m_hEvents
, true, INFINITE
);
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));
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)
315 //------------------------------------------------
317 //------------------------------------------------
319 unsigned int WINAPI
CAsyncEventNotifier::ThreadProc(LPVOID pParam
)
321 CAsyncEventNotifier
* pInst
= reinterpret_cast< CAsyncEventNotifier
* >(pParam
);