Proactor.cpp

Go to the documentation of this file.
00001 // $Id: Proactor.cpp 81535 2008-04-29 20:08:52Z shuston $
00002 
00003 #include "ace/config-lite.h"
00004 #include "ace/Proactor.h"
00005 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)
00006 
00007 // This only works on Win32 platforms and on Unix platforms with aio
00008 // calls.
00009 
00010 #include "ace/Auto_Ptr.h"
00011 #include "ace/Proactor_Impl.h"
00012 #include "ace/Object_Manager.h"
00013 #include "ace/Task_T.h"
00014 
00015 #if !defined (ACE_HAS_WINCE) && !defined (ACE_LACKS_ACE_SVCCONF)
00016 #    include "ace/Service_Config.h"
00017 #endif /* !ACE_HAS_WINCE && !ACE_LACKS_ACE_SVCCONF */
00018 
00019 
00020 ACE_RCSID (ace,
00021            Proactor,
00022            "$Id: Proactor.cpp 81535 2008-04-29 20:08:52Z shuston $")
00023 
00024 
00025 #include "ace/Task_T.h"
00026 #include "ace/Log_Msg.h"
00027 #include "ace/Framework_Component.h"
00028 
00029 #if defined (ACE_HAS_AIO_CALLS)
00030 #   include "ace/POSIX_Proactor.h"
00031 #   include "ace/POSIX_CB_Proactor.h"
00032 #else /* !ACE_HAS_AIO_CALLS */
00033 #   include "ace/WIN32_Proactor.h"
00034 #endif /* ACE_HAS_AIO_CALLS */
00035 
00036 #if !defined (__ACE_INLINE__)
00037 #include "ace/Proactor.inl"
00038 #endif /* __ACE_INLINE__ */
00039 
00040 #include "ace/Auto_Event.h"
00041 
00042 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00043 
00044 /// Process-wide ACE_Proactor.
00045 ACE_Proactor *ACE_Proactor::proactor_ = 0;
00046 
00047 /// Controls whether the Proactor is deleted when we shut down (we can
00048 /// only delete it safely if we created it!)
00049 bool ACE_Proactor::delete_proactor_ = false;
00050 
00051 /**
00052  * @class ACE_Proactor_Timer_Handler
00053  *
00054  * @brief A Handler for timer. It helps in the management of timers
00055  * registered with the Proactor.
00056  *
00057  * This object has a thread that will wait on the earliest time
00058  * in a list of timers and an event. When a timer expires, the
00059  * thread will post a completion event on the port and go back
00060  * to waiting on the timer queue and event. If the event is
00061  * signaled, the thread will refresh the time it is currently
00062  * waiting on (in case the earliest time has changed).
00063  */
00064 class ACE_Proactor_Timer_Handler : public ACE_Task<ACE_NULL_SYNCH>
00065 {
00066 
00067   /// Proactor has special privileges
00068   /// Access needed to: timer_event_
00069   friend class ACE_Proactor;
00070 
00071 public:
00072   /// Constructor.
00073   ACE_Proactor_Timer_Handler (ACE_Proactor &proactor);
00074 
00075   /// Destructor.
00076   virtual ~ACE_Proactor_Timer_Handler (void);
00077 
00078   /// Proactor calls this to shut down the timer handler
00079   /// gracefully. Just calling the destructor alone doesnt do what
00080   /// <destroy> does. <destroy> make sure the thread exits properly.
00081   int destroy (void);
00082 
00083 protected:
00084   /// Run by a daemon thread to handle deferred processing. In other
00085   /// words, this method will do the waiting on the earliest timer and
00086   /// event.
00087   virtual int svc (void);
00088 
00089   /// Event to wait on.
00090   ACE_Auto_Event timer_event_;
00091 
00092   /// Proactor.
00093   ACE_Proactor &proactor_;
00094 
00095   /// Flag used to indicate when we are shutting down.
00096   int shutting_down_;
00097 };
00098 
00099 ACE_Proactor_Timer_Handler::ACE_Proactor_Timer_Handler (ACE_Proactor &proactor)
00100   : ACE_Task <ACE_NULL_SYNCH> (&proactor.thr_mgr_),
00101     proactor_ (proactor),
00102     shutting_down_ (0)
00103 {
00104 }
00105 
00106 ACE_Proactor_Timer_Handler::~ACE_Proactor_Timer_Handler (void)
00107 {
00108   // Mark for closing down.
00109   this->shutting_down_ = 1;
00110 
00111   // Signal timer event.
00112   this->timer_event_.signal ();
00113 
00114   // Wait for the Timer Handler thread to exit.
00115   this->wait ();
00116 }
00117 
00118 int
00119 ACE_Proactor_Timer_Handler::svc (void)
00120 {
00121   ACE_Time_Value absolute_time;
00122   ACE_Time_Value relative_time;
00123   int result = 0;
00124 
00125   while (this->shutting_down_ == 0)
00126     {
00127       // Check whether the timer queue has any items in it.
00128       if (this->proactor_.timer_queue ()->is_empty () == 0)
00129         {
00130           // Get the earliest absolute time.
00131           absolute_time = this->proactor_.timer_queue ()->earliest_time ();
00132 
00133           // Get current time from timer queue since we don't know
00134           // which <gettimeofday> was used.
00135           ACE_Time_Value cur_time = this->proactor_.timer_queue ()->gettimeofday ();
00136 
00137           // Compare absolute time with curent time received from the
00138           // timer queue.
00139           if (absolute_time > cur_time)
00140             relative_time = absolute_time - cur_time;
00141           else
00142             relative_time = ACE_Time_Value::zero;
00143 
00144           // Block for relative time.
00145           result = this->timer_event_.wait (&relative_time, 0);
00146         }
00147       else
00148         // The timer queue has no entries, so wait indefinitely.
00149         result = this->timer_event_.wait ();
00150 
00151       // Check for timer expiries.
00152       if (result == -1)
00153         {
00154           switch (errno)
00155             {
00156             case ETIME:
00157               // timeout: expire timers
00158               this->proactor_.timer_queue ()->expire ();
00159               break;
00160             default:
00161               // Error.
00162               ACE_ERROR_RETURN ((LM_ERROR,
00163                                  ACE_TEXT ("%N:%l:(%P | %t):%p\n"),
00164                                  ACE_TEXT ("ACE_Proactor_Timer_Handler::svc:wait failed")),
00165                                 -1);
00166             }
00167         }
00168     }
00169   return 0;
00170 }
00171 
00172 // *********************************************************************
00173 
00174 ACE_Proactor_Handle_Timeout_Upcall::ACE_Proactor_Handle_Timeout_Upcall (void)
00175   : proactor_ (0)
00176 {
00177 }
00178 
00179 int
00180 ACE_Proactor_Handle_Timeout_Upcall::registration (TIMER_QUEUE &,
00181                                                   ACE_Handler *,
00182                                                   const void *)
00183 {
00184   return 0;
00185 }
00186 
00187 int
00188 ACE_Proactor_Handle_Timeout_Upcall::preinvoke (TIMER_QUEUE &,
00189                                                ACE_Handler *,
00190                                                const void *,
00191                                                int,
00192                                                const ACE_Time_Value &,
00193                                                const void *&)
00194 {
00195   return 0;
00196 }
00197 
00198 int
00199 ACE_Proactor_Handle_Timeout_Upcall::postinvoke (TIMER_QUEUE &,
00200                                                 ACE_Handler *,
00201                                                 const void *,
00202                                                 int,
00203                                                 const ACE_Time_Value &,
00204                                                 const void *)
00205 {
00206   return 0;
00207 }
00208 
00209 int
00210 ACE_Proactor_Handle_Timeout_Upcall::timeout (TIMER_QUEUE &,
00211                                              ACE_Handler *handler,
00212                                              const void *act,
00213                                              int,
00214                                              const ACE_Time_Value &time)
00215 {
00216   if (this->proactor_ == 0)
00217     ACE_ERROR_RETURN ((LM_ERROR,
00218                        ACE_TEXT ("(%t) No Proactor set in ACE_Proactor_Handle_Timeout_Upcall,")
00219                        ACE_TEXT (" no completion port to post timeout to?!@\n")),
00220                       -1);
00221 
00222   // Create the Asynch_Timer.
00223   ACE_Asynch_Result_Impl *asynch_timer =
00224     this->proactor_->create_asynch_timer (handler->proxy (),
00225                                           act,
00226                                           time,
00227                                           ACE_INVALID_HANDLE,
00228                                           0,
00229                                           -1);
00230 
00231   if (asynch_timer == 0)
00232     ACE_ERROR_RETURN ((LM_ERROR,
00233                        ACE_TEXT ("%N:%l:(%P | %t):%p\n"),
00234                        ACE_TEXT ("ACE_Proactor_Handle_Timeout_Upcall::timeout:")
00235                        ACE_TEXT ("create_asynch_timer failed")),
00236                       -1);
00237 
00238   auto_ptr<ACE_Asynch_Result_Impl> safe_asynch_timer (asynch_timer);
00239 
00240   // Post a completion.
00241   if (-1 == safe_asynch_timer->post_completion
00242       (this->proactor_->implementation ()))
00243     ACE_ERROR_RETURN ((LM_ERROR,
00244                        ACE_TEXT ("Failure in dealing with timers: ")
00245                        ACE_TEXT ("PostQueuedCompletionStatus failed\n")),
00246                       -1);
00247 
00248   // The completion has been posted.  The proactor is now responsible
00249   // for managing the asynch_timer memory.
00250   (void) safe_asynch_timer.release ();
00251 
00252   return 0;
00253 }
00254 
00255 int
00256 ACE_Proactor_Handle_Timeout_Upcall::cancel_type (TIMER_QUEUE &,
00257                                                  ACE_Handler *,
00258                                                  int,
00259                                                  int &)
00260 {
00261   // Do nothing
00262   return 0;
00263 }
00264 
00265 int
00266 ACE_Proactor_Handle_Timeout_Upcall::cancel_timer (TIMER_QUEUE &,
00267                                                   ACE_Handler *,
00268                                                   int,
00269                                                   int)
00270 {
00271   // Do nothing
00272   return 0;
00273 }
00274 
00275 int
00276 ACE_Proactor_Handle_Timeout_Upcall::deletion (TIMER_QUEUE &,
00277                                               ACE_Handler *,
00278                                               const void *)
00279 {
00280   // Do nothing
00281   return 0;
00282 }
00283 
00284 int
00285 ACE_Proactor_Handle_Timeout_Upcall::proactor (ACE_Proactor &proactor)
00286 {
00287   if (this->proactor_ == 0)
00288     {
00289       this->proactor_ = &proactor;
00290       return 0;
00291     }
00292   else
00293     ACE_ERROR_RETURN ((LM_ERROR,
00294                        ACE_TEXT ("ACE_Proactor_Handle_Timeout_Upcall is only suppose")
00295                        ACE_TEXT (" to be used with ONE (and only one) Proactor\n")),
00296                       -1);
00297 }
00298 
00299 // *********************************************************************
00300 
00301 ACE_Proactor::ACE_Proactor (ACE_Proactor_Impl *implementation,
00302                             bool delete_implementation,
00303                             TIMER_QUEUE *tq)
00304   : implementation_ (0),
00305     delete_implementation_ (delete_implementation),
00306     timer_handler_ (0),
00307     timer_queue_ (0),
00308     delete_timer_queue_ (0),
00309     end_event_loop_ (0),
00310     event_loop_thread_count_ (0)
00311 {
00312   this->implementation (implementation);
00313 
00314   if (this->implementation () == 0)
00315     {
00316 #if defined (ACE_HAS_AIO_CALLS)
00317       // POSIX Proactor.
00318 #  if defined (ACE_POSIX_AIOCB_PROACTOR)
00319       ACE_NEW (implementation, ACE_POSIX_AIOCB_Proactor);
00320 #  elif defined (ACE_POSIX_SIG_PROACTOR)
00321       ACE_NEW (implementation, ACE_POSIX_SIG_Proactor);
00322 #  else /* Default order: CB, SIG, AIOCB */
00323 #    if !defined(ACE_HAS_BROKEN_SIGEVENT_STRUCT)
00324       ACE_NEW (implementation, ACE_POSIX_CB_Proactor);
00325 #    else
00326 #      if defined(ACE_HAS_POSIX_REALTIME_SIGNALS)
00327       ACE_NEW (implementation, ACE_POSIX_SIG_Proactor);
00328 #      else
00329       ACE_NEW (implementation, ACE_POSIX_AIOCB_Proactor);
00330 #      endif /* ACE_HAS_POSIX_REALTIME_SIGNALS */
00331 #    endif /* !ACE_HAS_BROKEN_SIGEVENT_STRUCT */
00332 #  endif /* ACE_POSIX_AIOCB_PROACTOR */
00333 #elif (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE))
00334       // WIN_Proactor.
00335       ACE_NEW (implementation,
00336                ACE_WIN32_Proactor);
00337 #endif /* ACE_HAS_AIO_CALLS */
00338       this->implementation (implementation);
00339       this->delete_implementation_ = true;
00340     }
00341 
00342   // Set the timer queue.
00343   this->timer_queue (tq);
00344 
00345   // Create the timer handler
00346   ACE_NEW (this->timer_handler_,
00347            ACE_Proactor_Timer_Handler (*this));
00348 
00349   // Activate <timer_handler>.
00350   if (this->timer_handler_->activate () == -1)
00351     ACE_ERROR ((LM_ERROR,
00352                 ACE_TEXT ("%N:%l:(%P | %t):%p\n"),
00353                 ACE_TEXT ("Task::activate:could not create thread\n")));
00354 }
00355 
00356 ACE_Proactor::~ACE_Proactor (void)
00357 {
00358   this->close ();
00359 }
00360 
00361 ACE_Proactor *
00362 ACE_Proactor::instance (size_t /* threads */)
00363 {
00364   ACE_TRACE ("ACE_Proactor::instance");
00365 
00366   if (ACE_Proactor::proactor_ == 0)
00367     {
00368       // Perform Double-Checked Locking Optimization.
00369       ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00370                                 *ACE_Static_Object_Lock::instance (),
00371                                 0));
00372 
00373       if (ACE_Proactor::proactor_ == 0)
00374         {
00375           ACE_NEW_RETURN (ACE_Proactor::proactor_,
00376                           ACE_Proactor,
00377                           0);
00378 
00379           ACE_Proactor::delete_proactor_ = true;
00380           ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Proactor, ACE_Proactor::proactor_);
00381         }
00382     }
00383   return ACE_Proactor::proactor_;
00384 }
00385 
00386 ACE_Proactor *
00387 ACE_Proactor::instance (ACE_Proactor * r, bool delete_proactor)
00388 {
00389   ACE_TRACE ("ACE_Proactor::instance");
00390 
00391   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00392                             *ACE_Static_Object_Lock::instance (), 0));
00393 
00394   ACE_Proactor *t = ACE_Proactor::proactor_;
00395 
00396   ACE_Proactor::delete_proactor_ = delete_proactor;
00397   ACE_Proactor::proactor_ = r;
00398   ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Proactor, ACE_Proactor::proactor_);
00399 
00400   return t;
00401 }
00402 
00403 void
00404 ACE_Proactor::close_singleton (void)
00405 {
00406   ACE_TRACE ("ACE_Proactor::close_singleton");
00407 
00408   ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00409                      *ACE_Static_Object_Lock::instance ()));
00410 
00411   if (ACE_Proactor::delete_proactor_)
00412     {
00413       delete ACE_Proactor::proactor_;
00414       ACE_Proactor::proactor_ = 0;
00415       ACE_Proactor::delete_proactor_ = false;
00416     }
00417 }
00418 
00419 const ACE_TCHAR *
00420 ACE_Proactor::dll_name (void)
00421 {
00422   return ACE_TEXT ("ACE");
00423 }
00424 
00425 const ACE_TCHAR *
00426 ACE_Proactor::name (void)
00427 {
00428   return ACE_TEXT ("ACE_Proactor");
00429 }
00430 
00431 int
00432 ACE_Proactor::check_reconfiguration (ACE_Proactor *)
00433 {
00434 #if !defined (ACE_HAS_WINCE)  &&  !defined (ACE_LACKS_ACE_SVCCONF)
00435   if (ACE_Service_Config::reconfig_occurred ())
00436     {
00437       ACE_Service_Config::reconfigure ();
00438       return 1;
00439     }
00440 #endif /* ! ACE_HAS_WINCE || ! ACE_LACKS_ACE_SVCCONF */
00441   return 0;
00442 }
00443 
00444 int
00445 ACE_Proactor::proactor_run_event_loop (PROACTOR_EVENT_HOOK eh)
00446 {
00447   ACE_TRACE ("ACE_Proactor::proactor_run_event_loop");
00448   int result = 0;
00449 
00450   {
00451     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, mutex_, -1));
00452 
00453     // Early check. It is ok to do this without lock, since we care just
00454     // whether it is zero or non-zero.
00455     if (this->end_event_loop_ != 0)
00456       return 0;
00457 
00458     // First time you are in. Increment the thread count.
00459     this->event_loop_thread_count_ ++;
00460   }
00461 
00462   // Run the event loop.
00463   for (;;)
00464     {
00465       // Check the end loop flag. It is ok to do this without lock,
00466       // since we care just whether it is zero or non-zero.
00467       if (this->end_event_loop_ != 0)
00468         break;
00469 
00470       // <end_event_loop> is not set. Ready to do <handle_events>.
00471       result = this->handle_events ();
00472 
00473       if (eh != 0 && (*eh) (this))
00474         continue;
00475 
00476       if (result == -1)
00477         break;
00478     }
00479 
00480   // Leaving the event loop. Decrement the thread count.
00481 
00482   {
00483     // Obtain the lock in the MT environments.
00484     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, mutex_, -1));
00485 
00486     // Decrement the thread count.
00487     this->event_loop_thread_count_ --;
00488 
00489     if (this->event_loop_thread_count_ > 0
00490        && this->end_event_loop_ != 0)
00491        this->proactor_post_wakeup_completions (1);
00492   }
00493 
00494   return result;
00495 }
00496 
00497 // Handle events for -tv- time.  handle_events updates -tv- to reflect
00498 // time elapsed, so do not return until -tv- == 0, or an error occurs.
00499 int
00500 ACE_Proactor::proactor_run_event_loop (ACE_Time_Value &tv,
00501                                        PROACTOR_EVENT_HOOK eh)
00502 {
00503   ACE_TRACE ("ACE_Proactor::proactor_run_event_loop");
00504   int result = 0;
00505 
00506   {
00507     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, mutex_, -1));
00508 
00509     // Early check. It is ok to do this without lock, since we care just
00510     // whether it is zero or non-zero.
00511     if (this->end_event_loop_ != 0
00512        || tv == ACE_Time_Value::zero)
00513       return 0;
00514 
00515     // First time you are in. Increment the thread count.
00516     this->event_loop_thread_count_ ++;
00517   }
00518 
00519   // Run the event loop.
00520   for (;;)
00521     {
00522       // Check the end loop flag. It is ok to do this without lock,
00523       // since we care just whether it is zero or non-zero.
00524       if (this->end_event_loop_ != 0)
00525         break;
00526 
00527       // <end_event_loop> is not set. Ready to do <handle_events>.
00528       result = this->handle_events (tv);
00529 
00530       if (eh != 0 && (*eh) (this))
00531         continue;
00532 
00533       if (result == -1 || result == 0)
00534         break;
00535     }
00536 
00537   // Leaving the event loop. Decrement the thread count.
00538 
00539   {
00540     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, mutex_, -1));
00541 
00542     // Decrement the thread count.
00543     this->event_loop_thread_count_ --;
00544 
00545     if (this->event_loop_thread_count_ > 0
00546        && this->end_event_loop_ != 0)
00547        this->proactor_post_wakeup_completions (1);
00548   }
00549 
00550   return result;
00551 }
00552 
00553 int
00554 ACE_Proactor::proactor_reset_event_loop(void)
00555 {
00556   ACE_TRACE ("ACE_Proactor::proactor_reset_event_loop");
00557 
00558   // Obtain the lock in the MT environments.
00559   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, mutex_, -1));
00560 
00561   this->end_event_loop_ = 0;
00562   return 0;
00563 }
00564 
00565 int
00566 ACE_Proactor::proactor_end_event_loop (void)
00567 {
00568   ACE_TRACE ("ACE_Proactor::proactor_end_event_loop");
00569 
00570   int how_many = 0;
00571 
00572   {
00573     // Obtain the lock, set the end flag and post the wakeup
00574     // completions.
00575     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, mutex_, -1));
00576 
00577     // Set the end flag.
00578     this->end_event_loop_ = 1;
00579 
00580     // Number of completions to post.
00581     how_many = this->event_loop_thread_count_;
00582     if (how_many == 0)
00583       return 0;
00584   }
00585 
00586   // Post completions to all the threads so that they will all wake
00587   // up.
00588   return this->proactor_post_wakeup_completions (how_many);
00589 }
00590 
00591 int
00592 ACE_Proactor::proactor_event_loop_done (void)
00593 {
00594   ACE_TRACE ("ACE_Proactor::proactor_event_loop_done");
00595 
00596   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, mutex_, -1));
00597 
00598   return this->end_event_loop_ != 0 ? 1 : 0 ;
00599 }
00600 
00601 int
00602 ACE_Proactor::close (void)
00603 {
00604   // Close the implementation.
00605   if (this->implementation ()->close () == -1)
00606     ACE_ERROR ((LM_ERROR,
00607                 ACE_TEXT ("%N:%l:(%P | %t):%p\n"),
00608                 ACE_TEXT ("ACE_Proactor::close: implementation close")));
00609 
00610   // Delete the implementation.
00611   if (this->delete_implementation_)
00612     {
00613       delete this->implementation ();
00614       this->implementation_ = 0;
00615     }
00616 
00617   // Delete the timer handler.
00618   if (this->timer_handler_)
00619     {
00620       delete this->timer_handler_;
00621       this->timer_handler_ = 0;
00622     }
00623 
00624   // Delete the timer queue.
00625   if (this->delete_timer_queue_)
00626     {
00627       delete this->timer_queue_;
00628       this->timer_queue_ = 0;
00629       this->delete_timer_queue_ = 0;
00630     }
00631 
00632   return 0;
00633 }
00634 
00635 int
00636 ACE_Proactor::register_handle (ACE_HANDLE handle,
00637                                const void *completion_key)
00638 {
00639   return this->implementation ()->register_handle (handle,
00640                                                    completion_key);
00641 }
00642 
00643 long
00644 ACE_Proactor::schedule_timer (ACE_Handler &handler,
00645                               const void *act,
00646                               const ACE_Time_Value &time)
00647 {
00648   return this->schedule_timer (handler,
00649                                act,
00650                                time,
00651                                ACE_Time_Value::zero);
00652 }
00653 
00654 long
00655 ACE_Proactor::schedule_repeating_timer (ACE_Handler &handler,
00656                                         const void *act,
00657                                         const ACE_Time_Value &interval)
00658 {
00659   return this->schedule_timer (handler,
00660                                act,
00661                                interval,
00662                                interval);
00663 }
00664 
00665 long
00666 ACE_Proactor::schedule_timer (ACE_Handler &handler,
00667                               const void *act,
00668                               const ACE_Time_Value &time,
00669                               const ACE_Time_Value &interval)
00670 {
00671   // absolute time.
00672   ACE_Time_Value absolute_time =
00673     this->timer_queue_->gettimeofday () + time;
00674 
00675   // Only one guy goes in here at a time
00676   ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX,
00677                             ace_mon,
00678                             this->timer_queue_->mutex (),
00679                             -1));
00680 
00681   // Remember the old proactor.
00682   ACE_Proactor *old_proactor = handler.proactor ();
00683 
00684   // Assign *this* Proactor to the handler.
00685   handler.proactor (this);
00686 
00687   // Schedule the timer
00688   long result = this->timer_queue_->schedule (&handler,
00689                                               act,
00690                                               absolute_time,
00691                                               interval);
00692   if (result != -1)
00693     {
00694       // no failures: check to see if we are the earliest time
00695       if (this->timer_queue_->earliest_time () == absolute_time)
00696 
00697         // wake up the timer thread
00698         if (this->timer_handler_->timer_event_.signal () == -1)
00699           {
00700             // Cancel timer
00701             this->timer_queue_->cancel (result);
00702             result = -1;
00703           }
00704     }
00705 
00706   if (result == -1)
00707     {
00708       // Reset the old proactor in case of failures.
00709       handler.proactor (old_proactor);
00710     }
00711 
00712   return result;
00713 }
00714 
00715 int
00716 ACE_Proactor::cancel_timer (long timer_id,
00717                             const void **arg,
00718                             int dont_call_handle_close)
00719 {
00720   // No need to singal timer event here. Even if the cancel timer was
00721   // the earliest, we will have an extra wakeup.
00722   return this->timer_queue_->cancel (timer_id,
00723                                      arg,
00724                                      dont_call_handle_close);
00725 }
00726 
00727 int
00728 ACE_Proactor::cancel_timer (ACE_Handler &handler,
00729                                   int dont_call_handle_close)
00730 {
00731   // No need to signal timer event here. Even if the cancel timer was
00732   // the earliest, we will have an extra wakeup.
00733   return this->timer_queue_->cancel (&handler,
00734                                      dont_call_handle_close);
00735 }
00736 
00737 int
00738 ACE_Proactor::handle_events (ACE_Time_Value &wait_time)
00739 {
00740   return implementation ()->handle_events (wait_time);
00741 }
00742 
00743 int
00744 ACE_Proactor::handle_events (void)
00745 {
00746   return this->implementation ()->handle_events ();
00747 }
00748 
00749 int
00750 ACE_Proactor::wake_up_dispatch_threads (void)
00751 {
00752   return 0;
00753 }
00754 
00755 int
00756 ACE_Proactor::close_dispatch_threads (int)
00757 {
00758   return 0;
00759 }
00760 
00761 size_t
00762 ACE_Proactor::number_of_threads (void) const
00763 {
00764   return this->implementation ()->number_of_threads ();
00765 }
00766 
00767 void
00768 ACE_Proactor::number_of_threads (size_t threads)
00769 {
00770   this->implementation ()->number_of_threads (threads);
00771 }
00772 
00773 ACE_Proactor::TIMER_QUEUE *
00774 ACE_Proactor::timer_queue (void) const
00775 {
00776   return this->timer_queue_;
00777 }
00778 
00779 void
00780 ACE_Proactor::timer_queue (TIMER_QUEUE *tq)
00781 {
00782   // Cleanup old timer queue.
00783   if (this->delete_timer_queue_)
00784     {
00785       delete this->timer_queue_;
00786       this->delete_timer_queue_ = 0;
00787     }
00788 
00789   // New timer queue.
00790   if (tq == 0)
00791     {
00792       ACE_NEW (this->timer_queue_,
00793                TIMER_HEAP);
00794       this->delete_timer_queue_ = 1;
00795     }
00796   else
00797     {
00798       this->timer_queue_ = tq;
00799       this->delete_timer_queue_ = 0;
00800     }
00801 
00802   // Set the proactor in the timer queue's functor
00803   this->timer_queue_->upcall_functor ().proactor (*this);
00804 }
00805 
00806 ACE_HANDLE
00807 ACE_Proactor::get_handle (void) const
00808 {
00809   return this->implementation ()->get_handle ();
00810 }
00811 
00812 ACE_Proactor_Impl *
00813 ACE_Proactor::implementation (void) const
00814 {
00815   return this->implementation_;
00816 }
00817 
00818 
00819 ACE_Asynch_Read_Stream_Impl *
00820 ACE_Proactor::create_asynch_read_stream (void)
00821 {
00822   return this->implementation ()->create_asynch_read_stream ();
00823 }
00824 
00825 ACE_Asynch_Write_Stream_Impl *
00826 ACE_Proactor::create_asynch_write_stream (void)
00827 {
00828   return this->implementation ()->create_asynch_write_stream ();
00829 }
00830 
00831 ACE_Asynch_Read_Dgram_Impl *
00832 ACE_Proactor::create_asynch_read_dgram (void)
00833 {
00834   return this->implementation ()->create_asynch_read_dgram ();
00835 }
00836 
00837 ACE_Asynch_Write_Dgram_Impl *
00838 ACE_Proactor::create_asynch_write_dgram (void)
00839 {
00840   return this->implementation ()->create_asynch_write_dgram ();
00841 }
00842 
00843 ACE_Asynch_Read_File_Impl *
00844 ACE_Proactor::create_asynch_read_file (void)
00845 {
00846   return this->implementation ()->create_asynch_read_file ();
00847 }
00848 
00849 ACE_Asynch_Write_File_Impl *
00850 ACE_Proactor::create_asynch_write_file (void)
00851 {
00852   return this->implementation ()->create_asynch_write_file ();
00853 }
00854 
00855 ACE_Asynch_Accept_Impl *
00856 ACE_Proactor::create_asynch_accept (void)
00857 {
00858   return this->implementation ()->create_asynch_accept ();
00859 }
00860 
00861 ACE_Asynch_Connect_Impl *
00862 ACE_Proactor::create_asynch_connect (void)
00863 {
00864   return this->implementation ()->create_asynch_connect ();
00865 }
00866 
00867 ACE_Asynch_Transmit_File_Impl *
00868 ACE_Proactor::create_asynch_transmit_file (void)
00869 {
00870   return this->implementation ()->create_asynch_transmit_file ();
00871 }
00872 
00873 ACE_Asynch_Read_Stream_Result_Impl *
00874 ACE_Proactor::create_asynch_read_stream_result
00875   (ACE_Handler::Proxy_Ptr &handler_proxy,
00876    ACE_HANDLE handle,
00877    ACE_Message_Block &message_block,
00878    u_long bytes_to_read,
00879    const void* act,
00880    ACE_HANDLE event,
00881    int priority,
00882    int signal_number)
00883 {
00884   return this->implementation ()->create_asynch_read_stream_result
00885     (handler_proxy,
00886      handle,
00887      message_block,
00888      bytes_to_read,
00889      act,
00890      event,
00891      priority,
00892      signal_number);
00893 }
00894 
00895 
00896 ACE_Asynch_Write_Stream_Result_Impl *
00897 ACE_Proactor::create_asynch_write_stream_result
00898   (ACE_Handler::Proxy_Ptr &handler_proxy,
00899    ACE_HANDLE handle,
00900    ACE_Message_Block &message_block,
00901    u_long bytes_to_write,
00902    const void* act,
00903    ACE_HANDLE event,
00904    int priority,
00905    int signal_number)
00906 {
00907   return this->implementation ()->create_asynch_write_stream_result
00908     (handler_proxy,
00909      handle,
00910      message_block,
00911      bytes_to_write,
00912      act,
00913      event,
00914      priority,
00915      signal_number);
00916 }
00917 
00918 ACE_Asynch_Read_File_Result_Impl *
00919 ACE_Proactor::create_asynch_read_file_result
00920   (ACE_Handler::Proxy_Ptr &handler_proxy,
00921    ACE_HANDLE handle,
00922    ACE_Message_Block &message_block,
00923    u_long bytes_to_read,
00924    const void* act,
00925    u_long offset,
00926    u_long offset_high,
00927    ACE_HANDLE event,
00928    int priority,
00929    int signal_number)
00930 {
00931   return this->implementation ()->create_asynch_read_file_result
00932     (handler_proxy,
00933      handle,
00934      message_block,
00935      bytes_to_read,
00936      act,
00937      offset,
00938      offset_high,
00939      event,
00940      priority,
00941      signal_number);
00942 }
00943 
00944 ACE_Asynch_Write_File_Result_Impl *
00945 ACE_Proactor::create_asynch_write_file_result
00946   (ACE_Handler::Proxy_Ptr &handler_proxy,
00947    ACE_HANDLE handle,
00948    ACE_Message_Block &message_block,
00949    u_long bytes_to_write,
00950    const void* act,
00951    u_long offset,
00952    u_long offset_high,
00953    ACE_HANDLE event,
00954    int priority,
00955    int signal_number)
00956 {
00957   return this->implementation ()->create_asynch_write_file_result
00958     (handler_proxy,
00959      handle,
00960      message_block,
00961      bytes_to_write,
00962      act,
00963      offset,
00964      offset_high,
00965      event,
00966      priority,
00967      signal_number);
00968 }
00969 
00970 ACE_Asynch_Read_Dgram_Result_Impl *
00971 ACE_Proactor::create_asynch_read_dgram_result
00972   (ACE_Handler::Proxy_Ptr &handler_proxy,
00973    ACE_HANDLE handle,
00974    ACE_Message_Block *message_block,
00975    size_t bytes_to_read,
00976    int flags,
00977    int protocol_family,
00978    const void* act,
00979    ACE_HANDLE event,
00980    int priority,
00981    int signal_number)
00982 {
00983   return this->implementation()->create_asynch_read_dgram_result
00984     (handler_proxy,
00985      handle,
00986      message_block,
00987      bytes_to_read,
00988      flags,
00989      protocol_family,
00990      act,
00991      event,
00992      priority,
00993      signal_number);
00994 }
00995 
00996 ACE_Asynch_Write_Dgram_Result_Impl *
00997 ACE_Proactor::create_asynch_write_dgram_result
00998   (ACE_Handler::Proxy_Ptr &handler_proxy,
00999    ACE_HANDLE handle,
01000    ACE_Message_Block *message_block,
01001    size_t bytes_to_write,
01002    int flags,
01003    const void* act,
01004    ACE_HANDLE event,
01005    int priority,
01006    int signal_number)
01007 {
01008   return this->implementation()->create_asynch_write_dgram_result
01009     (handler_proxy,
01010      handle,
01011      message_block,
01012      bytes_to_write,
01013      flags,
01014      act,
01015      event,
01016      priority,
01017      signal_number);
01018 }
01019 
01020 ACE_Asynch_Accept_Result_Impl *
01021 ACE_Proactor::create_asynch_accept_result
01022   (ACE_Handler::Proxy_Ptr &handler_proxy,
01023    ACE_HANDLE listen_handle,
01024    ACE_HANDLE accept_handle,
01025    ACE_Message_Block &message_block,
01026    u_long bytes_to_read,
01027    const void* act,
01028    ACE_HANDLE event,
01029    int priority,
01030    int signal_number)
01031 {
01032   return this->implementation ()->create_asynch_accept_result
01033     (handler_proxy,
01034      listen_handle,
01035      accept_handle,
01036      message_block,
01037      bytes_to_read,
01038      act,
01039      event,
01040      priority,
01041      signal_number);
01042 }
01043 
01044 ACE_Asynch_Connect_Result_Impl *
01045 ACE_Proactor::create_asynch_connect_result
01046   (ACE_Handler::Proxy_Ptr &handler_proxy,
01047    ACE_HANDLE  connect_handle,
01048    const void* act,
01049    ACE_HANDLE event,
01050    int priority,
01051    int signal_number)
01052 {
01053   return this->implementation ()->create_asynch_connect_result
01054     (handler_proxy,
01055      connect_handle,
01056      act,
01057      event,
01058      priority,
01059      signal_number);
01060 }
01061 
01062 ACE_Asynch_Transmit_File_Result_Impl *
01063 ACE_Proactor::create_asynch_transmit_file_result
01064   (ACE_Handler::Proxy_Ptr &handler_proxy,
01065    ACE_HANDLE socket,
01066    ACE_HANDLE file,
01067    ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer,
01068    u_long bytes_to_write,
01069    u_long offset,
01070    u_long offset_high,
01071    u_long bytes_per_send,
01072    u_long flags,
01073    const void *act,
01074    ACE_HANDLE event,
01075    int priority,
01076    int signal_number)
01077 {
01078   return this->implementation ()->create_asynch_transmit_file_result
01079     (handler_proxy,
01080      socket,
01081      file,
01082      header_and_trailer,
01083      bytes_to_write,
01084      offset,
01085      offset_high,
01086      bytes_per_send,
01087      flags,
01088      act,
01089      event,
01090      priority,
01091      signal_number);
01092 }
01093 
01094 ACE_Asynch_Result_Impl *
01095 ACE_Proactor::create_asynch_timer
01096   (ACE_Handler::Proxy_Ptr &handler_proxy,
01097    const void *act,
01098    const ACE_Time_Value &tv,
01099    ACE_HANDLE event,
01100    int priority,
01101    int signal_number)
01102 {
01103   return this->implementation ()->create_asynch_timer
01104     (handler_proxy,
01105      act,
01106      tv,
01107      event,
01108      priority,
01109      signal_number);
01110 }
01111 
01112 int
01113 ACE_Proactor::proactor_post_wakeup_completions (int how_many)
01114 {
01115   return this->implementation ()->post_wakeup_completions (how_many);
01116 }
01117 
01118 void
01119 ACE_Proactor::implementation (ACE_Proactor_Impl *implementation)
01120 {
01121   this->implementation_ = implementation;
01122 }
01123 
01124 ACE_END_VERSIONED_NAMESPACE_DECL
01125 
01126 #else /* !ACE_WIN32 || !ACE_HAS_AIO_CALLS */
01127 
01128 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
01129 
01130 ACE_Proactor *
01131 ACE_Proactor::instance (size_t /* threads */)
01132 {
01133   return 0;
01134 }
01135 
01136 ACE_Proactor *
01137 ACE_Proactor::instance (ACE_Proactor *)
01138 {
01139   return 0;
01140 }
01141 
01142 void
01143 ACE_Proactor::close_singleton (void)
01144 {
01145 }
01146 
01147 int
01148 ACE_Proactor::run_event_loop (void)
01149 {
01150   // not implemented
01151   return -1;
01152 }
01153 
01154 int
01155 ACE_Proactor::run_event_loop (ACE_Time_Value &)
01156 {
01157   // not implemented
01158   return -1;
01159 }
01160 
01161 int
01162 ACE_Proactor::end_event_loop (void)
01163 {
01164   // not implemented
01165   return -1;
01166 }
01167 
01168 sig_atomic_t
01169 ACE_Proactor::event_loop_done (void)
01170 {
01171   return sig_atomic_t (1);
01172 }
01173 
01174 ACE_END_VERSIONED_NAMESPACE_DECL
01175 
01176 #endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */

Generated on Tue Feb 2 17:18:41 2010 for ACE by  doxygen 1.4.7