Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

QtReactor.cpp

Go to the documentation of this file.
00001 #include "ace_pch.h"
00002 //$Id: QtReactor.cpp,v 1.1.1.3.2.1 2003/03/13 19:44:22 chad Exp $
00003 #include "ace/QtReactor.h"
00004 
00005 #if defined (ACE_HAS_QT)
00006 
00007 ACE_ALLOC_HOOK_DEFINE (ACE_QtReactor)
00008 
00009 // Must be called with lock held
00010 ACE_QtReactor::ACE_QtReactor (QApplication *qapp,
00011                               size_t size,
00012                               int restart,
00013                               ACE_Sig_Handler *handler)
00014   : ACE_Select_Reactor(size, restart, handler),
00015     qapp_(qapp),
00016     qtime_ (0)
00017 
00018 {
00019   // When the ACE_Select_Reactor is constructed it creates the notify
00020   // pipe and registers it with the register_handler_i() method. The
00021   // QtReactor overloads this method BUT because the
00022   // register_handler_i occurs when constructing the base class
00023   // ACE_Select_Reactor, the ACE_Select_Reactor register_handler_i()
00024   // is called not the QtReactor register_handler_i().  This means
00025   // that the notify pipe is registered with the ACE_Select_Reactor
00026   // event handling code not the QtReactor and so notfications don't
00027   // work.  To get around this we simply close and re-opened the
00028   // notification handler in the constructor of the QtReactor.
00029 
00030 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00031   this->notify_handler_->close ();
00032 
00033   // Patch for MS Windows: close and open doesn't clear the read
00034   // fd_set, so reset it manually
00035   this->wait_set_.rd_mask_.reset ();
00036 
00037   this->notify_handler_->open (this, 0);
00038 #endif /* ACE_MT_SAFE */
00039 }
00040 
00041 ACE_QtReactor::~ACE_QtReactor (void)
00042 {
00043   //no-op
00044 }
00045 
00046 void
00047 ACE_QtReactor::qapplication (QApplication *qapp)
00048 {
00049   qapp_ = qapp ;
00050 }
00051 
00052 int
00053 ACE_QtReactor::wait_for_multiple_events (ACE_Select_Reactor_Handle_Set &handle_set,
00054                                          ACE_Time_Value *max_wait_time)
00055 {
00056   ACE_TRACE( "ACE_QtReactor::wait_for_multiple_events" );
00057 
00058   int nfound = 0;
00059   do
00060   {
00061     max_wait_time = this->timer_queue_->calculate_timeout (max_wait_time);
00062     size_t width = this->handler_rep_.max_handlep1 ();
00063     handle_set.rd_mask_ = this->wait_set_.rd_mask_;
00064     handle_set.wr_mask_ = this->wait_set_.wr_mask_;
00065     handle_set.ex_mask_ = this->wait_set_.ex_mask_;
00066 
00067     nfound = QtWaitForMultipleEvents (width,
00068                                       handle_set,
00069                                       max_wait_time);
00070 
00071   } while( nfound == -1 && this->handle_error () > 0 );
00072 
00073   if (nfound > 0)
00074   {
00075 #if !defined (ACE_WIN32)
00076     handle_set.rd_mask_.sync (this->handler_rep_.max_handlep1 ());
00077     handle_set.wr_mask_.sync (this->handler_rep_.max_handlep1 ());
00078     handle_set.ex_mask_.sync (this->handler_rep_.max_handlep1 ());
00079 #endif /* ACE_WIN32 */
00080   }
00081 
00082   return nfound;
00083   // Timed out or input available
00084 }
00085 
00086 void
00087 ACE_QtReactor::timeout_event (void)
00088 {
00089   // Deal with any timer events
00090   ACE_Select_Reactor_Handle_Set handle_set;
00091   this->dispatch (0, handle_set );
00092 
00093   // Set next timeout signal
00094   this->reset_timeout ();
00095 }
00096 
00097 void
00098 ACE_QtReactor::read_event (int handle)
00099 {
00100   // Send read event
00101   ACE_Select_Reactor_Handle_Set dispatch_set;
00102 
00103   dispatch_set.rd_mask_.set_bit (ACE_HANDLE(handle));
00104   this->dispatch (1, dispatch_set);
00105 }
00106 
00107 void
00108 ACE_QtReactor::write_event (int handle)
00109 {
00110   // Send write event
00111   ACE_Select_Reactor_Handle_Set dispatch_set;
00112 
00113   dispatch_set.wr_mask_.set_bit (ACE_HANDLE(handle));
00114   this->dispatch (1, dispatch_set);
00115 }
00116 
00117 void
00118 ACE_QtReactor::exception_event (int handle)
00119 {
00120   // Send exception event
00121   ACE_Select_Reactor_Handle_Set dispatch_set;
00122 
00123   dispatch_set.ex_mask_.set_bit(ACE_HANDLE(handle));
00124   dispatch (1, dispatch_set);
00125 }
00126 
00127 int
00128 ACE_QtReactor::QtWaitForMultipleEvents (int width,
00129                                         ACE_Select_Reactor_Handle_Set &wait_set,
00130                                         ACE_Time_Value */*max_wait_time*/)
00131 {
00132   // Check to make sure our handle's are all usable.
00133   ACE_Select_Reactor_Handle_Set temp_set = wait_set;
00134 
00135   if (ACE_OS::select (width,
00136                       temp_set.rd_mask_,
00137                       temp_set.wr_mask_,
00138                       temp_set.ex_mask_,
00139                       (ACE_Time_Value *) &ACE_Time_Value::zero ) == -1)
00140     return -1; // Bad file arguments...
00141 
00142   // Qt processing.
00143   this->qapp_->processOneEvent () ;
00144 
00145   // Reset the width, in case it changed during the upcalls.
00146   width = handler_rep_.max_handlep1 ();
00147 
00148   // Now actually read the result needed by the <Select_Reactor> using
00149   // <select>.
00150   return ACE_OS::select(width,
00151                         wait_set.rd_mask_,
00152                         wait_set.wr_mask_,
00153                         wait_set.ex_mask_,
00154                         (ACE_Time_Value *) &ACE_Time_Value::zero);
00155 }
00156 
00157 int
00158 ACE_QtReactor::register_handler_i (ACE_HANDLE handle ,
00159                                    ACE_Event_Handler *handler,
00160                                    ACE_Reactor_Mask mask)
00161 {
00162   ACE_TRACE ("ACE_QtReactor::register_handler_i");
00163 
00164   int result;
00165   if ((result = ACE_Select_Reactor::register_handler_i(handle,
00166                                                        handler,
00167                                                        mask ))
00168       == -1)
00169     return -1;
00170 
00171   if (ACE_BIT_ENABLED(mask, ACE_Event_Handler::READ_MASK) ||
00172       ACE_BIT_ENABLED( mask, ACE_Event_Handler::ACCEPT_MASK))
00173     {
00174       // We check for any unused handles.
00175       MAP::ITERATOR read_iter = this->read_notifier_.end ();
00176       QSocketNotifier *qsock_read_notifier = 0;
00177 
00178       // We check whether we have a data against the present
00179       // handle. If so we need to unbind the data.
00180       if ((this->read_notifier_.find (handle,
00181                                       qsock_read_notifier) != -1))
00182         {
00183           if (qsock_read_notifier != (*read_iter).int_id_)
00184             {
00185               this->read_notifier_.unbind (handle,
00186                                            qsock_read_notifier);
00187               delete qsock_read_notifier;
00188             }
00189         }
00190 
00191       ACE_NEW_RETURN (qsock_read_notifier,
00192                       QSocketNotifier (int(handle), QSocketNotifier::Read),
00193                       -1);
00194 
00195       this->read_notifier_.bind (handle,
00196                                   qsock_read_notifier);
00197 
00198       QObject::connect (qsock_read_notifier,
00199                         SIGNAL (activated (int)),
00200                         this,
00201                         SLOT (read_event (int))) ;
00202     }
00203 
00204   if (ACE_BIT_ENABLED( mask, ACE_Event_Handler::WRITE_MASK) ||
00205       ACE_BIT_ENABLED( mask, ACE_Event_Handler::ACCEPT_MASK) ||
00206       ACE_BIT_ENABLED( mask, ACE_Event_Handler::CONNECT_MASK))
00207     {
00208       // We check for any unused handles.
00209       MAP::ITERATOR write_iter = this->write_notifier_.end ();
00210       QSocketNotifier *qsock_write_notifier = 0;
00211 
00212       // We check whether we have a data against the present
00213       // handle. If so we need to unbind the data.
00214       if ((this->write_notifier_.find (handle,
00215                                        qsock_write_notifier) != -1))
00216         {
00217           if (qsock_write_notifier != (*write_iter).int_id_)
00218             {
00219               this->write_notifier_.unbind (handle,
00220                                             qsock_write_notifier);
00221               delete qsock_write_notifier;
00222             }
00223         }
00224 
00225       ACE_NEW_RETURN (qsock_write_notifier,
00226                       QSocketNotifier (int(handle), QSocketNotifier::Write),
00227                       -1);
00228 
00229       this->write_notifier_.bind (handle,
00230                                    qsock_write_notifier);
00231 
00232       QObject::connect (qsock_write_notifier,
00233                         SIGNAL (activated (int)),
00234                         this,
00235                         SLOT (write_event (int)));
00236   }
00237 
00238   if (ACE_BIT_ENABLED( mask,
00239                        ACE_Event_Handler::EXCEPT_MASK))
00240   {
00241     // We check for any unused handles.
00242     MAP::ITERATOR excpt_iter = this->exception_notifier_.end ();
00243     QSocketNotifier *qsock_excpt_notifier = 0;
00244 
00245       // We check whether we have a data against the present
00246       // handle. If so we need to unbind the data.
00247       if ((this->exception_notifier_.find (handle,
00248                                            qsock_excpt_notifier) != -1))
00249         {
00250           if (qsock_excpt_notifier != (*excpt_iter).int_id_)
00251             {
00252               this->exception_notifier_.unbind (handle,
00253                                                 qsock_excpt_notifier);
00254               delete qsock_excpt_notifier;
00255             }
00256         }
00257 
00258       ACE_NEW_RETURN (qsock_excpt_notifier,
00259                       QSocketNotifier (int(handle), QSocketNotifier::Exception),
00260                       -1);
00261 
00262       this->exception_notifier_.bind (handle,
00263                                        qsock_excpt_notifier);
00264 
00265       QObject::connect (qsock_excpt_notifier,
00266                         SIGNAL (activated (int)),
00267                         this,
00268                         SLOT (exception_event (int))) ;
00269   }
00270 
00271   return 0;
00272 }
00273 
00274 int
00275 ACE_QtReactor::register_handler_i (const ACE_Handle_Set &handles,
00276                                    ACE_Event_Handler *handler,
00277                                    ACE_Reactor_Mask mask)
00278 {
00279   return ACE_Select_Reactor::register_handler_i(handles,
00280                                                 handler,
00281                                                 mask);
00282 }
00283 
00284 int ACE_QtReactor::remove_handler_i (ACE_HANDLE handle ,
00285                                      ACE_Reactor_Mask mask   )
00286 {
00287   ACE_TRACE ("ACE_QtReactor::remove_handler_i");
00288 
00289   QSocketNotifier *qsock_notifier = 0;
00290 
00291   // Looks for the handle in the maps and removes them.
00292   MAP::ITERATOR iter = this->read_notifier_.end ();
00293 
00294   if ((this->read_notifier_.find (handle,
00295                                   qsock_notifier) != -1))
00296     {
00297       this->read_notifier_.unbind (handle,
00298                                    qsock_notifier);
00299       delete qsock_notifier;
00300     }
00301 
00302   iter = this->write_notifier_.end ();
00303   if ((this->write_notifier_.find (handle,
00304                                    qsock_notifier) != -1))
00305     {
00306       this->write_notifier_.unbind (handle,
00307                                     qsock_notifier);
00308       delete qsock_notifier;
00309     }
00310 
00311   iter = this->exception_notifier_.end ();
00312   if ((this->exception_notifier_.find (handle,
00313                                        qsock_notifier) != -1))
00314     {
00315       this->exception_notifier_.unbind (handle,
00316                                         qsock_notifier);
00317       delete qsock_notifier;
00318     }
00319 
00320   // Now let the reactor do its work.
00321   return ACE_Select_Reactor::remove_handler_i (handle, mask);
00322 }
00323 
00324 
00325 int
00326 ACE_QtReactor::remove_handler_i (const ACE_Handle_Set &handles,
00327                                  ACE_Reactor_Mask  mask)
00328 {
00329   return ACE_Select_Reactor::remove_handler_i (handles,
00330                                                mask);
00331 }
00332 
00333 // The following functions ensure that there is an Qt timeout for the
00334 // first timeout in the Reactor's Timer_Queue.
00335 
00336 void
00337 ACE_QtReactor::reset_timeout (void)
00338 {
00339   if (this->qtime_ != 0)
00340     {
00341       delete this->qtime_;
00342       this->qtime_ = 0;
00343     }
00344 
00345   ACE_Time_Value *max_wait_time =
00346     this->timer_queue_->calculate_timeout (0) ;
00347 
00348   if (max_wait_time)
00349   {
00350     ACE_NEW (this->qtime_,
00351              QTimer);
00352 
00353     QObject::connect (qtime_,
00354                       SIGNAL (timeout ()),
00355                       this,
00356                       SLOT (timeout_event ()));
00357 
00358     qtime_->start(max_wait_time->msec(), 1);
00359   }
00360 
00361 }
00362 
00363 
00364 long
00365 ACE_QtReactor::schedule_timer (ACE_Event_Handler *event_handler,
00366                                const void *arg,
00367                                const ACE_Time_Value &delay,
00368                                const ACE_Time_Value &interval)
00369 {
00370   ACE_TRACE ("ACE_QtReactor::schedule_timer");
00371   ACE_MT (ACE_GUARD_RETURN (ACE_Select_Reactor_Token,
00372                             ace_mon,
00373                             this->token_,
00374                             -1));
00375 
00376   long result;
00377   if ((result = ACE_Select_Reactor::schedule_timer(event_handler,
00378                                                    arg,
00379                                                    delay,
00380                                                    interval)) == -1 )
00381     return -1;
00382   else
00383   {
00384     this->reset_timeout ();
00385     return result;
00386   }
00387 }
00388 
00389 int
00390 ACE_QtReactor::cancel_timer (ACE_Event_Handler *handler,
00391                              int dont_call_handle_close)
00392 {
00393   ACE_TRACE ("ACE_QtReactor::cancel_timer");
00394 
00395   if (ACE_Select_Reactor::cancel_timer (handler,
00396                                         dont_call_handle_close ) == -1 )
00397     return -1 ;
00398   else
00399   {
00400     this->reset_timeout( ) ;
00401     return 0 ;
00402   }
00403 }
00404 
00405 int ACE_QtReactor::cancel_timer (long  timer_id,
00406                                  const void **arg,
00407                                  int dont_call_handle_close )
00408 {
00409   ACE_TRACE( "ACE_QtReactor::cancel_timer" ) ;
00410 
00411   if (ACE_Select_Reactor::cancel_timer (timer_id,
00412                                         arg,
00413                                         dont_call_handle_close ) == -1 )
00414     return -1 ;
00415   else
00416   {
00417     this->reset_timeout( ) ;
00418     return 0 ;
00419   }
00420 }
00421 
00422 
00423 #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
00424 template class ACE_Map_Entry<ACE_HANDLE, QSocketNotifier *>;
00425 template class ACE_Map_Manager<ACE_HANDLE, QSocketNotifier *, ACE_Null_Mutex>;
00426 template class ACE_Map_Iterator_Base<ACE_HANDLE, QSocketNotifier *, ACE_Null_Mutex>;
00427 template class ACE_Map_Iterator<ACE_HANDLE, QSocketNotifier *, ACE_Null_Mutex>;
00428 template class ACE_Map_Reverse_Iterator<ACE_HANDLE, QSocketNotifier *, ACE_Null_Mutex>;
00429 #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
00430 #pragma instantiate ACE_Map_Entry<ACE_HANDLE, QSocketNotifier *>
00431 #pragma instantiate ACE_Map_Manager<ACE_HANDLE, QSocketNotifier *, ACE_Null_Mutex>
00432 #pragma instantiate ACE_Map_Iterator_Base<ACE_HANDLE, QSocketNotifier *, ACE_Null_Mutex>
00433 #pragma instantiate ACE_Map_Iterator<ACE_HANDLE, QSocketNotifier *, ACE_Null_Mutex>
00434 #pragma instantiate ACE_Map_Reverse_Iterator<ACE_HANDLE, QSocketNotifier *, ACE_Null_Mutex>
00435 #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
00436 #endif /*ACE_HAS_QT */

Generated on Mon Jun 16 11:20:57 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002