Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "EventThread.hxx"
30 : : #include <comphelper/guarding.hxx>
31 : : #include <tools/debug.hxx>
32 : :
33 : : //.........................................................................
34 : : namespace frm
35 : : {
36 : : //.........................................................................
37 : : using namespace ::com::sun::star::uno;
38 : : using namespace ::com::sun::star::awt;
39 : : using namespace ::com::sun::star::lang;
40 : :
41 : : DBG_NAME( OComponentEventThread )
42 : 0 : OComponentEventThread::OComponentEventThread( ::cppu::OComponentHelper* pCompImpl ) :
43 [ # # ][ # # ]: 0 : m_pCompImpl( pCompImpl )
[ # # ][ # # ]
[ # # ]
44 : : {
45 : : DBG_CTOR( OComponentEventThread, NULL );
46 : :
47 [ # # ]: 0 : increment(m_refCount);
48 : :
49 : : // Hold a reference of the Control
50 : : {
51 [ # # ]: 0 : InterfaceRef xIFace(static_cast<XWeak*>(pCompImpl));
52 [ # # ]: 0 : query_interface(xIFace, m_xComp);
53 : : }
54 : :
55 : : // and add us at the Control
56 : : {
57 [ # # ]: 0 : Reference<XEventListener> xEvtLstnr = static_cast<XEventListener*>(this);
58 [ # # ][ # # ]: 0 : m_xComp->addEventListener( xEvtLstnr );
59 : : }
60 : :
61 [ # # ]: 0 : decrement(m_refCount);
62 : 0 : }
63 : :
64 [ # # ][ # # ]: 0 : OComponentEventThread::~OComponentEventThread()
[ # # ]
65 : : {
66 : : DBG_DTOR( OComponentEventThread, NULL );
67 : :
68 : : DBG_ASSERT( m_aEvents.empty(),
69 : : "OComponentEventThread::~OComponentEventThread: Didn't call dispose?" );
70 : :
71 [ # # ]: 0 : impl_clearEventQueue();
72 [ # # ]: 0 : }
73 : :
74 : 0 : Any SAL_CALL OComponentEventThread::queryInterface(const Type& _rType) throw (RuntimeException)
75 : : {
76 : 0 : Any aReturn;
77 : :
78 [ # # ]: 0 : aReturn = OWeakObject::queryInterface(_rType);
79 : :
80 [ # # ]: 0 : if (!aReturn.hasValue())
81 : : aReturn = ::cppu::queryInterface(_rType,
82 : : static_cast<XEventListener*>(this)
83 [ # # ]: 0 : );
84 : :
85 : 0 : return aReturn;
86 : : }
87 : :
88 : 0 : void OComponentEventThread::impl_clearEventQueue()
89 : : {
90 [ # # ]: 0 : while ( m_aEvents.size() )
91 : : {
92 [ # # ][ # # ]: 0 : delete *m_aEvents.begin();
93 : 0 : m_aEvents.erase( m_aEvents.begin() );
94 : : }
95 : 0 : m_aControls.erase( m_aControls.begin(), m_aControls.end() );
96 : 0 : m_aFlags.erase( m_aFlags.begin(), m_aFlags.end() );
97 : 0 : }
98 : :
99 : 0 : void OComponentEventThread::disposing( const EventObject& evt ) throw ( ::com::sun::star::uno::RuntimeException)
100 : : {
101 [ # # ]: 0 : if( evt.Source == m_xComp )
102 : : {
103 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
104 : :
105 : : // Remove EventListener
106 [ # # ]: 0 : Reference<XEventListener> xEvtLstnr = static_cast<XEventListener*>(this);
107 [ # # ][ # # ]: 0 : m_xComp->removeEventListener( xEvtLstnr );
108 : :
109 : : // Clear EventQueue
110 [ # # ]: 0 : impl_clearEventQueue();
111 : :
112 : : // Free the Control and set pCompImpl to 0,
113 : : // so that the thread knows, that it should terminate.
114 [ # # ]: 0 : m_xComp = 0;
115 : 0 : m_pCompImpl = 0;
116 : :
117 : : // Wake up the thread and terminate
118 [ # # ]: 0 : m_aCond.set();
119 [ # # ][ # # ]: 0 : terminate();
120 : : }
121 : 0 : }
122 : :
123 : 0 : void OComponentEventThread::addEvent( const EventObject* _pEvt, sal_Bool bFlag )
124 : : {
125 : 0 : Reference<XControl> xTmp;
126 [ # # ]: 0 : addEvent( _pEvt, xTmp, bFlag );
127 : 0 : }
128 : :
129 : 0 : void OComponentEventThread::addEvent( const EventObject* _pEvt,
130 : : const Reference<XControl>& rControl,
131 : : sal_Bool bFlag )
132 : : {
133 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
134 : :
135 : : // Put data into the queue
136 [ # # ][ # # ]: 0 : m_aEvents.push_back( cloneEvent( _pEvt ) );
137 : :
138 [ # # ]: 0 : Reference<XWeak> xWeakControl(rControl, UNO_QUERY);
139 [ # # ][ # # ]: 0 : Reference<XAdapter> xControlAdapter = xWeakControl.is() ? xWeakControl->queryAdapter() : Reference<XAdapter>();
[ # # ]
140 [ # # ]: 0 : m_aControls.push_back( xControlAdapter );
141 : :
142 [ # # ]: 0 : m_aFlags.push_back( bFlag );
143 : :
144 : : // Wake up thread
145 [ # # ][ # # ]: 0 : m_aCond.set();
146 : 0 : }
147 : :
148 : 0 : void OComponentEventThread::implStarted( )
149 : : {
150 : 0 : acquire( );
151 : 0 : }
152 : :
153 : 0 : void OComponentEventThread::implTerminated( )
154 : : {
155 : 0 : release( );
156 : 0 : }
157 : :
158 : 0 : void SAL_CALL OComponentEventThread::kill()
159 : : {
160 : 0 : OComponentEventThread_TBASE::terminate();
161 : 0 : OComponentEventThread_TBASE::join();
162 : :
163 : 0 : implTerminated( );
164 : 0 : }
165 : :
166 : 0 : void SAL_CALL OComponentEventThread::onTerminated()
167 : : {
168 : 0 : OComponentEventThread_TBASE::onTerminated();
169 : :
170 : 0 : implTerminated( );
171 : 0 : }
172 : :
173 : 0 : void OComponentEventThread::run()
174 : : {
175 : 0 : implStarted( );
176 : :
177 : : // Hold on to ourselves, so that we're not deleted if a dispose is called at some point in time
178 [ # # ]: 0 : InterfaceRef xThis(static_cast<XWeak*>(this));
179 : :
180 : 0 : do
181 : : {
182 [ # # ]: 0 : ::osl::MutexGuard aGuard(m_aMutex);
183 : :
184 [ # # ]: 0 : while( m_aEvents.size() > 0 )
185 : : {
186 : : // Get the Control and hold on to it so that it cannot be deleted during actionPerformed
187 : 0 : Reference<XComponent> xComp = m_xComp;
188 : 0 : ::cppu::OComponentHelper *pCompImpl = m_pCompImpl;
189 : :
190 : 0 : ThreadEvents::iterator firstEvent( m_aEvents.begin() );
191 : 0 : EventObject* pEvt = *firstEvent;
192 [ # # ]: 0 : m_aEvents.erase( firstEvent );
193 : :
194 : 0 : ThreadObjects::iterator firstControl( m_aControls.begin() );
195 : 0 : Reference<XAdapter> xControlAdapter = *firstControl;
196 [ # # ]: 0 : m_aControls.erase( firstControl );
197 : :
198 : 0 : ThreadBools::iterator firstFlag( m_aFlags.begin() );
199 [ # # ]: 0 : sal_Bool bFlag = *firstFlag;
200 [ # # ]: 0 : m_aFlags.erase( firstFlag );
201 : :
202 : : {
203 [ # # ]: 0 : MutexRelease aReleaseOnce(m_aMutex);
204 : : // Because a queryHardRef can throw an Exception, it shoudln't be called when
205 : : // the mutex is locked.
206 : 0 : Reference<XControl> xControl;
207 [ # # ]: 0 : if ( xControlAdapter.is() )
208 [ # # ][ # # ]: 0 : query_interface(xControlAdapter->queryAdapted(), xControl);
[ # # ]
209 : :
210 [ # # ]: 0 : if( xComp.is() )
211 [ # # ][ # # ]: 0 : processEvent( pCompImpl, pEvt, xControl, bFlag );
212 : : }
213 : :
214 [ # # ][ # # ]: 0 : delete pEvt;
215 : 0 : };
216 : :
217 : : // After a Dispose, we do not know the Control anymore.
218 : : // Thus, we must not wait either.
219 [ # # ]: 0 : if( !m_xComp.is() )
220 : 0 : return;
221 : :
222 : : // Reset waiting condition
223 [ # # ]: 0 : m_aCond.reset();
224 : : {
225 [ # # ]: 0 : MutexRelease aReleaseOnce(m_aMutex);
226 : : // And wait ... if, in the meantime, an Event came in after all
227 [ # # ][ # # ]: 0 : m_aCond.wait();
228 [ # # ][ # # ]: 0 : }
229 : : }
230 : 0 : while( sal_True );
231 : : }
232 : :
233 : : //.........................................................................
234 : : } // namespace frm
235 : : //.........................................................................
236 : :
237 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|