WIN32_Proactor.cpp

Go to the documentation of this file.
00001 // WIN32_Proactor.cpp,v 4.47 2006/04/19 07:57:27 jwillemsen Exp
00002 
00003 // ACE_RCSID(ace, Proactor, "WIN32_Proactor.cpp,v 4.47 2006/04/19 07:57:27 jwillemsen Exp")
00004 
00005 #include "ace/WIN32_Proactor.h"
00006 
00007 #if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE))
00008 // WIN implemenatation of the Proactor.
00009 
00010 #include "ace/Log_Msg.h"
00011 #include "ace/Object_Manager.h"
00012 #include "ace/OS_NS_errno.h"
00013 #include "ace/OS_NS_unistd.h"
00014 
00015 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00016 
00017 /**
00018  * @class ACE_WIN32_Wakeup_Completion
00019  *
00020  * This is result object is used by the <end_event_loop> of the
00021  * ACE_Proactor interface to wake up all the threads blocking
00022  * for completions.
00023  */
00024 class ACE_WIN32_Wakeup_Completion : public ACE_WIN32_Asynch_Result
00025 {
00026 
00027 public:
00028   /// Constructor.
00029   ACE_WIN32_Wakeup_Completion (ACE_Handler::Proxy_Ptr &handler_proxy,
00030                                const void *act = 0,
00031                                ACE_HANDLE event = ACE_INVALID_HANDLE,
00032                                int priority = 0,
00033                                int signal_number = ACE_SIGRTMIN);
00034 
00035   /// Destructor.
00036   virtual ~ACE_WIN32_Wakeup_Completion (void);
00037 
00038   /// This method calls the <handler>'s <handle_wakeup> method.
00039   virtual void complete (size_t bytes_transferred = 0,
00040                          int success = 1,
00041                          const void *completion_key = 0,
00042                          u_long error = 0);
00043 };
00044 
00045 ACE_WIN32_Proactor::ACE_WIN32_Proactor (size_t number_of_threads,
00046                                         int used_with_reactor_event_loop)
00047   : completion_port_ (0),
00048     // This *MUST* be 0, *NOT* ACE_INVALID_HANDLE !!!
00049     number_of_threads_ (static_cast<DWORD> (number_of_threads)),
00050     used_with_reactor_event_loop_ (used_with_reactor_event_loop)
00051 {
00052   // Create the completion port.
00053   this->completion_port_ = ::CreateIoCompletionPort (INVALID_HANDLE_VALUE,
00054                                                      0,
00055                                                      0,
00056                                                      this->number_of_threads_);
00057   if (this->completion_port_ == 0)
00058     ACE_ERROR ((LM_ERROR,
00059                 ACE_LIB_TEXT ("%p\n"),
00060                 ACE_LIB_TEXT ("CreateIoCompletionPort")));
00061 
00062   this->get_asynch_pseudo_task ().start ();
00063 }
00064 
00065 ACE_WIN32_Proactor::~ACE_WIN32_Proactor (void)
00066 {
00067   this->get_asynch_pseudo_task ().stop ();
00068 
00069   this->close ();
00070 }
00071 
00072 ACE_Asynch_Pseudo_Task &
00073 ACE_WIN32_Proactor::get_asynch_pseudo_task ()
00074 {
00075   return this->pseudo_task_;
00076 }
00077 
00078 int
00079 ACE_WIN32_Proactor::close (void)
00080 {
00081   // Close the completion port
00082   if (this->completion_port_ != 0)
00083     {
00084       // To avoid memory leaks we should delete all results from queue.
00085 
00086       for (;;)
00087         {
00088           ACE_OVERLAPPED *overlapped = 0;
00089           u_long bytes_transferred = 0;
00090           ULONG_PTR completion_key = 0;
00091 
00092           // Get the next asynchronous operation that completes
00093           BOOL res = ::GetQueuedCompletionStatus
00094             (this->completion_port_,
00095              &bytes_transferred,
00096              &completion_key,
00097              &overlapped,
00098              0);  // poll
00099 
00100           if (overlapped == 0 || res == FALSE)
00101             break;
00102 
00103           ACE_WIN32_Asynch_Result *asynch_result =
00104             (ACE_WIN32_Asynch_Result *) overlapped;
00105 
00106           delete asynch_result;
00107         }
00108 
00109       int result = ACE_OS::close (this->completion_port_);
00110       this->completion_port_ = 0;
00111       return result;
00112     }
00113 
00114   return 0;
00115 }
00116 
00117 int
00118 ACE_WIN32_Proactor::register_handle (ACE_HANDLE handle,
00119                                      const void *completion_key)
00120 {
00121   ULONG_PTR comp_key (reinterpret_cast<ULONG_PTR> (completion_key));
00122 
00123   // No locking is needed here as no state changes.
00124   ACE_HANDLE cp = ::CreateIoCompletionPort (handle,
00125                                             this->completion_port_,
00126                                             comp_key,
00127                                             this->number_of_threads_);
00128   if (cp == 0)
00129     {
00130       ACE_OS::set_errno_to_last_error ();
00131       // If errno == ERROR_INVALID_PARAMETER, then this handle was
00132       // already registered.
00133       if (errno != ERROR_INVALID_PARAMETER)
00134         {
00135           if (ACE::debug ())
00136             {
00137               ACE_DEBUG ((LM_ERROR,
00138                           ACE_LIB_TEXT ("%p\n"),
00139                           ACE_LIB_TEXT ("CreateIoCompletionPort")));
00140             }
00141           return -1;
00142         }
00143     }
00144   return 0;
00145 }
00146 
00147 ACE_Asynch_Read_Stream_Impl *
00148 ACE_WIN32_Proactor::create_asynch_read_stream (void)
00149 {
00150   ACE_Asynch_Read_Stream_Impl *implementation = 0;
00151   ACE_NEW_RETURN (implementation,
00152                   ACE_WIN32_Asynch_Read_Stream (this),
00153                   0);
00154   return implementation;
00155 }
00156 
00157 ACE_Asynch_Write_Stream_Impl *
00158 ACE_WIN32_Proactor::create_asynch_write_stream (void)
00159 {
00160   ACE_Asynch_Write_Stream_Impl *implementation = 0;
00161   ACE_NEW_RETURN (implementation,
00162                   ACE_WIN32_Asynch_Write_Stream (this),
00163                   0);
00164   return implementation;
00165 }
00166 
00167 ACE_Asynch_Read_Dgram_Impl *
00168 ACE_WIN32_Proactor::create_asynch_read_dgram (void)
00169 {
00170   ACE_Asynch_Read_Dgram_Impl *implementation = 0;
00171   ACE_NEW_RETURN (implementation,
00172                   ACE_WIN32_Asynch_Read_Dgram (this),
00173                   0);
00174   return implementation;
00175 }
00176 
00177 ACE_Asynch_Write_Dgram_Impl *
00178 ACE_WIN32_Proactor::create_asynch_write_dgram (void)
00179 {
00180   ACE_Asynch_Write_Dgram_Impl *implementation = 0;
00181   ACE_NEW_RETURN (implementation,
00182                   ACE_WIN32_Asynch_Write_Dgram (this),
00183                   0);
00184   return implementation;
00185 }
00186 
00187 ACE_Asynch_Read_File_Impl *
00188 ACE_WIN32_Proactor::create_asynch_read_file (void)
00189 {
00190   ACE_Asynch_Read_File_Impl *implementation = 0;
00191   ACE_NEW_RETURN (implementation,
00192                   ACE_WIN32_Asynch_Read_File (this),
00193                   0);
00194   return  implementation;
00195 }
00196 
00197 ACE_Asynch_Write_File_Impl *
00198 ACE_WIN32_Proactor::create_asynch_write_file (void)
00199 {
00200   ACE_Asynch_Write_File_Impl *implementation = 0;
00201   ACE_NEW_RETURN (implementation,
00202                   ACE_WIN32_Asynch_Write_File (this),
00203                   0);
00204   return  implementation;
00205 }
00206 
00207 ACE_Asynch_Accept_Impl *
00208 ACE_WIN32_Proactor::create_asynch_accept (void)
00209 {
00210   ACE_Asynch_Accept_Impl *implementation = 0;
00211   ACE_NEW_RETURN (implementation,
00212                   ACE_WIN32_Asynch_Accept (this),
00213                   0);
00214   return implementation;
00215 }
00216 
00217 ACE_Asynch_Connect_Impl *
00218 ACE_WIN32_Proactor::create_asynch_connect (void)
00219 {
00220   ACE_Asynch_Connect_Impl *implementation = 0;
00221   ACE_NEW_RETURN (implementation,
00222                   ACE_WIN32_Asynch_Connect (this),
00223                   0);
00224   return implementation;
00225 }
00226 
00227 ACE_Asynch_Transmit_File_Impl *
00228 ACE_WIN32_Proactor::create_asynch_transmit_file (void)
00229 {
00230   ACE_Asynch_Transmit_File_Impl *implementation = 0;
00231   ACE_NEW_RETURN (implementation,
00232                   ACE_WIN32_Asynch_Transmit_File (this),
00233                   0);
00234   return  implementation;
00235 }
00236 
00237 ACE_Asynch_Read_Stream_Result_Impl *
00238 ACE_WIN32_Proactor::create_asynch_read_stream_result
00239   (const ACE_Handler::Proxy_Ptr &handler_proxy,
00240    ACE_HANDLE handle,
00241    ACE_Message_Block &message_block,
00242    size_t bytes_to_read,
00243    const void* act,
00244    ACE_HANDLE event,
00245    int priority,
00246    int signal_number)
00247 {
00248   ACE_Asynch_Read_Stream_Result_Impl *implementation = 0;
00249   ACE_NEW_RETURN (implementation,
00250                   ACE_WIN32_Asynch_Read_Stream_Result (handler_proxy,
00251                                                        handle,
00252                                                        message_block,
00253                                                        bytes_to_read,
00254                                                        act,
00255                                                        event,
00256                                                        priority,
00257                                                        signal_number),
00258                   0);
00259   return implementation;
00260 }
00261 
00262 ACE_Asynch_Write_Stream_Result_Impl *
00263 ACE_WIN32_Proactor::create_asynch_write_stream_result
00264   (const ACE_Handler::Proxy_Ptr &handler_proxy,
00265    ACE_HANDLE handle,
00266    ACE_Message_Block &message_block,
00267    size_t bytes_to_write,
00268    const void* act,
00269    ACE_HANDLE event,
00270    int priority,
00271    int signal_number)
00272 {
00273   ACE_Asynch_Write_Stream_Result_Impl *implementation = 0;
00274   ACE_NEW_RETURN (implementation,
00275                   ACE_WIN32_Asynch_Write_Stream_Result (handler_proxy,
00276                                                         handle,
00277                                                         message_block,
00278                                                         bytes_to_write,
00279                                                         act,
00280                                                         event,
00281                                                         priority,
00282                                                         signal_number),
00283                   0);
00284   return implementation;
00285 }
00286 
00287 ACE_Asynch_Read_File_Result_Impl *
00288 ACE_WIN32_Proactor::create_asynch_read_file_result
00289   (const ACE_Handler::Proxy_Ptr &handler_proxy,
00290    ACE_HANDLE handle,
00291    ACE_Message_Block &message_block,
00292    size_t bytes_to_read,
00293    const void* act,
00294    u_long offset,
00295    u_long offset_high,
00296    ACE_HANDLE event,
00297    int priority,
00298    int signal_number)
00299 {
00300   ACE_Asynch_Read_File_Result_Impl *implementation = 0;
00301   ACE_NEW_RETURN (implementation,
00302                   ACE_WIN32_Asynch_Read_File_Result (handler_proxy,
00303                                                      handle,
00304                                                      message_block,
00305                                                      bytes_to_read,
00306                                                      act,
00307                                                      offset,
00308                                                      offset_high,
00309                                                      event,
00310                                                      priority,
00311                                                      signal_number),
00312                   0);
00313   return implementation;
00314 }
00315 
00316 ACE_Asynch_Write_File_Result_Impl *
00317 ACE_WIN32_Proactor::create_asynch_write_file_result
00318  (const ACE_Handler::Proxy_Ptr &handler_proxy,
00319   ACE_HANDLE handle,
00320   ACE_Message_Block &message_block,
00321   size_t bytes_to_write,
00322   const void* act,
00323   u_long offset,
00324   u_long offset_high,
00325   ACE_HANDLE event,
00326   int priority,
00327   int signal_number)
00328 {
00329   ACE_Asynch_Write_File_Result_Impl *implementation = 0;
00330   ACE_NEW_RETURN (implementation,
00331                   ACE_WIN32_Asynch_Write_File_Result (handler_proxy,
00332                                                       handle,
00333                                                       message_block,
00334                                                       bytes_to_write,
00335                                                       act,
00336                                                       offset,
00337                                                       offset_high,
00338                                                       event,
00339                                                       priority,
00340                                                       signal_number),
00341                   0);
00342   return implementation;
00343 }
00344 
00345 ACE_Asynch_Read_Dgram_Result_Impl *
00346 ACE_WIN32_Proactor::create_asynch_read_dgram_result
00347   (const ACE_Handler::Proxy_Ptr &handler_proxy,
00348    ACE_HANDLE handle,
00349    ACE_Message_Block *message_block,
00350    size_t bytes_to_read,
00351    int flags,
00352    int protocol_family,
00353    const void* act,
00354    ACE_HANDLE event,
00355    int priority,
00356    int signal_number)
00357 {
00358   ACE_Asynch_Read_Dgram_Result_Impl *implementation = 0;
00359   ACE_NEW_RETURN (implementation,
00360                   ACE_WIN32_Asynch_Read_Dgram_Result (handler_proxy,
00361                                                       handle,
00362                                                       message_block,
00363                                                       bytes_to_read,
00364                                                       flags,
00365                                                       protocol_family,
00366                                                       act,
00367                                                       event,
00368                                                       priority,
00369                                                       signal_number),
00370                   0);
00371   return implementation;
00372 }
00373 
00374 ACE_Asynch_Write_Dgram_Result_Impl *
00375 ACE_WIN32_Proactor::create_asynch_write_dgram_result
00376   (const ACE_Handler::Proxy_Ptr &handler_proxy,
00377    ACE_HANDLE handle,
00378    ACE_Message_Block *message_block,
00379    size_t bytes_to_read,
00380    int flags,
00381    const void* act,
00382    ACE_HANDLE event,
00383    int priority,
00384    int signal_number)
00385 {
00386   ACE_Asynch_Write_Dgram_Result_Impl *implementation = 0;
00387   ACE_NEW_RETURN (implementation,
00388                   ACE_WIN32_Asynch_Write_Dgram_Result(handler_proxy,
00389                                                       handle,
00390                                                       message_block,
00391                                                       bytes_to_read,
00392                                                       flags,
00393                                                       act,
00394                                                       event,
00395                                                       priority,
00396                                                       signal_number),
00397                  0);
00398   return implementation;
00399 }
00400 
00401 ACE_Asynch_Accept_Result_Impl *
00402 ACE_WIN32_Proactor::create_asynch_accept_result
00403   (const ACE_Handler::Proxy_Ptr &handler_proxy,
00404    ACE_HANDLE listen_handle,
00405    ACE_HANDLE accept_handle,
00406    ACE_Message_Block &message_block,
00407    size_t bytes_to_read,
00408    const void* act,
00409    ACE_HANDLE event,
00410    int priority,
00411    int signal_number)
00412 {
00413   ACE_Asynch_Accept_Result_Impl *implementation = 0;
00414   ACE_NEW_RETURN (implementation,
00415                   ACE_WIN32_Asynch_Accept_Result (handler_proxy,
00416                                                   listen_handle,
00417                                                   accept_handle,
00418                                                   message_block,
00419                                                   bytes_to_read,
00420                                                   act,
00421                                                   event,
00422                                                   priority,
00423                                                   signal_number),
00424                   0);
00425   return implementation;
00426 }
00427 
00428 ACE_Asynch_Connect_Result_Impl *
00429 ACE_WIN32_Proactor::create_asynch_connect_result
00430   (const ACE_Handler::Proxy_Ptr &handler_proxy,
00431    ACE_HANDLE connect_handle,
00432    const void *act,
00433    ACE_HANDLE event,
00434    int priority,
00435    int signal_number)
00436 {
00437   ACE_Asynch_Connect_Result_Impl *implementation = 0;
00438   ACE_NEW_RETURN (implementation,
00439                   ACE_WIN32_Asynch_Connect_Result (handler_proxy,
00440                                                    connect_handle,
00441                                                    act,
00442                                                    event,
00443                                                    priority,
00444                                                    signal_number),
00445                   0);
00446   return implementation;
00447 }
00448 
00449 ACE_Asynch_Transmit_File_Result_Impl *
00450 ACE_WIN32_Proactor::create_asynch_transmit_file_result
00451   (const ACE_Handler::Proxy_Ptr &handler_proxy,
00452    ACE_HANDLE socket,
00453    ACE_HANDLE file,
00454    ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer,
00455    size_t bytes_to_write,
00456    u_long offset,
00457    u_long offset_high,
00458    size_t bytes_per_send,
00459    u_long flags,
00460    const void *act,
00461    ACE_HANDLE event,
00462    int priority,
00463    int signal_number)
00464 {
00465   ACE_Asynch_Transmit_File_Result_Impl *implementation = 0;
00466   ACE_NEW_RETURN (implementation,
00467                   ACE_WIN32_Asynch_Transmit_File_Result (handler_proxy,
00468                                                          socket,
00469                                                          file,
00470                                                          header_and_trailer,
00471                                                          bytes_to_write,
00472                                                          offset,
00473                                                          offset_high,
00474                                                          bytes_per_send,
00475                                                          flags,
00476                                                          act,
00477                                                          event,
00478                                                          priority,
00479                                                          signal_number),
00480                   0);
00481   return implementation;
00482 }
00483 
00484 ACE_Asynch_Result_Impl *
00485 ACE_WIN32_Proactor::create_asynch_timer (const ACE_Handler::Proxy_Ptr &handler_proxy,
00486                                          const void *act,
00487                                          const ACE_Time_Value &tv,
00488                                          ACE_HANDLE event,
00489                                          int priority,
00490                                          int signal_number)
00491 {
00492   ACE_Asynch_Result_Impl *implementation = 0;
00493   ACE_NEW_RETURN (implementation,
00494                   ACE_WIN32_Asynch_Timer (handler_proxy,
00495                                           act,
00496                                           tv,
00497                                           event,
00498                                           priority,
00499                                           signal_number),
00500                   0);
00501   return implementation;
00502 }
00503 
00504 int
00505 ACE_WIN32_Proactor::handle_signal (int, siginfo_t *, ucontext_t *)
00506 {
00507   // Perform a non-blocking "poll" for all the I/O events that have
00508   // completed in the I/O completion queue.
00509 
00510   int result = 0;
00511 
00512   for (ACE_Time_Value timeout (0, 0);
00513        ;
00514       )
00515     {
00516       result = this->handle_events (timeout);
00517 
00518       if (result != 1)
00519         break;
00520     }
00521 
00522   // If our handle_events failed, we'll report a failure to the
00523   // Reactor.
00524   return result == -1 ? -1 : 0;
00525 }
00526 
00527 int
00528 ACE_WIN32_Proactor::handle_close (ACE_HANDLE handle,
00529                                   ACE_Reactor_Mask close_mask)
00530 {
00531   ACE_UNUSED_ARG (close_mask);
00532   ACE_UNUSED_ARG (handle);
00533 
00534   return this->close ();
00535 }
00536 
00537 ACE_HANDLE
00538 ACE_WIN32_Proactor::get_handle (void) const
00539 {
00540   if (this->used_with_reactor_event_loop_)
00541     return this->event_.handle ();
00542   else
00543     return 0;
00544 }
00545 
00546 int
00547 ACE_WIN32_Proactor::handle_events (ACE_Time_Value &wait_time)
00548 {
00549   // Decrement <wait_time> with the amount of time spent in the method
00550   ACE_Countdown_Time countdown (&wait_time);
00551   return this->handle_events (wait_time.msec ());
00552 }
00553 
00554 int
00555 ACE_WIN32_Proactor::handle_events (void)
00556 {
00557   return this->handle_events (ACE_INFINITE);
00558 }
00559 
00560 int
00561 ACE_WIN32_Proactor::handle_events (unsigned long milli_seconds)
00562 {
00563   ACE_OVERLAPPED *overlapped = 0;
00564   u_long bytes_transferred = 0;
00565   ULONG_PTR completion_key = 0;
00566 
00567   // Get the next asynchronous operation that completes
00568   BOOL result = ::GetQueuedCompletionStatus (this->completion_port_,
00569                                              &bytes_transferred,
00570                                              &completion_key,
00571                                              &overlapped,
00572                                              milli_seconds);
00573   if (result == FALSE && overlapped == 0)
00574     {
00575       ACE_OS::set_errno_to_last_error ();
00576 
00577       switch (errno)
00578         {
00579         case WAIT_TIMEOUT:
00580           errno = ETIME;
00581           return 0;
00582 
00583         case ERROR_SUCCESS:
00584           // Calling GetQueuedCompletionStatus with timeout value 0
00585           // returns FALSE with extended errno "ERROR_SUCCESS" errno =
00586           // ETIME; ?? I don't know if this has to be done !!
00587           return 0;
00588 
00589         default:
00590           if (ACE::debug ())
00591             ACE_DEBUG ((LM_ERROR,
00592                         ACE_LIB_TEXT ("%p\n"),
00593                         ACE_LIB_TEXT ("GetQueuedCompletionStatus")));
00594           return -1;
00595         }
00596     }
00597   else
00598     {
00599       // Narrow the result.
00600       ACE_WIN32_Asynch_Result *asynch_result = (ACE_WIN32_Asynch_Result *) overlapped;
00601 
00602       // If errors happen, grab the error.
00603       if (result == FALSE)
00604         ACE_OS::set_errno_to_last_error ();
00605       else
00606         errno = 0;
00607 
00608       u_long result_err = asynch_result->error ();
00609 
00610       // if "result_err" is 0 than
00611       //     It is normal OS/WIN32 AIO completion.
00612       //     We have cleared asynch_result->error_
00613       //     during shared_read/shared_write.
00614       //     The real error code is already stored in "errno",
00615       //     so copy "errno" value to the "result_err"
00616       //     and pass this "result_err" code
00617       //     to the application_specific_code ()
00618       // else
00619       //    "result_err" non zero
00620       //     it means we have "post_completed" result
00621       //     so pass this "result_err" code
00622       //     to the application_specific_code ()
00623 
00624       if (result_err == 0)
00625         result_err = errno ;
00626 
00627       this->application_specific_code (asynch_result,
00628                                        static_cast<size_t> (bytes_transferred),
00629                                        (void *) completion_key,
00630                                        result_err);
00631     }
00632   return 1;
00633 }
00634 
00635 void
00636 ACE_WIN32_Proactor::application_specific_code (ACE_WIN32_Asynch_Result *asynch_result,
00637                                                size_t bytes_transferred,
00638                                                const void *completion_key,
00639                                                u_long error)
00640 {
00641   ACE_SEH_TRY
00642     {
00643       // Call completion hook
00644       asynch_result->complete (bytes_transferred,
00645                                error ? 0 : 1,
00646                                (void *) completion_key,
00647                                error);
00648     }
00649   ACE_SEH_FINALLY
00650     {
00651       // This is crucial to prevent memory leaks
00652       delete asynch_result;
00653     }
00654 }
00655 
00656 int
00657 ACE_WIN32_Proactor::post_completion (ACE_WIN32_Asynch_Result *result)
00658 {
00659   // Grab the event associated with the Proactor
00660   HANDLE handle = this->get_handle ();
00661 
00662   // pass
00663   //   bytes_transferred
00664   //   completion_key
00665   // to the ::PostQueuedCompletionStatus()
00666   //   error will be extracted later in handle_events()
00667 
00668   DWORD bytes_transferred = 0;
00669   const void * completion_key = 0 ;
00670 
00671   if (result != 0)
00672     {
00673       // This cast is ok since the original API calls restricted the transfer
00674       // counts to DWORD range.
00675       bytes_transferred = static_cast<DWORD> (result->bytes_transferred ());
00676       completion_key = result->completion_key();
00677     }
00678 
00679   ULONG_PTR comp_key (reinterpret_cast<ULONG_PTR> (completion_key));
00680 
00681   // Post a completion
00682   if (::PostQueuedCompletionStatus (this->completion_port_, // completion port
00683                                     bytes_transferred,      // xfer count
00684                                     comp_key,               // completion key
00685                                     result                  // overlapped
00686                                    ) == FALSE)
00687     {
00688       delete result;
00689 
00690       if (ACE::debug ())
00691         {
00692           ACE_DEBUG ((LM_ERROR,
00693                       ACE_LIB_TEXT ("%p\n"),
00694                       ACE_LIB_TEXT ("PostQueuedCompletionStatus failed")));
00695         }
00696       return -1;
00697     }
00698 
00699   // If Proactor event is valid, signal it
00700   if (handle != ACE_INVALID_HANDLE
00701       && handle != 0)
00702     ACE_OS::event_signal (&handle);
00703 
00704   return 0;
00705 }
00706 
00707 int
00708 ACE_WIN32_Proactor::post_wakeup_completions (int how_many)
00709 {
00710   ACE_WIN32_Wakeup_Completion *wakeup_completion = 0;
00711 
00712   for (ssize_t ci = 0; ci < how_many; ci++)
00713     {
00714       ACE_NEW_RETURN
00715         (wakeup_completion,
00716          ACE_WIN32_Wakeup_Completion (this->wakeup_handler_.proxy ()),
00717          -1);
00718 
00719       if (wakeup_completion->post_completion (this) == -1)
00720         return -1;
00721     }
00722 
00723   return 0;
00724 }
00725 
00726 int
00727 ACE_WIN32_Proactor::wake_up_dispatch_threads (void)
00728 {
00729   return 0;
00730 }
00731 
00732 int
00733 ACE_WIN32_Proactor::close_dispatch_threads (int)
00734 {
00735   return 0;
00736 }
00737 
00738 size_t
00739 ACE_WIN32_Proactor::number_of_threads (void) const
00740 {
00741   return static_cast<size_t> (this->number_of_threads_);
00742 }
00743 
00744 void
00745 ACE_WIN32_Proactor::number_of_threads (size_t threads)
00746 {
00747   this->number_of_threads_ = static_cast<DWORD> (threads);
00748 }
00749 
00750 ACE_WIN32_Asynch_Timer::ACE_WIN32_Asynch_Timer
00751   (const ACE_Handler::Proxy_Ptr &handler_proxy,
00752    const void *act,
00753    const ACE_Time_Value &tv,
00754    ACE_HANDLE event,
00755    int priority,
00756    int signal_number)
00757   : ACE_Asynch_Result_Impl (),
00758     ACE_WIN32_Asynch_Result (handler_proxy, act, event, 0, 0, priority,
00759                              signal_number),
00760     time_ (tv)
00761 {
00762 }
00763 
00764 void
00765 ACE_WIN32_Asynch_Timer::complete (size_t,
00766                                   int,
00767                                   const void *,
00768                                   u_long)
00769 {
00770   ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
00771   if (handler != 0)
00772     handler->handle_time_out (this->time_, this->act ());
00773 }
00774 
00775 ACE_WIN32_Wakeup_Completion::ACE_WIN32_Wakeup_Completion
00776   (ACE_Handler::Proxy_Ptr &handler_proxy,
00777    const void *act,
00778    ACE_HANDLE event,
00779    int priority,
00780    int signal_number)
00781   : ACE_Asynch_Result_Impl (),
00782     ACE_WIN32_Asynch_Result
00783      (handler_proxy, act, event, 0, 0, priority, signal_number)
00784 {
00785 }
00786 
00787 ACE_WIN32_Wakeup_Completion::~ACE_WIN32_Wakeup_Completion (void)
00788 {
00789 }
00790 
00791 void
00792 ACE_WIN32_Wakeup_Completion::complete (size_t       /* bytes_transferred */,
00793                                        int          /* success */,
00794                                        const void * /* completion_key */,
00795                                        u_long       /*  error */)
00796 {
00797   ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
00798   if (handler != 0)
00799     handler->handle_wakeup ();
00800 }
00801 
00802 ACE_END_VERSIONED_NAMESPACE_DECL
00803 
00804 #endif /* ACE_WIN32 */

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