Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / include / comphelper / asyncnotification.hxx
blob69c5647c5bdacab2ec416d5d4e85ce6abd000b4b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 #ifndef INCLUDED_COMPHELPER_ASYNCNOTIFICATION_HXX
21 #define INCLUDED_COMPHELPER_ASYNCNOTIFICATION_HXX
23 #include <sal/config.h>
25 #include <comphelper/comphelperdllapi.h>
26 #include <rtl/ref.hxx>
27 #include <sal/types.h>
28 #include <salhelper/thread.hxx>
29 #include <salhelper/simplereferenceobject.hxx>
30 #include <memory>
32 namespace comphelper
34 //= AnyEvent
36 /** the very basic instance to hold a description of an event
38 class COMPHELPER_DLLPUBLIC AnyEvent : public salhelper::SimpleReferenceObject
40 public:
41 AnyEvent();
43 protected:
44 virtual ~AnyEvent() override;
46 private:
47 AnyEvent( AnyEvent& ) = delete;
48 void operator=( AnyEvent& ) = delete;
52 //= typedefs
54 typedef ::rtl::Reference< AnyEvent > AnyEventRef;
57 //= IEventProcessor
59 /** an event processor
61 @see AsyncEventNotifier
63 class SAL_NO_VTABLE IEventProcessor
65 public:
66 /** process a single event
68 virtual void processEvent( const AnyEvent& _rEvent ) = 0;
70 virtual void SAL_CALL acquire() throw () = 0;
71 virtual void SAL_CALL release() throw () = 0;
73 protected:
74 ~IEventProcessor() {}
78 //= AsyncEventNotifier
80 struct EventNotifierImpl;
82 /** a helper class for notifying events asynchronously
84 If you need to notify certain events to external components, you usually should
85 not do this while you have mutexes locked, to prevent multi-threading issues.
87 However, you do not always have complete control over all mutex guards on the stack.
88 If, in such a case, the listener notification is one-way, you can decide to do it
89 asynchronously.
91 The ->AsyncEventNotifier helps you to process such events asynchronously. Every
92 event is tied to an ->IEventProcessor which is responsible for processing it.
94 The AsyncEventNotifier is implemented as a thread itself, which sleeps as long as there are no
95 events in the queue. As soon as you add an event, the thread is woken up, processes the event,
96 and sleeps again.
98 class COMPHELPER_DLLPUBLIC AsyncEventNotifierBase
100 friend struct EventNotifierImpl;
102 protected:
103 std::unique_ptr<EventNotifierImpl> m_xImpl;
105 SAL_DLLPRIVATE virtual ~AsyncEventNotifierBase();
107 // Thread
108 SAL_DLLPRIVATE virtual void execute();
110 public:
111 AsyncEventNotifierBase();
113 /** terminates the thread
115 Note that this is a cooperative termination - if you call this from a thread different
116 from the notification thread itself, then it will block until the notification thread
117 finished processing the current event. If you call it from the notification thread
118 itself, it will return immediately, and the thread will be terminated as soon as
119 the current notification is finished.
121 virtual void SAL_CALL terminate();
123 /** adds an event to the queue, together with the instance which is responsible for
124 processing it
126 @param _rEvent
127 the event to add to the queue
128 @param _xProcessor
129 the processor for the event.<br/>
130 Beware of life time issues here. If your event processor dies or becomes otherwise
131 nonfunctional, you are responsible for removing all respective events from the queue.
132 You can do this by calling ->removeEventsForProcessor
134 void addEvent( const AnyEventRef& _rEvent, const ::rtl::Reference< IEventProcessor >& _xProcessor );
136 /** removes all events for the given event processor from the queue
138 void removeEventsForProcessor( const ::rtl::Reference< IEventProcessor >& _xProcessor );
141 /** This class is usable with rtl::Reference.
142 As always, the thread must be joined somewhere.
144 class COMPHELPER_DLLPUBLIC AsyncEventNotifier
145 : public AsyncEventNotifierBase
146 , public salhelper::Thread
149 private:
150 SAL_DLLPRIVATE virtual ~AsyncEventNotifier() override;
152 SAL_DLLPRIVATE virtual void execute() override;
154 public:
155 /** constructs a notifier thread
157 @param name the thread name, see ::osl_setThreadName; must not be
158 null
160 AsyncEventNotifier(char const* name);
162 virtual void SAL_CALL terminate() override;
165 /** This is a hack (when proper joining is not possible), use of which
166 should be avoided by good design.
168 class COMPHELPER_DLLPUBLIC AsyncEventNotifierAutoJoin
169 : public AsyncEventNotifierBase
170 , private osl::Thread
173 private:
174 SAL_DLLPRIVATE AsyncEventNotifierAutoJoin(char const* name);
176 SAL_DLLPRIVATE virtual void SAL_CALL run() override;
177 SAL_DLLPRIVATE virtual void SAL_CALL onTerminated() override;
179 public:
180 // only public so shared_ptr finds it
181 SAL_DLLPRIVATE virtual ~AsyncEventNotifierAutoJoin() override;
183 static std::shared_ptr<AsyncEventNotifierAutoJoin>
184 newAsyncEventNotifierAutoJoin(char const* name);
186 virtual void SAL_CALL terminate() override;
188 using osl::Thread::join;
189 using osl::Thread::operator new;
190 using osl::Thread::operator delete; // clang really wants this?
192 static void launch(std::shared_ptr<AsyncEventNotifierAutoJoin> const&);
196 //= EventHolder
198 /** AnyEvent derivee holding an foreign event instance
200 template < typename EVENT_OBJECT >
201 class EventHolder : public AnyEvent
203 public:
204 typedef EVENT_OBJECT EventObjectType;
206 private:
207 EventObjectType m_aEvent;
209 public:
210 EventHolder( const EventObjectType& _rEvent )
211 :m_aEvent( _rEvent )
215 const EventObjectType& getEventObject() const { return m_aEvent; }
218 COMPHELPER_DLLPUBLIC void JoinAsyncEventNotifiers();
220 } // namespace comphelper
223 #endif // INCLUDED_COMPHELPER_ASYNCNOTIFICATION_HXX
225 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */