00001
00002
00003
00004
00005 #include "ace/WIN32_Proactor.h"
00006
00007 #if defined (ACE_WIN32) && defined (ACE_HAS_WIN32_OVERLAPPED_IO)
00008
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
00019
00020
00021
00022
00023
00024 class ACE_WIN32_Wakeup_Completion : public ACE_WIN32_Asynch_Result
00025 {
00026
00027 public:
00028
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
00036 virtual ~ACE_WIN32_Wakeup_Completion (void);
00037
00038
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
00049 number_of_threads_ (static_cast<DWORD> (number_of_threads)),
00050 used_with_reactor_event_loop_ (used_with_reactor_event_loop)
00051 {
00052
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_TEXT ("%p\n"),
00060 ACE_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
00082 if (this->completion_port_ != 0)
00083 {
00084
00085
00086 for (;;)
00087 {
00088 ACE_OVERLAPPED *overlapped = 0;
00089 u_long bytes_transferred = 0;
00090 ULONG_PTR completion_key = 0;
00091
00092
00093 BOOL res = ::GetQueuedCompletionStatus
00094 (this->completion_port_,
00095 &bytes_transferred,
00096 &completion_key,
00097 &overlapped,
00098 0);
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
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
00132
00133 if (errno != ERROR_INVALID_PARAMETER)
00134 {
00135 if (ACE::debug ())
00136 {
00137 ACE_DEBUG ((LM_ERROR,
00138 ACE_TEXT ("%p\n"),
00139 ACE_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
00508
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
00523
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
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
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
00585
00586
00587 return 0;
00588
00589 default:
00590 if (ACE::debug ())
00591 ACE_DEBUG ((LM_ERROR,
00592 ACE_TEXT ("%p\n"),
00593 ACE_TEXT ("GetQueuedCompletionStatus")));
00594 return -1;
00595 }
00596 }
00597 else if (overlapped != 0)
00598 {
00599
00600 ACE_WIN32_Asynch_Result *asynch_result = (ACE_WIN32_Asynch_Result *) overlapped;
00601
00602
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
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
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
00644 asynch_result->complete (bytes_transferred,
00645 error ? 0 : 1,
00646 (void *) completion_key,
00647 error);
00648 }
00649 ACE_SEH_FINALLY
00650 {
00651
00652 delete asynch_result;
00653 }
00654 }
00655
00656 int
00657 ACE_WIN32_Proactor::post_completion (ACE_WIN32_Asynch_Result *result)
00658 {
00659
00660 HANDLE handle = this->get_handle ();
00661
00662
00663
00664
00665
00666
00667
00668 DWORD bytes_transferred = 0;
00669 const void * completion_key = 0 ;
00670
00671 if (result != 0)
00672 {
00673
00674
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
00682 if (::PostQueuedCompletionStatus (this->completion_port_,
00683 bytes_transferred,
00684 comp_key,
00685 result
00686 ) == FALSE)
00687 {
00688 delete result;
00689
00690 if (ACE::debug ())
00691 {
00692 ACE_DEBUG ((LM_ERROR,
00693 ACE_TEXT ("%p\n"),
00694 ACE_TEXT ("PostQueuedCompletionStatus failed")));
00695 }
00696 return -1;
00697 }
00698
00699
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 ,
00793 int ,
00794 const void * ,
00795 u_long )
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