QtReactor.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    QtReactor.h
00006  *
00007  *  QtReactor.h,v 4.18 2005/10/28 16:14:54 ossama Exp
00008  *
00009  *  @author Hamish Friedlander <ullexco@wave.co.nz>
00010  *  @author Balachandran Natarajan <bala@cs.wustl.edu>
00011  */
00012 //=============================================================================
00013 
00014 #ifndef ACE_QTREACTOR_H
00015 #define ACE_QTREACTOR_H
00016 
00017 #include /**/ "ace/pre.h"
00018 
00019 #include "ace/ACE_QtReactor_export.h"
00020 
00021 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00022 # pragma once
00023 #endif /* ACE_LACKS_PRAGMA_ONCE */
00024 
00025 #include "ace/Select_Reactor.h"
00026 #include "ace/Map_Manager.h"
00027 
00028 // QT toolkit specific includes.
00029 #include /**/ <qapplication.h>
00030 #include /**/ <qobject.h>
00031 #include /**/ <qsocketnotifier.h>
00032 #include /**/ <qtimer.h>
00033 
00034 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00035 
00036 /**
00037  * @class ACE_QtReactor
00038  *
00039  * @brief An object-oriented event demultiplexor and event handler
00040  * dispatcher that uses the Qt Library. This class declaration
00041  * also uses the extension facilities  provided by the Qt. So,
00042  * readers  of the class declaration should not be upset with
00043  * the appearence of the Keywords like Q_OBJECT, private slots
00044  * etc. They are specific to Qt which uses these as a call back
00045  * methods implementation mechanism.
00046  *
00047  * \note Marek Brudka <mbrudka@elka.pw.edu.pl>: ACE_QtReactor was
00048  * quickly bugfixed to meet ACE 5.4.2 (6.0.0?) deadline.
00049  * While it passes QtReactor_Test now, there is a great
00050  * room for improvements as the implementation is rather inefficient
00051  * and obfuscated
00052  * To be more specific:
00053  * - reset_timeout always creates and removes qtimer after each
00054  * timeout event! Obviously, for fast triggering timers this may
00055  * lead to excessive memory management.
00056  * - create/destroy_notifiers_for_handle may also be reworked to
00057  * establish more clean relations between handles and QSocketNotifiers.
00058  * - read/write_exception_event disable now SocketNotifier for a while
00059  * to clear pending events. The cost of this operation is high: two hash
00060  * acces in ACE and at least two next ones in Qt. This makes QtReator slow,
00061  * but how clear pending events another way ?
00062  * - there is qapplication() mutator, which sets new qapplication for
00063  * QtReactor. This mutator violates implicit assumption about the
00064  * relations between QTimer and QSocketNotifiers and QApplication for
00065  * this reactor, namely one may expect that after qapplication(), none
00066  * of QtReactor artifacts is bound to old qapplication. That's not true
00067  * now, as QTimer and QSocketNotifiers are not reparent to new
00068  * QApplication. As a result, the sequence:
00069  * QApplication *old_qapp = new QApplication(..);
00070  * QtReactor qreactor( old_qapp);
00071  * // .. register handlers, schedule_timers etc
00072  * QApplication *new_qapp = new QApplication(..);
00073  * qreactor.qpplication( new_qapp );
00074  * delete old_qapp;
00075  * almost always leads to problems and memory violation, because
00076  * QSocketNotifiers are released by old_qapp. Therefore QtReactor
00077  * should not be reparent now by setting new qapplication.
00078  * - the lifecycle of Qt objects in ACE contects is rather mysterious
00079  * and should be made more explicit.
00080  * - valgrind reports a small memory leak in QtReactor_Test, though as for now
00081  * it is not clear if the leak is introduced by  QtReactor, or rather incorrect
00082  * memory management in QtReactor_Test.
00083  */
00084 class ACE_QtReactor_Export ACE_QtReactor
00085   : public QObject,
00086     public ACE_Select_Reactor
00087 {
00088 
00089     Q_OBJECT
00090 
00091 public:
00092     /** \brief Constructor follows  @ACE_Select_Reactor
00093         \param QApplication *qapp, qapplication which runs events loop
00094     */
00095     ACE_QtReactor (QApplication *qapp = 0,
00096         ACE_Sig_Handler * = 0,
00097         ACE_Timer_Queue * = 0,
00098         int disable_notify_pipe = 0,
00099         ACE_Reactor_Notify *notify = 0,
00100         int mask_signals = 1,
00101         int s_queue = ACE_SELECT_TOKEN::FIFO);
00102 
00103     /** \brief Constructor follows @ACE_Select_Reactor
00104         \param QApplication *qapp, qapplication which runs events loop
00105     */
00106     ACE_QtReactor (size_t size,
00107         QApplication *qapp = 0,
00108         int restart = 0,
00109         ACE_Sig_Handler * = 0,
00110         ACE_Timer_Queue * = 0,
00111         int disable_notify_pipe = 0,
00112         ACE_Reactor_Notify *notify = 0,
00113         int mask_signals = 1,
00114         int s_queue = ACE_SELECT_TOKEN::FIFO);
00115 
00116     virtual ~ACE_QtReactor (void);
00117 
00118     void qapplication (QApplication *qapp);
00119 
00120     // = Timer operations.
00121     virtual long schedule_timer (ACE_Event_Handler *handler,
00122         const void *arg,
00123         const ACE_Time_Value &delay_time,
00124         const ACE_Time_Value &interval);
00125 
00126     virtual int  cancel_timer (ACE_Event_Handler *handler,
00127         int dont_call_handle_close = 1);
00128 
00129     virtual int  cancel_timer (long timer_id,
00130         const void **arg = 0,
00131         int dont_call_handle_close = 1);
00132 
00133 protected:
00134 
00135     // = Register timers/handles with Qt
00136 
00137     /// Register a single <handler>.
00138     virtual int register_handler_i (ACE_HANDLE handle,
00139         ACE_Event_Handler *handler,
00140         ACE_Reactor_Mask mask);
00141 
00142     /// Register a set of <handlers> with Qt.
00143     virtual int register_handler_i (const ACE_Handle_Set &handles,
00144         ACE_Event_Handler *handler,
00145         ACE_Reactor_Mask mask);
00146 
00147 
00148     /// Remove the <handler> associated with this <handle>.
00149     virtual int remove_handler_i (ACE_HANDLE handle,
00150         ACE_Reactor_Mask mask);
00151 
00152     /// Remove a set of <handles>.
00153     virtual int remove_handler_i (const ACE_Handle_Set &handles,
00154         ACE_Reactor_Mask mask);
00155 
00156     /// Wait for events to occur.
00157     virtual int wait_for_multiple_events (ACE_Select_Reactor_Handle_Set &handle_set,
00158         ACE_Time_Value *max_wait_time);
00159 
00160     virtual int QtWaitForMultipleEvents (int width,
00161         ACE_Select_Reactor_Handle_Set &wait_set,
00162         ACE_Time_Value *max_wait_time);
00163 
00164     virtual int bit_ops (ACE_HANDLE handle,
00165         ACE_Reactor_Mask mask,
00166         ACE_Select_Reactor_Handle_Set &handle_set,
00167         int ops);
00168 
00169     int set_enable_flag_by_mask (int flag_value, ACE_HANDLE handle, ACE_Reactor_Mask mask);
00170     void create_notifiers_for_handle (ACE_HANDLE handle);
00171     void destroy_notifiers_for_handle (ACE_HANDLE handle);
00172 
00173     // Wait for Qt events to occur
00174 
00175     /// Some Qt stuff that we need to have
00176     QApplication *qapp_ ;
00177 
00178     /// Typedef of a map.
00179     typedef ACE_Map_Manager<ACE_HANDLE, QSocketNotifier *, ACE_Null_Mutex> MAP;
00180 
00181     /// A notifier for a read
00182     MAP read_notifier_;
00183 
00184     /// A write notifier
00185     MAP write_notifier_;
00186 
00187     /// An exception notifier
00188     MAP exception_notifier_;
00189 
00190     /// The timer class that would provide timer-sgnals & single-shot timers
00191     QTimer *qtime_ ;
00192 
00193 private:
00194     /// This method ensures there's an Qt timeout for the first timeout
00195     /// in the Reactor's Timer_Queue.
00196     void reset_timeout (void);
00197     /// reopens notification pipe to create SocketNotifier for it
00198     void reopen_notification_pipe(void);
00199     /// Deny access since member-wise won't work...
00200     ACE_QtReactor (const ACE_QtReactor &);
00201     ACE_QtReactor &operator= (const ACE_QtReactor &);
00202 
00203 private slots:
00204 
00205     // These are all part of the communication mechanism adopted in Qt.
00206     /// Dispatch a Read Event
00207     void read_event (int FD);
00208 
00209     /// Dispatch a Write Event
00210     void write_event (int FD);
00211 
00212     /// Dispatch an exception event
00213     void exception_event (int FD);
00214 
00215     /// Dispach a timeout event
00216     void timeout_event (void);
00217 };
00218 
00219 ACE_END_VERSIONED_NAMESPACE_DECL
00220 
00221 #include /**/ "ace/post.h"
00222 #endif /* ACE_QTREACTOR_H */

Generated on Thu Nov 9 09:42:00 2006 for ACE by doxygen 1.3.6