1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef COMPHELPER_ASYNCNOTIFICATION_HXX 25 #define COMPHELPER_ASYNCNOTIFICATION_HXX 26 27 #include <osl/thread.hxx> 28 #include <rtl/ref.hxx> 29 #include <comphelper/comphelperdllapi.h> 30 #include <rtl/alloc.h> 31 32 #include <memory> 33 34 //........................................................................ 35 namespace comphelper 36 { 37 //........................................................................ 38 39 //==================================================================== 40 //= AnyEvent 41 //==================================================================== 42 /** the very basic instance to hold a description of an event 43 */ 44 class COMPHELPER_DLLPUBLIC AnyEvent : ::rtl::IReference 45 { 46 private: 47 oslInterlockedCount m_refCount; 48 49 public: 50 AnyEvent(); 51 52 virtual oslInterlockedCount SAL_CALL acquire(); 53 virtual oslInterlockedCount SAL_CALL release(); 54 55 protected: 56 virtual ~AnyEvent(); 57 58 private: 59 AnyEvent( AnyEvent& ); // not defined 60 void operator=( AnyEvent& ); // not defined 61 }; 62 63 //==================================================================== 64 //= typedefs 65 //==================================================================== 66 typedef ::rtl::Reference< AnyEvent > AnyEventRef; 67 68 //==================================================================== 69 //= IEventProcessor 70 //==================================================================== 71 /** an event processor 72 73 @see AsyncEventNotifier 74 */ 75 class SAL_NO_VTABLE IEventProcessor 76 { 77 public: 78 /** process a single event 79 */ 80 virtual void processEvent( const AnyEvent& _rEvent ) = 0; 81 82 virtual void SAL_CALL acquire() = 0; 83 virtual void SAL_CALL release() = 0; 84 }; 85 86 //==================================================================== 87 //= AsyncEventNotifier 88 //==================================================================== 89 typedef ::osl::Thread AsyncEventNotifier_TBASE; 90 struct EventNotifierImpl; 91 92 /** a helper class for notifying events asynchronously 93 94 If you need to notify certain events to external components, you usually should 95 not do this while you have mutexes locked, to prevent multi-threading issues. 96 97 However, you do not always have complete control over all mutex guards on the stack. 98 If, in such a case, the listener notification is one-way, you can decide to do it 99 asynchronously. 100 101 The ->AsyncEventNotifier helps you to process such events asynchronously. Every 102 event is tied to an ->IEventProcessor which is responsible for processing it. 103 104 The AsyncEventNotifier is implemented as a thread itself, which sleeps as long as there are no 105 events in the queue. As soon as you add an event, the thread is woken up, processes the event, 106 and sleeps again. 107 */ 108 class COMPHELPER_DLLPUBLIC AsyncEventNotifier :protected AsyncEventNotifier_TBASE 109 ,public ::rtl::IReference 110 { 111 friend struct EventNotifierImpl; 112 113 private: 114 ::std::auto_ptr< EventNotifierImpl > m_pImpl; 115 116 protected: 117 // Thread 118 virtual void SAL_CALL run(); 119 virtual void SAL_CALL onTerminated(); 120 121 public: 122 /** constructs a notifier thread 123 */ 124 AsyncEventNotifier(); 125 126 // IReference implementations 127 virtual oslInterlockedCount SAL_CALL acquire(); 128 virtual oslInterlockedCount SAL_CALL release(); 129 130 using AsyncEventNotifier_TBASE::create; 131 using AsyncEventNotifier_TBASE::join; 132 using AsyncEventNotifier_TBASE::getIdentifier; 133 134 using AsyncEventNotifier_TBASE::operator new; 135 using AsyncEventNotifier_TBASE::operator delete; 136 137 /** terminates the thread 138 139 Note that this is a cooporative termination - if you call this from a thread different 140 from the notification thread itself, then it will block until the notification thread 141 finished processing the current event. If you call it from the notification thread 142 itself, it will return immediately, and the thread will be terminated as soon as 143 the current notification is finished. 144 */ 145 virtual void SAL_CALL terminate(); 146 147 /** adds an event to the queue, together with the instance which is responsible for 148 processing it 149 150 @param _rEvent 151 the event to add to the queue 152 @param _xProcessor 153 the processor for the event.<br/> 154 Beware of life time issues here. If your event processor dies or becomes otherwise 155 nonfunctional, you are responsible for removing all respective events from the queue. 156 You can do this by calling ->removeEventsForProcessor 157 */ 158 void addEvent( const AnyEventRef& _rEvent, const ::rtl::Reference< IEventProcessor >& _xProcessor ); 159 160 /** removes all events for the given event processor from the queue 161 */ 162 void removeEventsForProcessor( const ::rtl::Reference< IEventProcessor >& _xProcessor ); 163 164 protected: 165 virtual ~AsyncEventNotifier(); 166 }; 167 168 //==================================================================== 169 //= EventHolder 170 //==================================================================== 171 /** AnyEvent derivee holding an foreign event instance 172 */ 173 template < typename EVENT_OBJECT > 174 class EventHolder : public AnyEvent 175 { 176 public: 177 typedef EVENT_OBJECT EventObjectType; 178 179 private: 180 EventObjectType m_aEvent; 181 182 public: EventHolder(const EventObjectType & _rEvent)183 inline EventHolder( const EventObjectType& _rEvent ) 184 :m_aEvent( _rEvent ) 185 { 186 } 187 getEventObject() const188 inline const EventObjectType& getEventObject() const { return m_aEvent; } 189 }; 190 191 //........................................................................ 192 } // namespace comphelper 193 //........................................................................ 194 195 #endif // COMPHELPER_ASYNCNOTIFICATION_HXX 196