tdf#130857 qt weld: Support mail merge "Server Auth" dialog
[LibreOffice.git] / include / comphelper / asyncnotification.hxx
blobae241e4bc997abd04d863db2f648676499c349ec
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>
24 #include <config_options.h>
26 #include <com/sun/star/document/DocumentEvent.hpp>
27 #include <comphelper/comphelperdllapi.h>
28 #include <rtl/ref.hxx>
29 #include <sal/types.h>
30 #include <salhelper/thread.hxx>
31 #include <salhelper/simplereferenceobject.hxx>
32 #include <memory>
34 namespace comphelper
36 //= AnyEvent
38 /** the very basic instance to hold a description of an event
40 class COMPHELPER_DLLPUBLIC AnyEvent : public salhelper::SimpleReferenceObject
42 public:
43 AnyEvent();
45 protected:
46 virtual ~AnyEvent() override;
48 private:
49 AnyEvent( AnyEvent const & ) = delete;
50 AnyEvent& operator=( AnyEvent const & ) = delete;
54 //= typedefs
56 typedef ::rtl::Reference< AnyEvent > AnyEventRef;
59 //= IEventProcessor
61 /** an event processor
63 @see AsyncEventNotifier
65 class SAL_NO_VTABLE IEventProcessor
67 public:
68 /** process a single event
70 virtual void processEvent( const AnyEvent& _rEvent ) = 0;
72 virtual void SAL_CALL acquire() noexcept = 0;
73 virtual void SAL_CALL release() noexcept = 0;
75 protected:
76 ~IEventProcessor() {}
80 //= AsyncEventNotifier
82 struct EventNotifierImpl;
84 /** a helper class for notifying events asynchronously
86 If you need to notify certain events to external components, you usually should
87 not do this while you have mutexes locked, to prevent multi-threading issues.
89 However, you do not always have complete control over all mutex guards on the stack.
90 If, in such a case, the listener notification is one-way, you can decide to do it
91 asynchronously.
93 The ->AsyncEventNotifier helps you to process such events asynchronously. Every
94 event is tied to an ->IEventProcessor which is responsible for processing it.
96 The AsyncEventNotifier is implemented as a thread itself, which sleeps as long as there are no
97 events in the queue. As soon as you add an event, the thread is woken up, processes the event,
98 and sleeps again.
100 class COMPHELPER_DLLPUBLIC AsyncEventNotifierBase
102 friend struct EventNotifierImpl;
104 protected:
105 std::unique_ptr<EventNotifierImpl> m_xImpl;
107 SAL_DLLPRIVATE virtual ~AsyncEventNotifierBase();
109 // Thread
110 SAL_DLLPRIVATE virtual void execute();
112 public:
113 AsyncEventNotifierBase();
115 /** terminates the thread
117 Note that this is a cooperative termination - if you call this from a thread different
118 from the notification thread itself, then it will block until the notification thread
119 finished processing the current event. If you call it from the notification thread
120 itself, it will return immediately, and the thread will be terminated as soon as
121 the current notification is finished.
123 virtual void SAL_CALL terminate();
125 /** adds an event to the queue, together with the instance which is responsible for
126 processing it
128 @param _rEvent
129 the event to add to the queue
130 @param _xProcessor
131 the processor for the event.<br/>
132 Beware of life time issues here. If your event processor dies or becomes otherwise
133 nonfunctional, you are responsible for removing all respective events from the queue.
134 You can do this by calling ->removeEventsForProcessor
136 void addEvent( const AnyEventRef& _rEvent, const ::rtl::Reference< IEventProcessor >& _xProcessor );
138 /** removes all events for the given event processor from the queue
140 void removeEventsForProcessor( const ::rtl::Reference< IEventProcessor >& _xProcessor );
143 /** This class is usable with rtl::Reference.
144 As always, the thread must be joined somewhere.
146 class COMPHELPER_DLLPUBLIC AsyncEventNotifier final
147 : public AsyncEventNotifierBase
148 , public salhelper::Thread
151 private:
152 SAL_DLLPRIVATE virtual ~AsyncEventNotifier() override;
154 SAL_DLLPRIVATE virtual void execute() override;
156 public:
157 /** constructs a notifier thread
159 @param name the thread name, see ::osl_setThreadName; must not be
160 null
162 AsyncEventNotifier(char const* name);
164 virtual void SAL_CALL terminate() override;
167 /** This is a hack (when proper joining is not possible), use of which
168 should be avoided by good design.
170 class UNLESS_MERGELIBS_MORE(COMPHELPER_DLLPUBLIC) AsyncEventNotifierAutoJoin final
171 : public AsyncEventNotifierBase
172 , private osl::Thread
175 private:
176 SAL_DLLPRIVATE AsyncEventNotifierAutoJoin(char const* name);
178 SAL_DLLPRIVATE virtual void SAL_CALL run() override;
179 SAL_DLLPRIVATE virtual void SAL_CALL onTerminated() override;
181 public:
182 // only public so shared_ptr finds it
183 SAL_DLLPRIVATE virtual ~AsyncEventNotifierAutoJoin() override;
185 static std::shared_ptr<AsyncEventNotifierAutoJoin>
186 newAsyncEventNotifierAutoJoin(char const* name);
188 virtual void SAL_CALL terminate() override;
190 using osl::Thread::join;
191 using osl::Thread::operator new;
192 using osl::Thread::operator delete; // clang really wants this?
194 static void launch(std::shared_ptr<AsyncEventNotifierAutoJoin> const&);
198 //= EventHolder
200 /** AnyEvent derivee holding a foreign event instance
202 template < typename EVENT_OBJECT >
203 class SAL_DLLPUBLIC_TEMPLATE EventHolder final : public AnyEvent
205 public:
206 typedef EVENT_OBJECT EventObjectType;
208 private:
209 EventObjectType const m_aEvent;
211 public:
212 EventHolder( EventObjectType _aEvent )
213 :m_aEvent(std::move( _aEvent ))
217 const EventObjectType& getEventObject() const { return m_aEvent; }
220 extern template class EventHolder<css::document::DocumentEvent>;
221 using DocumentEventHolder = EventHolder<css::document::DocumentEvent>;
223 COMPHELPER_DLLPUBLIC void JoinAsyncEventNotifiers();
225 } // namespace comphelper
228 #endif // INCLUDED_COMPHELPER_ASYNCNOTIFICATION_HXX
230 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */