Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / QtReactor / QtReactor.h
blob25fed71affb135c757da16190fd70c47826c182e
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file QtReactor.h
7 * @author Hamish Friedlander <ullexco@wave.co.nz>
8 * @author Balachandran Natarajan <bala@cs.wustl.edu>
9 */
10 //=============================================================================
12 #ifndef ACE_QTREACTOR_H
13 #define ACE_QTREACTOR_H
15 #include /**/ "ace/pre.h"
17 #include "ace/QtReactor/ACE_QtReactor_export.h"
19 #if !defined (ACE_LACKS_PRAGMA_ONCE)
20 # pragma once
21 #endif /* ACE_LACKS_PRAGMA_ONCE */
23 #include "ace/Select_Reactor.h"
24 #include "ace/Map_Manager.h"
26 #if defined (ACE_HAS_QT4)
27 # include "QtCore/qglobal.h"
28 #endif
30 // QT toolkit specific includes.
31 #ifdef ACE_HAS_QT5
32 #include /**/ <QtWidgets/QApplication>
33 #define ACE_QT_HANDLE_TYPE qintptr
34 #else
35 #include /**/ <QtGui/QApplication>
36 #define ACE_QT_HANDLE_TYPE int
37 #endif
38 #include /**/ <QtCore/QObject>
39 #include /**/ <QtCore/QSocketNotifier>
40 #include /**/ <QtCore/QTimer>
42 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
44 /**
45 * @class ACE_QtReactor
47 * @brief An object-oriented event demultiplexor and event handler
48 * dispatcher that uses the Qt Library. This class declaration
49 * also uses the extension facilities provided by the Qt. So,
50 * readers of the class declaration should not be upset with
51 * the appearance of the Keywords like Q_OBJECT, private slots
52 * etc. They are specific to Qt which uses these as a call back
53 * methods implementation mechanism.
55 * \note Marek Brudka <mbrudka@elka.pw.edu.pl>: ACE_QtReactor was
56 * quickly bugfixed to meet ACE 5.4.2 (6.0.0?) deadline.
57 * While it passes QtReactor_Test now, there is a great
58 * room for improvements as the implementation is rather inefficient
59 * and obfuscated
60 * To be more specific:
61 * - reset_timeout always creates and removes qtimer after each
62 * timeout event! Obviously, for fast triggering timers this may
63 * lead to excessive memory management.
64 * - create/destroy_notifiers_for_handle may also be reworked to
65 * establish more clean relations between handles and QSocketNotifiers.
66 * - read/write_exception_event disable now SocketNotifier for a while
67 * to clear pending events. The cost of this operation is high: two hash
68 * acces in ACE and at least two next ones in Qt. This makes QtReator slow,
69 * but how clear pending events another way ?
70 * - there is qapplication() mutator, which sets new qapplication for
71 * QtReactor. This mutator violates implicit assumption about the
72 * relations between QTimer and QSocketNotifiers and QApplication for
73 * this reactor, namely one may expect that after qapplication(), none
74 * of QtReactor artifacts is bound to old qapplication. That's not true
75 * now, as QTimer and QSocketNotifiers are not reparent to new
76 * QApplication. As a result, the sequence:
77 * QApplication *old_qapp = new QApplication(..);
78 * QtReactor qreactor( old_qapp);
79 * // .. register handlers, schedule_timers etc
80 * QApplication *new_qapp = new QApplication(..);
81 * qreactor.qpplication( new_qapp );
82 * delete old_qapp;
83 * almost always leads to problems and memory violation, because
84 * QSocketNotifiers are released by old_qapp. Therefore QtReactor
85 * should not be reparent now by setting new qapplication.
86 * - the lifecycle of Qt objects in ACE contects is rather mysterious
87 * and should be made more explicit.
88 * - valgrind reports a small memory leak in QtReactor_Test, though as for now
89 * it is not clear if the leak is introduced by QtReactor, or rather incorrect
90 * memory management in QtReactor_Test.
92 class ACE_QtReactor_Export ACE_QtReactor
93 : public QObject,
94 public ACE_Select_Reactor
96 Q_OBJECT
98 public:
99 /** \brief Constructor follows @ACE_Select_Reactor
100 \param QApplication *qapp, qapplication which runs events loop
102 explicit ACE_QtReactor (QApplication *qapp = 0,
103 ACE_Sig_Handler * = 0,
104 ACE_Timer_Queue * = 0,
105 int disable_notify_pipe = 0,
106 ACE_Reactor_Notify *notify = 0,
107 bool mask_signals = true,
108 int s_queue = ACE_SELECT_TOKEN::FIFO);
110 /** \brief Constructor follows @ACE_Select_Reactor
111 \param QApplication *qapp, qapplication which runs events loop
113 explicit ACE_QtReactor (size_t size,
114 QApplication *qapp = 0,
115 bool restart = false,
116 ACE_Sig_Handler * = 0,
117 ACE_Timer_Queue * = 0,
118 int disable_notify_pipe = 0,
119 ACE_Reactor_Notify *notify = 0,
120 bool mask_signals = true,
121 int s_queue = ACE_SELECT_TOKEN::FIFO);
123 virtual ~ACE_QtReactor ();
125 void qapplication (QApplication *qapp);
127 // = Timer operations.
128 virtual long schedule_timer (ACE_Event_Handler *handler,
129 const void *arg,
130 const ACE_Time_Value &delay_time,
131 const ACE_Time_Value &interval);
133 virtual int cancel_timer (ACE_Event_Handler *handler,
134 int dont_call_handle_close = 1);
136 virtual int cancel_timer (long timer_id,
137 const void **arg = 0,
138 int dont_call_handle_close = 1);
140 protected:
141 /// Register a single @a handler.
142 virtual int register_handler_i (ACE_HANDLE handle,
143 ACE_Event_Handler *handler,
144 ACE_Reactor_Mask mask);
146 /// Register a set of <handlers> with Qt.
147 virtual int register_handler_i (const ACE_Handle_Set &handles,
148 ACE_Event_Handler *handler,
149 ACE_Reactor_Mask mask);
152 /// Remove the <handler> associated with this @a handle.
153 virtual int remove_handler_i (ACE_HANDLE handle,
154 ACE_Reactor_Mask mask);
156 /// Remove a set of <handles>.
157 virtual int remove_handler_i (const ACE_Handle_Set &handles,
158 ACE_Reactor_Mask mask);
160 /// Wait for events to occur.
161 virtual int wait_for_multiple_events (ACE_Select_Reactor_Handle_Set &handle_set,
162 ACE_Time_Value *max_wait_time);
164 virtual int QtWaitForMultipleEvents (int width,
165 ACE_Select_Reactor_Handle_Set &wait_set,
166 ACE_Time_Value *max_wait_time);
168 virtual int bit_ops (ACE_HANDLE handle,
169 ACE_Reactor_Mask mask,
170 ACE_Select_Reactor_Handle_Set &handle_set,
171 int ops);
173 int set_enable_flag_by_mask (int flag_value, ACE_HANDLE handle, ACE_Reactor_Mask mask);
174 void create_notifiers_for_handle (ACE_HANDLE handle);
175 void destroy_notifiers_for_handle (ACE_HANDLE handle);
177 // Wait for Qt events to occur
179 /// Some Qt stuff that we need to have
180 QApplication *qapp_ ;
182 /// Typedef of a map.
183 typedef ACE_Map_Manager<ACE_HANDLE, QSocketNotifier *, ACE_Null_Mutex> MAP;
185 /// A notifier for a read
186 MAP read_notifier_;
188 /// A write notifier
189 MAP write_notifier_;
191 /// An exception notifier
192 MAP exception_notifier_;
194 /// The timer class that would provide timer-signals & single-shot timers
195 QTimer *qtime_ ;
197 private:
198 /// This method ensures there's an Qt timeout for the first timeout
199 /// in the Reactor's Timer_Queue.
200 void reset_timeout ();
201 /// reopens notification pipe to create SocketNotifier for it
202 void reopen_notification_pipe();
204 #ifdef ACE_HAS_QT5
205 /// Recover the socket's ACE_HANDLE based on the sender of the Qt signal.
206 /// Must be called from a Qt slot method.
207 ACE_HANDLE handle_from_sender () const;
208 #endif
210 /// Deny access since member-wise won't work...
211 ACE_QtReactor (const ACE_QtReactor &);
212 ACE_QtReactor &operator= (const ACE_QtReactor &);
214 private slots:
215 // These are all part of the communication mechanism adopted in Qt.
216 /// Dispatch a Read Event
217 void read_event (ACE_QT_HANDLE_TYPE p_handle);
219 /// Dispatch a Write Event
220 void write_event (ACE_QT_HANDLE_TYPE p_handle);
222 /// Dispatch an exception event
223 void exception_event (ACE_QT_HANDLE_TYPE p_handle);
225 /// Dispatch a timeout event
226 void timeout_event ();
229 ACE_END_VERSIONED_NAMESPACE_DECL
231 #include /**/ "ace/post.h"
232 #endif /* ACE_QTREACTOR_H */