Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : :
20 : : #ifndef COMPHELPER_ASYNCNOTIFICATION_HXX
21 : : #define COMPHELPER_ASYNCNOTIFICATION_HXX
22 : :
23 : : #include "sal/config.h"
24 : :
25 : : #include "boost/scoped_ptr.hpp"
26 : : #include "comphelper/comphelperdllapi.h"
27 : : #include "rtl/ref.hxx"
28 : : #include "sal/types.h"
29 : : #include "salhelper/thread.hxx"
30 : :
31 : : //........................................................................
32 : : namespace comphelper
33 : : {
34 : : //........................................................................
35 : :
36 : : //====================================================================
37 : : //= AnyEvent
38 : : //====================================================================
39 : : /** the very basic instance to hold a description of an event
40 : : */
41 : : class COMPHELPER_DLLPUBLIC AnyEvent : ::rtl::IReference
42 : : {
43 : : private:
44 : : oslInterlockedCount m_refCount;
45 : :
46 : : public:
47 : : AnyEvent();
48 : :
49 : : virtual oslInterlockedCount SAL_CALL acquire();
50 : : virtual oslInterlockedCount SAL_CALL release();
51 : :
52 : : protected:
53 : : virtual ~AnyEvent();
54 : :
55 : : private:
56 : : AnyEvent( AnyEvent& ); // not defined
57 : : void operator=( AnyEvent& ); // not defined
58 : : };
59 : :
60 : : //====================================================================
61 : : //= typedefs
62 : : //====================================================================
63 : : typedef ::rtl::Reference< AnyEvent > AnyEventRef;
64 : :
65 : : //====================================================================
66 : : //= IEventProcessor
67 : : //====================================================================
68 : : /** an event processor
69 : :
70 : : @see AsyncEventNotifier
71 : : */
72 : 198 : class SAL_NO_VTABLE IEventProcessor
73 : : {
74 : : public:
75 : : /** process a single event
76 : : */
77 : : virtual void processEvent( const AnyEvent& _rEvent ) = 0;
78 : :
79 : : virtual void SAL_CALL acquire() = 0;
80 : : virtual void SAL_CALL release() = 0;
81 : :
82 : : protected:
83 : 198 : ~IEventProcessor() {}
84 : : };
85 : :
86 : : //====================================================================
87 : : //= AsyncEventNotifier
88 : : //====================================================================
89 : : struct EventNotifierImpl;
90 : :
91 : : /** a helper class for notifying events asynchronously
92 : :
93 : : If you need to notify certain events to external components, you usually should
94 : : not do this while you have mutexes locked, to prevent multi-threading issues.
95 : :
96 : : However, you do not always have complete control over all mutex guards on the stack.
97 : : If, in such a case, the listener notification is one-way, you can decide to do it
98 : : asynchronously.
99 : :
100 : : The ->AsyncEventNotifier helps you to process such events asynchronously. Every
101 : : event is tied to an ->IEventProcessor which is responsible for processing it.
102 : :
103 : : The AsyncEventNotifier is implemented as a thread itself, which sleeps as long as there are no
104 : : events in the queue. As soon as you add an event, the thread is woken up, processes the event,
105 : : and sleeps again.
106 : : */
107 : : class COMPHELPER_DLLPUBLIC AsyncEventNotifier: public salhelper::Thread
108 : : {
109 : : friend struct EventNotifierImpl;
110 : :
111 : : private:
112 : : boost::scoped_ptr< EventNotifierImpl > m_pImpl;
113 : :
114 : : SAL_DLLPRIVATE virtual ~AsyncEventNotifier();
115 : :
116 : : // Thread
117 : : SAL_DLLPRIVATE virtual void execute();
118 : :
119 : : public:
120 : : /** constructs a notifier thread
121 : :
122 : : @param name the thread name, see ::osl_setThreadName; must not be
123 : : null
124 : : */
125 : : AsyncEventNotifier(char const * name);
126 : :
127 : : /** terminates the thread
128 : :
129 : : Note that this is a cooporative termination - if you call this from a thread different
130 : : from the notification thread itself, then it will block until the notification thread
131 : : finished processing the current event. If you call it from the notification thread
132 : : itself, it will return immediately, and the thread will be terminated as soon as
133 : : the current notification is finished.
134 : : */
135 : : virtual void SAL_CALL terminate();
136 : :
137 : : /** adds an event to the queue, together with the instance which is responsible for
138 : : processing it
139 : :
140 : : @param _rEvent
141 : : the event to add to the queue
142 : : @param _xProcessor
143 : : the processor for the event.<br/>
144 : : Beware of life time issues here. If your event processor dies or becomes otherwise
145 : : nonfunctional, you are responsible for removing all respective events from the queue.
146 : : You can do this by calling ->removeEventsForProcessor
147 : : */
148 : : void addEvent( const AnyEventRef& _rEvent, const ::rtl::Reference< IEventProcessor >& _xProcessor );
149 : :
150 : : /** removes all events for the given event processor from the queue
151 : : */
152 : : void removeEventsForProcessor( const ::rtl::Reference< IEventProcessor >& _xProcessor );
153 : : };
154 : :
155 : : //====================================================================
156 : : //= EventHolder
157 : : //====================================================================
158 : : /** AnyEvent derivee holding an foreign event instance
159 : : */
160 : : template < typename EVENT_OBJECT >
161 [ + - ][ - + ]: 856 : class EventHolder : public AnyEvent
162 : : {
163 : : public:
164 : : typedef EVENT_OBJECT EventObjectType;
165 : :
166 : : private:
167 : : EventObjectType m_aEvent;
168 : :
169 : : public:
170 : 428 : inline EventHolder( const EventObjectType& _rEvent )
171 [ + - ]: 428 : :m_aEvent( _rEvent )
172 : : {
173 : 428 : }
174 : :
175 : 428 : inline const EventObjectType& getEventObject() const { return m_aEvent; }
176 : : };
177 : :
178 : : //........................................................................
179 : : } // namespace comphelper
180 : : //........................................................................
181 : :
182 : : #endif // COMPHELPER_ASYNCNOTIFICATION_HXX
183 : :
184 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|