1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "EventThread.hxx"
21 #include <comphelper/guarding.hxx>
22 #include <tools/debug.hxx>
23 #include <cppuhelper/queryinterface.hxx>
25 #include <boost/scoped_ptr.hpp>
30 using namespace ::com::sun::star::uno
;
31 using namespace ::com::sun::star::awt
;
32 using namespace ::com::sun::star::lang
;
34 OComponentEventThread::OComponentEventThread( ::cppu::OComponentHelper
* pCompImpl
) :
35 m_pCompImpl( pCompImpl
)
38 osl_atomic_increment(&m_refCount
);
40 // Hold a reference of the Control
42 InterfaceRef
xIFace(static_cast<XWeak
*>(pCompImpl
));
43 m_xComp
.set(xIFace
, css::uno::UNO_QUERY
);
46 // and add us at the Control
48 Reference
<XEventListener
> xEvtLstnr
= static_cast<XEventListener
*>(this);
49 m_xComp
->addEventListener( xEvtLstnr
);
52 osl_atomic_decrement(&m_refCount
);
55 OComponentEventThread::~OComponentEventThread()
58 DBG_ASSERT( m_aEvents
.empty(),
59 "OComponentEventThread::~OComponentEventThread: Didn't call dispose?" );
61 impl_clearEventQueue();
64 Any SAL_CALL
OComponentEventThread::queryInterface(const Type
& _rType
) throw (RuntimeException
, std::exception
)
68 aReturn
= OWeakObject::queryInterface(_rType
);
70 if (!aReturn
.hasValue())
71 aReturn
= ::cppu::queryInterface(_rType
,
72 static_cast<XEventListener
*>(this)
78 void OComponentEventThread::impl_clearEventQueue()
80 while ( m_aEvents
.size() )
82 delete *m_aEvents
.begin();
83 m_aEvents
.erase( m_aEvents
.begin() );
85 m_aControls
.erase( m_aControls
.begin(), m_aControls
.end() );
86 m_aFlags
.erase( m_aFlags
.begin(), m_aFlags
.end() );
89 void OComponentEventThread::disposing( const EventObject
& evt
) throw ( ::com::sun::star::uno::RuntimeException
, std::exception
)
91 if( evt
.Source
== m_xComp
)
93 ::osl::MutexGuard
aGuard( m_aMutex
);
95 // Remove EventListener
96 Reference
<XEventListener
> xEvtLstnr
= static_cast<XEventListener
*>(this);
97 m_xComp
->removeEventListener( xEvtLstnr
);
100 impl_clearEventQueue();
102 // Free the Control and set pCompImpl to 0,
103 // so that the thread knows, that it should terminate.
107 // Wake up the thread and terminate
113 void OComponentEventThread::addEvent( const EventObject
* _pEvt
, bool bFlag
)
115 Reference
<XControl
> xTmp
;
116 addEvent( _pEvt
, xTmp
, bFlag
);
119 void OComponentEventThread::addEvent( const EventObject
* _pEvt
,
120 const Reference
<XControl
>& rControl
,
123 ::osl::MutexGuard
aGuard( m_aMutex
);
125 // Put data into the queue
126 m_aEvents
.push_back( cloneEvent( _pEvt
) );
128 Reference
<XWeak
> xWeakControl(rControl
, UNO_QUERY
);
129 Reference
<XAdapter
> xControlAdapter
= xWeakControl
.is() ? xWeakControl
->queryAdapter() : Reference
<XAdapter
>();
130 m_aControls
.push_back( xControlAdapter
);
132 m_aFlags
.push_back( bFlag
);
138 void OComponentEventThread::implStarted( )
143 void OComponentEventThread::implTerminated( )
148 void SAL_CALL
OComponentEventThread::onTerminated()
150 OComponentEventThread_TBASE::onTerminated();
155 void OComponentEventThread::run()
157 osl_setThreadName("frm::OComponentEventThread");
161 // Hold on to ourselves, so that we're not deleted if a dispose is called at some point in time
162 InterfaceRef
xThis(static_cast<XWeak
*>(this));
166 ::osl::MutexGuard
aGuard(m_aMutex
);
168 while( m_aEvents
.size() > 0 )
170 // Get the Control and hold on to it so that it cannot be deleted during actionPerformed
171 Reference
<XComponent
> xComp
= m_xComp
;
172 ::cppu::OComponentHelper
*pCompImpl
= m_pCompImpl
;
174 ThreadEvents::iterator
firstEvent( m_aEvents
.begin() );
175 boost::scoped_ptr
<EventObject
> pEvt(*firstEvent
);
176 m_aEvents
.erase( firstEvent
);
178 ThreadObjects::iterator
firstControl( m_aControls
.begin() );
179 Reference
<XAdapter
> xControlAdapter
= *firstControl
;
180 m_aControls
.erase( firstControl
);
182 ThreadBools::iterator
firstFlag( m_aFlags
.begin() );
183 bool bFlag
= *firstFlag
;
184 m_aFlags
.erase( firstFlag
);
187 MutexRelease
aReleaseOnce(m_aMutex
);
188 // Because a queryHardRef can throw an Exception, it should not be called when
189 // the mutex is locked.
190 Reference
<XControl
> xControl
;
191 if ( xControlAdapter
.is() )
193 xControlAdapter
->queryAdapted(), css::uno::UNO_QUERY
);
196 processEvent( pCompImpl
, pEvt
.get(), xControl
, bFlag
);
200 // After a Dispose, we do not know the Control anymore.
201 // Thus, we must not wait either.
205 // Reset waiting condition
208 MutexRelease
aReleaseOnce(m_aMutex
);
209 // And wait ... if, in the meantime, an Event came in after all
220 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */