FlReactor.cpp

Go to the documentation of this file.
00001 // FlReactor.cpp,v 4.16 2005/10/28 16:14:52 ossama Exp
00002 
00003 #include "ace/FlReactor.h"
00004 
00005 ACE_RCSID(ace, FlReactor, "FlReactor.cpp,v 4.16 2005/10/28 16:14:52 ossama Exp")
00006 
00007 #include /**/ <FL/Fl.h>
00008 
00009 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00010 
00011 ACE_ALLOC_HOOK_DEFINE (ACE_FlReactor)
00012 
00013 // Must be called with lock held
00014 ACE_FlReactor::ACE_FlReactor (size_t size,
00015                               int restart,
00016                               ACE_Sig_Handler *h)
00017   : ACE_Select_Reactor (size, restart, h)
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   // FlReactor 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 FlReactor register_handler_i().  This means
00025   // that the notify pipe is registered with the ACE_Select_Reactor
00026   // event handling code not the FlReactor 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 FlReactor.
00029 
00030 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00031   this->notify_handler_->close ();
00032   this->notify_handler_->open (this, 0);
00033 #endif /* ACE_MT_SAFE */
00034 }
00035 
00036 ACE_FlReactor::~ACE_FlReactor (void)
00037 {
00038 }
00039 
00040 // This is just the <wait_for_multiple_events> from ace/Reactor.cpp
00041 // but we use the Fl functions to wait for an event, not <select>
00042 
00043 int
00044 ACE_FlReactor::wait_for_multiple_events (ACE_Select_Reactor_Handle_Set &handle_set,
00045                                          ACE_Time_Value *max_wait_time)
00046 {
00047   ACE_TRACE ("ACE_FlReactor::wait_for_multiple_events");
00048   int nfound;
00049 
00050   do
00051     {
00052       max_wait_time = this->timer_queue_->calculate_timeout (max_wait_time);
00053 
00054       size_t width = this->handler_rep_.max_handlep1 ();
00055       handle_set.rd_mask_ = this->wait_set_.rd_mask_;
00056       handle_set.wr_mask_ = this->wait_set_.wr_mask_;
00057       handle_set.ex_mask_ = this->wait_set_.ex_mask_;
00058 
00059       // Check to make sure our handle's are all usable.
00060       ACE_Select_Reactor_Handle_Set temp_set = handle_set;
00061 
00062       ACE_Time_Value zero = ACE_Time_Value::zero;
00063       if (ACE_OS::select (width,
00064                           temp_set.rd_mask_,
00065                           temp_set.wr_mask_,
00066                           temp_set.ex_mask_,
00067                           &zero) == -1)
00068         return -1; // Bad file arguments...
00069 
00070       // Instead of waiting using <select>, just use the Fl mechanism
00071       // to wait for one or more events...
00072 
00073       // Wait for something to happen.
00074       double t = 0;
00075       if (max_wait_time != 0)
00076         t = max_wait_time->sec () + max_wait_time->usec () / 1000000.0F;
00077 
00078       while (t > 0) {
00079         t = Fl::wait (t);
00080       }
00081 
00082       // Reset the width, in case it changed during the upcalls.
00083       width = this->handler_rep_.max_handlep1 ();
00084 
00085       // Now actually read the result needed by the <Select_Reactor>
00086       // using <select>.
00087       zero = ACE_Time_Value::zero;
00088       nfound = ACE_OS::select (width,
00089                                handle_set.rd_mask_,
00090                                handle_set.wr_mask_,
00091                                handle_set.ex_mask_,
00092                                &zero);
00093 
00094     } while (nfound == -1 && this->handle_error () > 0);
00095 
00096   if (nfound > 0)
00097     {
00098 #if !defined (ACE_WIN32)
00099       handle_set.rd_mask_.sync (this->handler_rep_.max_handlep1 ());
00100       handle_set.wr_mask_.sync (this->handler_rep_.max_handlep1 ());
00101       handle_set.ex_mask_.sync (this->handler_rep_.max_handlep1 ());
00102 #endif /* ACE_WIN32 */
00103     }
00104   return nfound; // Timed out or input available
00105 }
00106 
00107 void
00108 ACE_FlReactor::fl_io_proc (int fd, void* reactor)
00109 {
00110   ACE_FlReactor *self = static_cast<ACE_FlReactor *> (reactor);
00111   ACE_HANDLE handle = (ACE_HANDLE)fd; //reinterpret_cast<ACE_HANDLE> (fd);
00112 
00113   // my copy isn't const.
00114   ACE_Time_Value zero = ACE_Time_Value::zero;
00115 
00116   ACE_Select_Reactor_Handle_Set wait_set;
00117 
00118   // Deal with one file event.
00119 
00120   // - read which kind of event
00121   if (self->wait_set_.rd_mask_.is_set (handle))
00122     wait_set.rd_mask_.set_bit (handle);
00123   if (self->wait_set_.wr_mask_.is_set (handle))
00124     wait_set.wr_mask_.set_bit (handle);
00125   if (self->wait_set_.ex_mask_.is_set (handle))
00126     wait_set.ex_mask_.set_bit (handle);
00127 
00128   int result = ACE_OS::select (fd + 1,
00129                                wait_set.rd_mask_,
00130                                wait_set.wr_mask_,
00131                                wait_set.ex_mask_, &zero);
00132 
00133   ACE_Select_Reactor_Handle_Set dispatch_set;
00134 
00135   // - Use only that one file event (removes events for other files).
00136   if (result > 0)
00137     {
00138       if (wait_set.rd_mask_.is_set (handle))
00139         dispatch_set.rd_mask_.set_bit (handle);
00140       if (wait_set.wr_mask_.is_set (handle))
00141         dispatch_set.wr_mask_.set_bit (handle);
00142       if (wait_set.ex_mask_.is_set (handle))
00143         dispatch_set.ex_mask_.set_bit (handle);
00144 
00145       self->dispatch (1, dispatch_set);
00146     }
00147 }
00148 
00149 void
00150 ACE_FlReactor::fl_timeout_proc (void* reactor)
00151 {
00152   ACE_FlReactor *self = static_cast<ACE_FlReactor *> (reactor);
00153 
00154   // Deal with any timer events
00155   ACE_Select_Reactor_Handle_Set handle_set;
00156   self->dispatch (0, handle_set);
00157   self->reset_timeout ();
00158 }
00159 
00160 
00161 int
00162 ACE_FlReactor::register_handler_i (ACE_HANDLE handle,
00163                                    ACE_Event_Handler *handler,
00164                                    ACE_Reactor_Mask mask)
00165 {
00166   ACE_TRACE ("ACE_FlReactor::register_handler_i");
00167 
00168   int result = ACE_Select_Reactor::register_handler_i (handle,
00169                                                        handler, mask);
00170   if (result == -1)
00171     return -1;
00172 
00173   int condition = 0;
00174 
00175   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK))
00176     ACE_SET_BITS (condition, FL_READ);
00177   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK))
00178     ACE_SET_BITS (condition, FL_WRITE);
00179   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK))
00180     ACE_SET_BITS (condition, FL_EXCEPT);
00181   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::ACCEPT_MASK))
00182     ACE_SET_BITS (condition, FL_READ);
00183   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::CONNECT_MASK))
00184     {
00185       ACE_SET_BITS (condition, FL_WRITE); // connected, you may write
00186       ACE_SET_BITS (condition, FL_READ);  // connected, you have data/err
00187     }
00188 
00189   if (condition != 0)
00190     {
00191       Fl::add_fd ((int)handle, // reinterpret_cast<int> (handle),
00192                   ACE_FlReactor::fl_io_proc,
00193                   this);
00194     }
00195   return 0;
00196 }
00197 
00198 int
00199 ACE_FlReactor::register_handler_i (const ACE_Handle_Set &handles,
00200                                    ACE_Event_Handler *handler,
00201                                    ACE_Reactor_Mask mask)
00202 {
00203   return ACE_Select_Reactor::register_handler_i (handles,
00204                                                  handler,
00205                                                  mask);
00206 }
00207 
00208 int
00209 ACE_FlReactor::remove_handler_i (ACE_HANDLE handle,
00210                                  ACE_Reactor_Mask mask)
00211 {
00212   ACE_TRACE ("ACE_FlReactor::remove_handler_i");
00213 
00214   // In the registration phase we registered first with
00215   // ACE_Select_Reactor and then with X.  Now we are now doing things
00216   // in reverse order.
00217 
00218   // First clean up the corresponding X11Input.
00219   Fl::remove_fd ((int)handle); // reinterpret_cast<int> (handle);
00220 
00221   // Now let the reactor do its work.
00222   return ACE_Select_Reactor::remove_handler_i (handle,
00223                                                mask);
00224 }
00225 
00226 int
00227 ACE_FlReactor::remove_handler_i (const ACE_Handle_Set &handles,
00228                                  ACE_Reactor_Mask mask)
00229 {
00230   return ACE_Select_Reactor::remove_handler_i (handles,
00231                                                mask);
00232 }
00233 
00234 // The following function ensures there's an Fl timeout for the first
00235 // timeout in the Reactor's Timer_Queue.
00236 
00237 void
00238 ACE_FlReactor::reset_timeout (void)
00239 {
00240   ACE_Time_Value *max_wait_time =
00241     this->timer_queue_->calculate_timeout (0);
00242 
00243   if (max_wait_time != 0)
00244     {
00245       float t = max_wait_time->sec ()
00246         + max_wait_time->usec () / 1000000.0F;
00247       Fl::add_timeout (t,
00248                        ACE_FlReactor::fl_timeout_proc,
00249                        this);
00250     }
00251 }
00252 
00253 int
00254 ACE_FlReactor::reset_timer_interval
00255   (long timer_id,
00256    const ACE_Time_Value &interval)
00257 {
00258   ACE_TRACE ("ACE_FlReactor::reset_timer_interval");
00259   ACE_MT (ACE_GUARD_RETURN (ACE_Select_Reactor_Token, ace_mon, this->token_, -1));
00260 
00261   int result =
00262     ACE_Select_Reactor::reset_timer_interval (timer_id,
00263                                               interval);
00264 
00265   if (result == -1)
00266     return -1;
00267   else
00268     {
00269       this->reset_timeout ();
00270       return result;
00271     }
00272 }
00273 
00274 long
00275 ACE_FlReactor::schedule_timer (ACE_Event_Handler *event_handler,
00276                                const void *arg,
00277                 const ACE_Time_Value &delay,
00278                                const ACE_Time_Value &interval)
00279 {
00280   ACE_TRACE ("ACE_FlReactor::schedule_timer");
00281   ACE_MT (ACE_GUARD_RETURN (ACE_Select_Reactor_Token, ace_mon, this->token_, -1));
00282 
00283   long result = ACE_Select_Reactor::schedule_timer (event_handler,
00284                                                     arg,
00285                                                     delay,
00286                                                     interval);
00287   if (result == -1)
00288     return -1;
00289   else
00290     {
00291       this->reset_timeout ();
00292       return result;
00293     }
00294 }
00295 
00296 int
00297 ACE_FlReactor::cancel_timer (ACE_Event_Handler *handler,
00298                              int dont_call_handle_close)
00299 {
00300   ACE_TRACE ("ACE_FlReactor::cancel_timer");
00301 
00302   if (ACE_Select_Reactor::cancel_timer (handler,
00303                                         dont_call_handle_close) == -1)
00304     return -1;
00305   else
00306     {
00307       this->reset_timeout ();
00308       return 0;
00309     }
00310 }
00311 
00312 int
00313 ACE_FlReactor::cancel_timer (long timer_id,
00314                              const void **arg,
00315                              int dont_call_handle_close)
00316 {
00317   ACE_TRACE ("ACE_FlReactor::cancel_timer");
00318 
00319   if (ACE_Select_Reactor::cancel_timer (timer_id,
00320                                         arg,
00321                                         dont_call_handle_close) == -1)
00322     return -1;
00323   else
00324     {
00325       this->reset_timeout ();
00326       return 0;
00327     }
00328 }
00329 
00330 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:41:51 2006 for ACE by doxygen 1.3.6