Proactor.cpp

Go to the documentation of this file.
00001 // $Id: Proactor.cpp 79134 2007-07-31 18:23:50Z johnnyw $
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 79134 2007-07-31 18:23:50Z johnnyw $")
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 int ACE_Proactor::delete_proactor_ = 0;
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->thr_mgr ()->wait_grp (this->grp_id ());
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                             int 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_ = 1;
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 (THR_NEW_LWP) == -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_ = 1;
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, int 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 
00414       delete ACE_Proactor::proactor_;
00415       ACE_Proactor::proactor_ = 0;
00416       ACE_Proactor::delete_proactor_ = 0;
00417     }
00418 }
00419 
00420 const ACE_TCHAR *
00421 ACE_Proactor::dll_name (void)
00422 {
00423   return ACE_TEXT ("ACE");
00424 }
00425 
00426 const ACE_TCHAR *
00427 ACE_Proactor::name (void)
00428 {
00429   return ACE_TEXT ("ACE_Proactor");
00430 }
00431 
00432 int
00433 ACE_Proactor::check_reconfiguration (ACE_Proactor *)
00434 {
00435 #if !defined (ACE_HAS_WINCE)  &&  !defined (ACE_LACKS_ACE_SVCCONF)
00436   if (ACE_Service_Config::reconfig_occurred ())
00437     {
00438       ACE_Service_Config::reconfigure ();
00439       return 1;
00440     }
00441 #endif /* ! ACE_HAS_WINCE || ! ACE_LACKS_ACE_SVCCONF */
00442   return 0;
00443 }
00444 
00445 int
00446 ACE_Proactor::proactor_run_event_loop (PROACTOR_EVENT_HOOK eh)
00447 {
00448   ACE_TRACE ("ACE_Proactor::proactor_run_event_loop");
00449   int result = 0;
00450 
00451   {
00452     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, mutex_, -1));
00453 
00454     // Early check. It is ok to do this without lock, since we care just
00455     // whether it is zero or non-zero.
00456     if (this->end_event_loop_ != 0)
00457       return 0;
00458 
00459     // First time you are in. Increment the thread count.
00460     this->event_loop_thread_count_ ++;
00461   }
00462 
00463   // Run the event loop.
00464   for (;;)
00465     {
00466       // Check the end loop flag. It is ok to do this without lock,
00467       // since we care just whether it is zero or non-zero.
00468       if (this->end_event_loop_ != 0)
00469         break;
00470 
00471       // <end_event_loop> is not set. Ready to do <handle_events>.
00472       result = this->handle_events ();
00473 
00474       if (eh != 0 && (*eh) (this))
00475         continue;
00476 
00477       if (result == -1)
00478         break;
00479     }
00480 
00481   // Leaving the event loop. Decrement the thread count.
00482 
00483   {
00484     // Obtain the lock in the MT environments.
00485     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, mutex_, -1));
00486 
00487     // Decrement the thread count.
00488     this->event_loop_thread_count_ --;
00489 
00490     if (this->event_loop_thread_count_ > 0
00491        && this->end_event_loop_ != 0)
00492        this->proactor_post_wakeup_completions (1);
00493   }
00494 
00495   return result;
00496 }
00497 
00498 // Handle events for -tv- time.  handle_events updates -tv- to reflect
00499 // time elapsed, so do not return until -tv- == 0, or an error occurs.
00500 int
00501 ACE_Proactor::proactor_run_event_loop (ACE_Time_Value &tv,
00502                                        PROACTOR_EVENT_HOOK eh)
00503 {
00504   ACE_TRACE ("ACE_Proactor::proactor_run_event_loop");
00505   int result = 0;
00506 
00507   {
00508     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, mutex_, -1));
00509 
00510     // Early check. It is ok to do this without lock, since we care just
00511     // whether it is zero or non-zero.
00512     if (this->end_event_loop_ != 0
00513        || tv == ACE_Time_Value::zero)
00514       return 0;
00515 
00516     // First time you are in. Increment the thread count.
00517     this->event_loop_thread_count_ ++;
00518   }
00519 
00520   // Run the event loop.
00521   for (;;)
00522     {
00523       // Check the end loop flag. It is ok to do this without lock,
00524       // since we care just whether it is zero or non-zero.
00525       if (this->end_event_loop_ != 0)
00526         break;
00527 
00528       // <end_event_loop> is not set. Ready to do <handle_events>.
00529       result = this->handle_events (tv);
00530 
00531       if (eh != 0 && (*eh) (this))
00532         continue;
00533 
00534       if (result == -1 || result == 0)
00535         break;
00536     }
00537 
00538   // Leaving the event loop. Decrement the thread count.
00539 
00540   {
00541     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, mutex_, -1));
00542 
00543     // Decrement the thread count.
00544     this->event_loop_thread_count_ --;
00545 
00546     if (this->event_loop_thread_count_ > 0
00547        && this->end_event_loop_ != 0)
00548        this->proactor_post_wakeup_completions (1);
00549   }
00550 
00551   return result;
00552 }
00553 
00554 int
00555 ACE_Proactor::proactor_reset_event_loop(void)
00556 {
00557   ACE_TRACE ("ACE_Proactor::proactor_reset_event_loop");
00558 
00559   // Obtain the lock in the MT environments.
00560   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, mutex_, -1));
00561 
00562   this->end_event_loop_ = 0;
00563   return 0;
00564 }
00565 
00566 int
00567 ACE_Proactor::proactor_end_event_loop (void)
00568 {
00569   ACE_TRACE ("ACE_Proactor::proactor_end_event_loop");
00570 
00571   int how_many = 0;
00572 
00573   {
00574     // Obtain the lock, set the end flag and post the wakeup
00575     // completions.
00576     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, mutex_, -1));
00577 
00578     // Set the end flag.
00579     this->end_event_loop_ = 1;
00580 
00581     // Number of completions to post.
00582     how_many = this->event_loop_thread_count_;
00583     if (how_many == 0)
00584       return 0;
00585   }
00586 
00587   // Post completions to all the threads so that they will all wake
00588   // up.
00589   return this->proactor_post_wakeup_completions (how_many);
00590 }
00591 
00592 int
00593 ACE_Proactor::proactor_event_loop_done (void)
00594 {
00595   ACE_TRACE ("ACE_Proactor::proactor_event_loop_done");
00596 
00597   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, mutex_, -1));
00598 
00599   return this->end_event_loop_ != 0 ? 1 : 0 ;
00600 }
00601 
00602 int
00603 ACE_Proactor::close (void)
00604 {
00605   // Close the implementation.
00606   if (this->implementation ()->close () == -1)
00607     ACE_ERROR_RETURN ((LM_ERROR,
00608                        ACE_TEXT ("%N:%l:(%P | %t):%p\n"),
00609                        ACE_TEXT ("ACE_Proactor::close:implementation couldnt be closed")),
00610                       -1);
00611 
00612   // Delete the implementation.
00613   if (this->delete_implementation_)
00614     {
00615       delete this->implementation ();
00616       this->implementation_ = 0;
00617     }
00618 
00619   // Delete the timer handler.
00620   if (this->timer_handler_)
00621     {
00622       delete this->timer_handler_;
00623       this->timer_handler_ = 0;
00624     }
00625 
00626   // Delete the timer queue.
00627   if (this->delete_timer_queue_)
00628     {
00629       delete this->timer_queue_;
00630       this->timer_queue_ = 0;
00631       this->delete_timer_queue_ = 0;
00632     }
00633 
00634   return 0;
00635 }
00636 
00637 int
00638 ACE_Proactor::register_handle (ACE_HANDLE handle,
00639                                const void *completion_key)
00640 {
00641   return this->implementation ()->register_handle (handle,
00642                                                    completion_key);
00643 }
00644 
00645 long
00646 ACE_Proactor::schedule_timer (ACE_Handler &handler,
00647                               const void *act,
00648                               const ACE_Time_Value &time)
00649 {
00650   return this->schedule_timer (handler,
00651                                act,
00652                                time,
00653                                ACE_Time_Value::zero);
00654 }
00655 
00656 long
00657 ACE_Proactor::schedule_repeating_timer (ACE_Handler &handler,
00658                                         const void *act,
00659                                         const ACE_Time_Value &interval)
00660 {
00661   return this->schedule_timer (handler,
00662                                act,
00663                                interval,
00664                                interval);
00665 }
00666 
00667 long
00668 ACE_Proactor::schedule_timer (ACE_Handler &handler,
00669                               const void *act,
00670                               const ACE_Time_Value &time,
00671                               const ACE_Time_Value &interval)
00672 {
00673   // absolute time.
00674   ACE_Time_Value absolute_time =
00675     this->timer_queue_->gettimeofday () + time;
00676 
00677   // Only one guy goes in here at a time
00678   ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX,
00679                             ace_mon,
00680                             this->timer_queue_->mutex (),
00681                             -1));
00682 
00683   // Remember the old proactor.
00684   ACE_Proactor *old_proactor = handler.proactor ();
00685 
00686   // Assign *this* Proactor to the handler.
00687   handler.proactor (this);
00688 
00689   // Schedule the timer
00690   long result = this->timer_queue_->schedule (&handler,
00691                                               act,
00692                                               absolute_time,
00693                                               interval);
00694   if (result != -1)
00695     {
00696       // no failures: check to see if we are the earliest time
00697       if (this->timer_queue_->earliest_time () == absolute_time)
00698 
00699         // wake up the timer thread
00700         if (this->timer_handler_->timer_event_.signal () == -1)
00701           {
00702             // Cancel timer
00703             this->timer_queue_->cancel (result);
00704             result = -1;
00705           }
00706     }
00707 
00708   if (result == -1)
00709     {
00710       // Reset the old proactor in case of failures.
00711       handler.proactor (old_proactor);
00712     }
00713 
00714   return result;
00715 }
00716 
00717 int
00718 ACE_Proactor::cancel_timer (long timer_id,
00719                             const void **arg,
00720                             int dont_call_handle_close)
00721 {
00722   // No need to singal timer event here. Even if the cancel timer was
00723   // the earliest, we will have an extra wakeup.
00724   return this->timer_queue_->cancel (timer_id,
00725                                      arg,
00726                                      dont_call_handle_close);
00727 }
00728 
00729 int
00730 ACE_Proactor::cancel_timer (ACE_Handler &handler,
00731                                   int dont_call_handle_close)
00732 {
00733   // No need to signal timer event here. Even if the cancel timer was
00734   // the earliest, we will have an extra wakeup.
00735   return this->timer_queue_->cancel (&handler,
00736                                      dont_call_handle_close);
00737 }
00738 
00739 int
00740 ACE_Proactor::handle_events (ACE_Time_Value &wait_time)
00741 {
00742   return implementation ()->handle_events (wait_time);
00743 }
00744 
00745 int
00746 ACE_Proactor::handle_events (void)
00747 {
00748   return this->implementation ()->handle_events ();
00749 }
00750 
00751 int
00752 ACE_Proactor::wake_up_dispatch_threads (void)
00753 {
00754   return 0;
00755 }
00756 
00757 int
00758 ACE_Proactor::close_dispatch_threads (int)
00759 {
00760   return 0;
00761 }
00762 
00763 size_t
00764 ACE_Proactor::number_of_threads (void) const
00765 {
00766   return this->implementation ()->number_of_threads ();
00767 }
00768 
00769 void
00770 ACE_Proactor::number_of_threads (size_t threads)
00771 {
00772   this->implementation ()->number_of_threads (threads);
00773 }
00774 
00775 ACE_Proactor::TIMER_QUEUE *
00776 ACE_Proactor::timer_queue (void) const
00777 {
00778   return this->timer_queue_;
00779 }
00780 
00781 void
00782 ACE_Proactor::timer_queue (TIMER_QUEUE *tq)
00783 {
00784   // Cleanup old timer queue.
00785   if (this->delete_timer_queue_)
00786     {
00787       delete this->timer_queue_;
00788       this->delete_timer_queue_ = 0;
00789     }
00790 
00791   // New timer queue.
00792   if (tq == 0)
00793     {
00794       ACE_NEW (this->timer_queue_,
00795                TIMER_HEAP);
00796       this->delete_timer_queue_ = 1;
00797     }
00798   else
00799     {
00800       this->timer_queue_ = tq;
00801       this->delete_timer_queue_ = 0;
00802     }
00803 
00804   // Set the proactor in the timer queue's functor
00805   this->timer_queue_->upcall_functor ().proactor (*this);
00806 }
00807 
00808 ACE_HANDLE
00809 ACE_Proactor::get_handle (void) const
00810 {
00811   return this->implementation ()->get_handle ();
00812 }
00813 
00814 ACE_Proactor_Impl *
00815 ACE_Proactor::implementation (void) const
00816 {
00817   return this->implementation_;
00818 }
00819 
00820 
00821 ACE_Asynch_Read_Stream_Impl *
00822 ACE_Proactor::create_asynch_read_stream (void)
00823 {
00824   return this->implementation ()->create_asynch_read_stream ();
00825 }
00826 
00827 ACE_Asynch_Write_Stream_Impl *
00828 ACE_Proactor::create_asynch_write_stream (void)
00829 {
00830   return this->implementation ()->create_asynch_write_stream ();
00831 }
00832 
00833 ACE_Asynch_Read_Dgram_Impl *
00834 ACE_Proactor::create_asynch_read_dgram (void)
00835 {
00836   return this->implementation ()->create_asynch_read_dgram ();
00837 }
00838 
00839 ACE_Asynch_Write_Dgram_Impl *
00840 ACE_Proactor::create_asynch_write_dgram (void)
00841 {
00842   return this->implementation ()->create_asynch_write_dgram ();
00843 }
00844 
00845 ACE_Asynch_Read_File_Impl *
00846 ACE_Proactor::create_asynch_read_file (void)
00847 {
00848   return this->implementation ()->create_asynch_read_file ();
00849 }
00850 
00851 ACE_Asynch_Write_File_Impl *
00852 ACE_Proactor::create_asynch_write_file (void)
00853 {
00854   return this->implementation ()->create_asynch_write_file ();
00855 }
00856 
00857 ACE_Asynch_Accept_Impl *
00858 ACE_Proactor::create_asynch_accept (void)
00859 {
00860   return this->implementation ()->create_asynch_accept ();
00861 }
00862 
00863 ACE_Asynch_Connect_Impl *
00864 ACE_Proactor::create_asynch_connect (void)
00865 {
00866   return this->implementation ()->create_asynch_connect ();
00867 }
00868 
00869 ACE_Asynch_Transmit_File_Impl *
00870 ACE_Proactor::create_asynch_transmit_file (void)
00871 {
00872   return this->implementation ()->create_asynch_transmit_file ();
00873 }
00874 
00875 ACE_Asynch_Read_Stream_Result_Impl *
00876 ACE_Proactor::create_asynch_read_stream_result
00877   (ACE_Handler::Proxy_Ptr &handler_proxy,
00878    ACE_HANDLE handle,
00879    ACE_Message_Block &message_block,
00880    u_long bytes_to_read,
00881    const void* act,
00882    ACE_HANDLE event,
00883    int priority,
00884    int signal_number)
00885 {
00886   return this->implementation ()->create_asynch_read_stream_result
00887     (handler_proxy,
00888      handle,
00889      message_block,
00890      bytes_to_read,
00891      act,
00892      event,
00893      priority,
00894      signal_number);
00895 }
00896 
00897 
00898 ACE_Asynch_Write_Stream_Result_Impl *
00899 ACE_Proactor::create_asynch_write_stream_result
00900   (ACE_Handler::Proxy_Ptr &handler_proxy,
00901    ACE_HANDLE handle,
00902    ACE_Message_Block &message_block,
00903    u_long bytes_to_write,
00904    const void* act,
00905    ACE_HANDLE event,
00906    int priority,
00907    int signal_number)
00908 {
00909   return this->implementation ()->create_asynch_write_stream_result
00910     (handler_proxy,
00911      handle,
00912      message_block,
00913      bytes_to_write,
00914      act,
00915      event,
00916      priority,
00917      signal_number);
00918 }
00919 
00920 ACE_Asynch_Read_File_Result_Impl *
00921 ACE_Proactor::create_asynch_read_file_result
00922   (ACE_Handler::Proxy_Ptr &handler_proxy,
00923    ACE_HANDLE handle,
00924    ACE_Message_Block &message_block,
00925    u_long bytes_to_read,
00926    const void* act,
00927    u_long offset,
00928    u_long offset_high,
00929    ACE_HANDLE event,
00930    int priority,
00931    int signal_number)
00932 {
00933   return this->implementation ()->create_asynch_read_file_result
00934     (handler_proxy,
00935      handle,
00936      message_block,
00937      bytes_to_read,
00938      act,
00939      offset,
00940      offset_high,
00941      event,
00942      priority,
00943      signal_number);
00944 }
00945 
00946 ACE_Asynch_Write_File_Result_Impl *
00947 ACE_Proactor::create_asynch_write_file_result
00948   (ACE_Handler::Proxy_Ptr &handler_proxy,
00949    ACE_HANDLE handle,
00950    ACE_Message_Block &message_block,
00951    u_long bytes_to_write,
00952    const void* act,
00953    u_long offset,
00954    u_long offset_high,
00955    ACE_HANDLE event,
00956    int priority,
00957    int signal_number)
00958 {
00959   return this->implementation ()->create_asynch_write_file_result
00960     (handler_proxy,
00961      handle,
00962      message_block,
00963      bytes_to_write,
00964      act,
00965      offset,
00966      offset_high,
00967      event,
00968      priority,
00969      signal_number);
00970 }
00971 
00972 ACE_Asynch_Read_Dgram_Result_Impl *
00973 ACE_Proactor::create_asynch_read_dgram_result
00974   (ACE_Handler::Proxy_Ptr &handler_proxy,
00975    ACE_HANDLE handle,
00976    ACE_Message_Block *message_block,
00977    size_t bytes_to_read,
00978    int flags,
00979    int protocol_family,
00980    const void* act,
00981    ACE_HANDLE event,
00982    int priority,
00983    int signal_number)
00984 {
00985   return this->implementation()->create_asynch_read_dgram_result
00986     (handler_proxy,
00987      handle,
00988      message_block,
00989      bytes_to_read,
00990      flags,
00991      protocol_family,
00992      act,
00993      event,
00994      priority,
00995      signal_number);
00996 }
00997 
00998 ACE_Asynch_Write_Dgram_Result_Impl *
00999 ACE_Proactor::create_asynch_write_dgram_result
01000   (ACE_Handler::Proxy_Ptr &handler_proxy,
01001    ACE_HANDLE handle,
01002    ACE_Message_Block *message_block,
01003    size_t bytes_to_write,
01004    int flags,
01005    const void* act,
01006    ACE_HANDLE event,
01007    int priority,
01008    int signal_number)
01009 {
01010   return this->implementation()->create_asynch_write_dgram_result
01011     (handler_proxy,
01012      handle,
01013      message_block,
01014      bytes_to_write,
01015      flags,
01016      act,
01017      event,
01018      priority,
01019      signal_number);
01020 }
01021 
01022 ACE_Asynch_Accept_Result_Impl *
01023 ACE_Proactor::create_asynch_accept_result
01024   (ACE_Handler::Proxy_Ptr &handler_proxy,
01025    ACE_HANDLE listen_handle,
01026    ACE_HANDLE accept_handle,
01027    ACE_Message_Block &message_block,
01028    u_long bytes_to_read,
01029    const void* act,
01030    ACE_HANDLE event,
01031    int priority,
01032    int signal_number)
01033 {
01034   return this->implementation ()->create_asynch_accept_result
01035     (handler_proxy,
01036      listen_handle,
01037      accept_handle,
01038      message_block,
01039      bytes_to_read,
01040      act,
01041      event,
01042      priority,
01043      signal_number);
01044 }
01045 
01046 ACE_Asynch_Connect_Result_Impl *
01047 ACE_Proactor::create_asynch_connect_result
01048   (ACE_Handler::Proxy_Ptr &handler_proxy,
01049    ACE_HANDLE  connect_handle,
01050    const void* act,
01051    ACE_HANDLE event,
01052    int priority,
01053    int signal_number)
01054 {
01055   return this->implementation ()->create_asynch_connect_result
01056     (handler_proxy,
01057      connect_handle,
01058      act,
01059      event,
01060      priority,
01061      signal_number);
01062 }
01063 
01064 ACE_Asynch_Transmit_File_Result_Impl *
01065 ACE_Proactor::create_asynch_transmit_file_result
01066   (ACE_Handler::Proxy_Ptr &handler_proxy,
01067    ACE_HANDLE socket,
01068    ACE_HANDLE file,
01069    ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer,
01070    u_long bytes_to_write,
01071    u_long offset,
01072    u_long offset_high,
01073    u_long bytes_per_send,
01074    u_long flags,
01075    const void *act,
01076    ACE_HANDLE event,
01077    int priority,
01078    int signal_number)
01079 {
01080   return this->implementation ()->create_asynch_transmit_file_result
01081     (handler_proxy,
01082      socket,
01083      file,
01084      header_and_trailer,
01085      bytes_to_write,
01086      offset,
01087      offset_high,
01088      bytes_per_send,
01089      flags,
01090      act,
01091      event,
01092      priority,
01093      signal_number);
01094 }
01095 
01096 ACE_Asynch_Result_Impl *
01097 ACE_Proactor::create_asynch_timer
01098   (ACE_Handler::Proxy_Ptr &handler_proxy,
01099    const void *act,
01100    const ACE_Time_Value &tv,
01101    ACE_HANDLE event,
01102    int priority,
01103    int signal_number)
01104 {
01105   return this->implementation ()->create_asynch_timer
01106     (handler_proxy,
01107      act,
01108      tv,
01109      event,
01110      priority,
01111      signal_number);
01112 }
01113 
01114 int
01115 ACE_Proactor::proactor_post_wakeup_completions (int how_many)
01116 {
01117   return this->implementation ()->post_wakeup_completions (how_many);
01118 }
01119 
01120 void
01121 ACE_Proactor::implementation (ACE_Proactor_Impl *implementation)
01122 {
01123   this->implementation_ = implementation;
01124 }
01125 
01126 ACE_END_VERSIONED_NAMESPACE_DECL
01127 
01128 #else /* !ACE_WIN32 || !ACE_HAS_AIO_CALLS */
01129 
01130 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
01131 
01132 ACE_Proactor *
01133 ACE_Proactor::instance (size_t /* threads */)
01134 {
01135   return 0;
01136 }
01137 
01138 ACE_Proactor *
01139 ACE_Proactor::instance (ACE_Proactor *)
01140 {
01141   return 0;
01142 }
01143 
01144 void
01145 ACE_Proactor::close_singleton (void)
01146 {
01147 }
01148 
01149 int
01150 ACE_Proactor::run_event_loop (void)
01151 {
01152   // not implemented
01153   return -1;
01154 }
01155 
01156 int
01157 ACE_Proactor::run_event_loop (ACE_Time_Value &)
01158 {
01159   // not implemented
01160   return -1;
01161 }
01162 
01163 int
01164 ACE_Proactor::end_event_loop (void)
01165 {
01166   // not implemented
01167   return -1;
01168 }
01169 
01170 sig_atomic_t
01171 ACE_Proactor::event_loop_done (void)
01172 {
01173   return sig_atomic_t (1);
01174 }
01175 
01176 ACE_END_VERSIONED_NAMESPACE_DECL
01177 
01178 #endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */

Generated on Sun Jan 27 12:05:35 2008 for ACE by doxygen 1.3.6