WIN32_Asynch_IO.cpp

Go to the documentation of this file.
00001 // $Id: WIN32_Asynch_IO.cpp 79596 2007-09-06 14:47:30Z schmidt $
00002 
00003 #include "ace/WIN32_Asynch_IO.h"
00004 
00005 ACE_RCSID (ace,
00006            Win32_Asynch_IO,
00007            "$Id: WIN32_Asynch_IO.cpp 79596 2007-09-06 14:47:30Z schmidt $")
00008 
00009 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) && \
00010     (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 == 1))
00011 
00012 #include "ace/WIN32_Proactor.h"
00013 #include "ace/Proactor.h"
00014 #include "ace/Message_Block.h"
00015 #include "ace/Service_Config.h"
00016 #include "ace/INET_Addr.h"
00017 #include "ace/Task_T.h"
00018 #include "ace/OS_NS_errno.h"
00019 #include "ace/OS_NS_unistd.h"
00020 #include "ace/OS_NS_sys_socket.h"
00021 
00022 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00023 
00024 size_t
00025 ACE_WIN32_Asynch_Result::bytes_transferred (void) const
00026 {
00027   return this->bytes_transferred_;
00028 }
00029 
00030 const void *
00031 ACE_WIN32_Asynch_Result::act (void) const
00032 {
00033   return this->act_;
00034 }
00035 
00036 int
00037 ACE_WIN32_Asynch_Result::success (void) const
00038 {
00039   return this->success_;
00040 }
00041 
00042 const void *
00043 ACE_WIN32_Asynch_Result::completion_key (void) const
00044 {
00045   return this->completion_key_;
00046 }
00047 
00048 u_long
00049 ACE_WIN32_Asynch_Result::error (void) const
00050 {
00051   return this->error_;
00052 }
00053 
00054 ACE_HANDLE
00055 ACE_WIN32_Asynch_Result::event (void) const
00056 {
00057   return this->hEvent;
00058 }
00059 
00060 u_long
00061 ACE_WIN32_Asynch_Result::offset (void) const
00062 {
00063   return this->Offset;
00064 }
00065 
00066 u_long
00067 ACE_WIN32_Asynch_Result::offset_high (void) const
00068 {
00069   return this->OffsetHigh;
00070 }
00071 
00072 int
00073 ACE_WIN32_Asynch_Result::priority (void) const
00074 {
00075   ACE_NOTSUP_RETURN (0);
00076 }
00077 
00078 int
00079 ACE_WIN32_Asynch_Result::signal_number (void) const
00080 {
00081   ACE_NOTSUP_RETURN (0);
00082 }
00083 
00084 int
00085 ACE_WIN32_Asynch_Result::post_completion (ACE_Proactor_Impl *proactor)
00086 {
00087   // Get to the platform specific implementation.
00088   ACE_WIN32_Proactor *win32_proactor = dynamic_cast<ACE_WIN32_Proactor *> (proactor);
00089 
00090   if (win32_proactor == 0)
00091     ACE_ERROR_RETURN ((LM_ERROR,
00092                        ACE_TEXT ("Dynamic cast to WIN32 Proactor failed\n")),
00093                       -1);
00094 
00095   // Post myself.
00096   return win32_proactor->post_completion (this);
00097 }
00098 
00099 void
00100 ACE_WIN32_Asynch_Result::set_bytes_transferred (size_t nbytes)
00101 {
00102   this->bytes_transferred_ = nbytes;
00103 }
00104 
00105 void
00106 ACE_WIN32_Asynch_Result::set_error (u_long errcode)
00107 {
00108   this->error_ = errcode;
00109 }
00110 
00111 ACE_WIN32_Asynch_Result::~ACE_WIN32_Asynch_Result (void)
00112 {
00113 }
00114 
00115 ACE_WIN32_Asynch_Result::ACE_WIN32_Asynch_Result
00116    (const ACE_Handler::Proxy_Ptr &handler_proxy,
00117     const void* act,
00118     ACE_HANDLE event,
00119     u_long offset,
00120     u_long offset_high,
00121     int priority,
00122     int signal_number)
00123   : ACE_Asynch_Result_Impl (),
00124     OVERLAPPED (),
00125     handler_proxy_ (handler_proxy),
00126     act_ (act),
00127     bytes_transferred_ (0),
00128     success_ (0),
00129     completion_key_ (0),
00130     error_ (0)
00131 {
00132   // Set the ACE_OVERLAPPED structure
00133   this->Internal = 0;
00134   this->InternalHigh = 0;
00135   this->Offset = offset;
00136   this->OffsetHigh = offset_high;
00137   this->hEvent = event;
00138 
00139   ACE_UNUSED_ARG (priority);
00140   ACE_UNUSED_ARG (signal_number);
00141 }
00142 
00143 int
00144 ACE_WIN32_Asynch_Operation::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
00145                                   ACE_HANDLE handle,
00146                                   const void *completion_key,
00147                                   ACE_Proactor *proactor)
00148 {
00149   this->proactor_ = proactor;
00150   this->handler_proxy_ = handler_proxy;
00151   this->handle_ = handle;
00152 
00153   // Grab the handle from the <handler> if <handle> is invalid
00154   if (this->handle_ == ACE_INVALID_HANDLE)
00155     {
00156       ACE_Handler *handler = handler_proxy.get ()->handler ();
00157       if (handler != 0)
00158         this->handle_ = handler->handle ();
00159     }
00160   if (this->handle_ == ACE_INVALID_HANDLE)
00161     return -1;
00162 
00163   if (this->proactor_!= 0)
00164     // update implementation.
00165     this->win32_proactor_ =
00166       dynamic_cast <ACE_WIN32_Proactor *>(this->proactor_->implementation ());
00167 
00168   // Register with the <proactor>.
00169   return this->win32_proactor_->register_handle (this->handle_,
00170                                                  completion_key);
00171 }
00172 
00173 int
00174 ACE_WIN32_Asynch_Operation::cancel (void)
00175 {
00176 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) \
00177     && (   (defined (_MSC_VER)) \
00178         || (defined (__BORLANDC__)) \
00179         || (defined (__MINGW32)))
00180   // All I/O operations that are canceled will complete with the error
00181   // ERROR_OPERATION_ABORTED. All completion notifications for the I/O
00182   // operations will occur normally.
00183 
00184   // @@ This API returns 0 on failure. So, I am returning -1 in that
00185   //    case. Is that right? (Alex).
00186 
00187   int const result = (int) ::CancelIo (this->handle_);
00188 
00189   if (result == 0)
00190     // Couldnt cancel the operations.
00191     return 2;
00192 
00193   // result is non-zero. All the operations are cancelled then.
00194   return 0;
00195 
00196 #else /* Not ACE_HAS_WIN32_OVERLAPPED_IO && _MSC... */
00197   ACE_NOTSUP_RETURN (-1);
00198 #endif /* ACE_HAS_AIO_CALLS */
00199 }
00200 
00201 ACE_Proactor *
00202 ACE_WIN32_Asynch_Operation::proactor (void) const
00203 {
00204   return this->proactor_;
00205 }
00206 
00207 ACE_WIN32_Asynch_Operation::ACE_WIN32_Asynch_Operation (ACE_WIN32_Proactor *win32_proactor)
00208   : ACE_Asynch_Operation_Impl (),
00209     win32_proactor_ (win32_proactor),
00210     proactor_ (0),
00211     handle_ (ACE_INVALID_HANDLE)
00212 {
00213 }
00214 
00215 ACE_WIN32_Asynch_Operation::~ACE_WIN32_Asynch_Operation (void)
00216 {
00217 }
00218 
00219 // ************************************************************
00220 
00221 size_t
00222 ACE_WIN32_Asynch_Read_Stream_Result::bytes_to_read (void) const
00223 {
00224   return this->bytes_to_read_;
00225 }
00226 
00227 ACE_Message_Block &
00228 ACE_WIN32_Asynch_Read_Stream_Result::message_block (void) const
00229 {
00230   return this->message_block_;
00231 }
00232 
00233 ACE_HANDLE
00234 ACE_WIN32_Asynch_Read_Stream_Result::handle (void) const
00235 {
00236   return this->handle_;
00237 }
00238 
00239 ACE_WIN32_Asynch_Read_Stream_Result::ACE_WIN32_Asynch_Read_Stream_Result (
00240   const ACE_Handler::Proxy_Ptr &handler_proxy,
00241   ACE_HANDLE handle,
00242   ACE_Message_Block &message_block,
00243   size_t bytes_to_read,
00244   const void* act,
00245   ACE_HANDLE event,
00246   int priority,
00247   int signal_number,
00248   int scatter_enabled)
00249   : ACE_Asynch_Result_Impl (),
00250     ACE_Asynch_Read_Stream_Result_Impl (),
00251     ACE_WIN32_Asynch_Result (handler_proxy,
00252                              act,
00253                              event,
00254                              0,
00255                              0,
00256                              priority,
00257                              signal_number),
00258     bytes_to_read_ (bytes_to_read),
00259     message_block_ (message_block),
00260     handle_ (handle),
00261     scatter_enabled_ (scatter_enabled)
00262 {
00263 }
00264 
00265 void
00266 ACE_WIN32_Asynch_Read_Stream_Result::complete (size_t bytes_transferred,
00267                                                int success,
00268                                                const void *completion_key,
00269                                                u_long error)
00270 {
00271   // Copy the data which was returned by GetQueuedCompletionStatus
00272   this->bytes_transferred_ = bytes_transferred;
00273   this->success_ = success;
00274   this->completion_key_ = completion_key;
00275   this->error_ = error;
00276 
00277   // Appropriately move the pointers in the message block.
00278   if (!this->scatter_enabled ())
00279     this->message_block_.wr_ptr (bytes_transferred);
00280   else
00281   {
00282     for (ACE_Message_Block* mb = &this->message_block_;
00283          (mb != 0) && (bytes_transferred > 0);
00284          mb = mb->cont ())
00285     {
00286       size_t len_part = mb->space ();
00287 
00288       if (len_part > bytes_transferred)
00289         len_part = bytes_transferred;
00290 
00291       mb->wr_ptr (len_part);
00292 
00293       bytes_transferred -= len_part;
00294     }
00295   }
00296 
00297   // Create the interface result class.
00298   ACE_Asynch_Read_Stream::Result result (this);
00299 
00300   // Call the application handler.
00301   ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
00302   if (handler != 0)
00303     handler->handle_read_stream (result);
00304 }
00305 
00306 ACE_WIN32_Asynch_Read_Stream_Result::~ACE_WIN32_Asynch_Read_Stream_Result (void)
00307 {
00308 }
00309 
00310 // Base class operations. These operations are here to kill dominance
00311 // warnings. These methods call the base class methods.
00312 
00313 size_t
00314 ACE_WIN32_Asynch_Read_Stream_Result::bytes_transferred (void) const
00315 {
00316   return ACE_WIN32_Asynch_Result::bytes_transferred ();
00317 }
00318 
00319 const void *
00320 ACE_WIN32_Asynch_Read_Stream_Result::act (void) const
00321 {
00322   return ACE_WIN32_Asynch_Result::act ();
00323 }
00324 
00325 int
00326 ACE_WIN32_Asynch_Read_Stream_Result::success (void) const
00327 {
00328   return ACE_WIN32_Asynch_Result::success ();
00329 }
00330 
00331 const void *
00332 ACE_WIN32_Asynch_Read_Stream_Result::completion_key (void) const
00333 {
00334   return ACE_WIN32_Asynch_Result::completion_key ();
00335 }
00336 
00337 u_long
00338 ACE_WIN32_Asynch_Read_Stream_Result::error (void) const
00339 {
00340   return ACE_WIN32_Asynch_Result::error ();
00341 }
00342 
00343 ACE_HANDLE
00344 ACE_WIN32_Asynch_Read_Stream_Result::event (void) const
00345 {
00346   return ACE_WIN32_Asynch_Result::event ();
00347 }
00348 
00349 u_long
00350 ACE_WIN32_Asynch_Read_Stream_Result::offset (void) const
00351 {
00352   return ACE_WIN32_Asynch_Result::offset ();
00353 }
00354 
00355 u_long
00356 ACE_WIN32_Asynch_Read_Stream_Result::offset_high (void) const
00357 {
00358   return ACE_WIN32_Asynch_Result::offset_high ();
00359 }
00360 
00361 int
00362 ACE_WIN32_Asynch_Read_Stream_Result::priority (void) const
00363 {
00364   return ACE_WIN32_Asynch_Result::priority ();
00365 }
00366 
00367 int
00368 ACE_WIN32_Asynch_Read_Stream_Result::signal_number (void) const
00369 {
00370   return ACE_WIN32_Asynch_Result::signal_number ();
00371 }
00372 
00373 int
00374 ACE_WIN32_Asynch_Read_Stream_Result::post_completion (ACE_Proactor_Impl *proactor)
00375 {
00376   return ACE_WIN32_Asynch_Result::post_completion (proactor);
00377 }
00378 
00379 int
00380 ACE_WIN32_Asynch_Read_Stream_Result::scatter_enabled (void) const
00381 {
00382   return this->scatter_enabled_;
00383 }
00384 
00385 ACE_WIN32_Asynch_Read_Stream::ACE_WIN32_Asynch_Read_Stream (ACE_WIN32_Proactor *win32_proactor)
00386   : ACE_Asynch_Operation_Impl (),
00387     ACE_Asynch_Read_Stream_Impl (),
00388     ACE_WIN32_Asynch_Operation (win32_proactor)
00389 {
00390 }
00391 
00392 int
00393 ACE_WIN32_Asynch_Read_Stream::read (ACE_Message_Block &message_block,
00394                                     size_t bytes_to_read,
00395                                     const void *act,
00396                                     int priority,
00397                                     int signal_number)
00398 {
00399   size_t space = message_block.space ();
00400   if (bytes_to_read > space)
00401     bytes_to_read = space;
00402 
00403   if (bytes_to_read == 0)
00404     {
00405       errno = ENOSPC;
00406       return -1;
00407     }
00408 
00409   // Create the Asynch_Result.
00410   ACE_WIN32_Asynch_Read_Stream_Result *result = 0;
00411   ACE_NEW_RETURN (result,
00412                   ACE_WIN32_Asynch_Read_Stream_Result (this->handler_proxy_,
00413                                                        this->handle_,
00414                                                        message_block,
00415                                                        bytes_to_read,
00416                                                        act,
00417                                                        this->win32_proactor_->get_handle (),
00418                                                        priority,
00419                                                        signal_number),
00420                   -1);
00421 
00422   // Shared read
00423   int const return_val = this->shared_read (result);
00424 
00425   // Upon errors
00426   if (return_val == -1)
00427     delete result;
00428 
00429   return return_val;
00430 }
00431 
00432 int
00433 ACE_WIN32_Asynch_Read_Stream::readv (ACE_Message_Block &message_block,
00434                                      size_t bytes_to_read,
00435                                      const void *act,
00436                                      int priority,
00437                                      int signal_number)
00438 {
00439 #if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
00440   iovec  iov[ACE_IOV_MAX];
00441   int    iovcnt = 0;
00442 
00443   // We should not read more than user requested,
00444   // but it is allowed to read less
00445 
00446   for (const ACE_Message_Block* msg = &message_block;
00447        msg != 0 && bytes_to_read > 0 && iovcnt < ACE_IOV_MAX;
00448        msg = msg->cont () , ++iovcnt )
00449   {
00450     size_t msg_space = msg->space ();
00451 
00452     // OS should correctly process zero length buffers
00453     // if ( msg_space == 0 )
00454     //   ACE_ERROR_RETURN ((LM_ERROR,
00455     //                      ACE_TEXT ("ACE_WIN32_Asynch_Read_Stream::readv:")
00456     //                      ACE_TEXT ("No space in the message block\n")),
00457     //                     -1);
00458 
00459     if (msg_space > bytes_to_read)
00460       msg_space = bytes_to_read;
00461     bytes_to_read -= msg_space;
00462 
00463     // Make as many iovec as needed to fit all of msg_space.
00464     size_t wr_ptr_offset = 0;
00465     while (msg_space > 0 && iovcnt < ACE_IOV_MAX)
00466       {
00467         u_long this_chunk_length;
00468         if (msg_space > ULONG_MAX)
00469           this_chunk_length = ULONG_MAX;
00470         else
00471           this_chunk_length = static_cast<u_long> (msg_space);
00472         // Collect the data in the iovec.
00473         iov[iovcnt].iov_base = msg->wr_ptr () + wr_ptr_offset;
00474         iov[iovcnt].iov_len  = this_chunk_length;
00475         msg_space -= this_chunk_length;
00476         wr_ptr_offset += this_chunk_length;
00477 
00478         // Increment iovec counter if there's more to do.
00479         if (msg_space > 0)
00480           ++iovcnt;
00481       }
00482     if (msg_space > 0)       // Ran out of iovecs before msg_space exhausted
00483       {
00484         errno = ERANGE;
00485         return -1;
00486       }
00487   }
00488 
00489   // Re-calculate number bytes to read
00490   bytes_to_read = 0;
00491 
00492   for (int i = 0; i < iovcnt ; ++i)
00493     bytes_to_read += iov[i].iov_len;
00494 
00495   if (bytes_to_read == 0)
00496       ACE_ERROR_RETURN ((LM_ERROR,
00497                          ACE_TEXT ("ACE_WIN32_Asynch_Read_Stream::readv:")
00498                          ACE_TEXT ("Attempt to read 0 bytes\n")),
00499                         -1);
00500 
00501   // Create the Asynch_Result.
00502   ACE_WIN32_Asynch_Read_Stream_Result *result = 0;
00503   ACE_NEW_RETURN (result,
00504                   ACE_WIN32_Asynch_Read_Stream_Result (this->handler_proxy_,
00505                                                        this->handle_,
00506                                                        message_block,
00507                                                        bytes_to_read,
00508                                                        act,
00509                                                        this->win32_proactor_->get_handle (),
00510                                                        priority,
00511                                                        signal_number,
00512                                                        1), // scatter read enabled
00513                   -1);
00514 
00515   // do the scatter recv
00516 
00517   result->set_error (0); // Clear error before starting IO.
00518 
00519   DWORD bytes_recvd = 0;
00520   u_long flags = 0;
00521 
00522   int initiate_result = ::WSARecv (reinterpret_cast<SOCKET> (result->handle ()),
00523                                    reinterpret_cast<WSABUF *> (iov),
00524                                    iovcnt,
00525                                    &bytes_recvd,
00526                                    &flags,
00527                                    result,
00528                                    0);
00529 
00530   if (0 == initiate_result)
00531     // Immediate success: the OVERLAPPED will still get queued.
00532     return 1;
00533 
00534   ACE_ASSERT (initiate_result == SOCKET_ERROR);
00535 
00536   // If initiate failed, check for a bad error.
00537   ACE_OS::set_errno_to_last_error ();
00538   switch (errno)
00539   {
00540     case ERROR_IO_PENDING:
00541       // The IO will complete proactively: the OVERLAPPED will still
00542       // get queued.
00543       initiate_result = 0;
00544       break;
00545 
00546     default:
00547       // Something else went wrong: the OVERLAPPED will not get
00548       // queued.
00549 
00550       if (ACE::debug ())
00551       {
00552         ACE_DEBUG ((LM_ERROR,
00553                     ACE_TEXT ("%p\n"),
00554                     ACE_TEXT ("WSARecv")));
00555       }
00556 
00557       delete result;
00558       initiate_result = -1;
00559       break;
00560   }
00561 
00562   return initiate_result;
00563 #else
00564   ACE_UNUSED_ARG (message_block);
00565   ACE_UNUSED_ARG (bytes_to_read);
00566   ACE_UNUSED_ARG (act);
00567   ACE_UNUSED_ARG (priority);
00568   ACE_UNUSED_ARG (signal_number);
00569   ACE_NOTSUP_RETURN (-1);
00570 #endif /* ACE_HAS_WINSOCK2 && ACE_HAS_WINSOCK2 != 0 */
00571 }
00572 
00573 ACE_WIN32_Asynch_Read_Stream::~ACE_WIN32_Asynch_Read_Stream (void)
00574 {
00575 }
00576 
00577 int
00578 ACE_WIN32_Asynch_Read_Stream::shared_read (ACE_WIN32_Asynch_Read_Stream_Result *result)
00579 {
00580   // ReadFile API limits us to DWORD range.
00581   if (result->bytes_to_read () > MAXDWORD)
00582     {
00583       errno = ERANGE;
00584       return -1;
00585     }
00586   DWORD bytes_to_read = static_cast<DWORD> (result->bytes_to_read ());
00587   u_long bytes_read;
00588 
00589   result->set_error (0); // Clear error before starting IO.
00590 
00591   // Initiate the read
00592   int initiate_result = ::ReadFile (result->handle (),
00593                                     result->message_block ().wr_ptr (),
00594                                     bytes_to_read,
00595                                     &bytes_read,
00596                                     result);
00597   if (initiate_result == 1)
00598     // Immediate success: the OVERLAPPED will still get queued.
00599     return 0;
00600 
00601   // If initiate failed, check for a bad error.
00602   ACE_OS::set_errno_to_last_error ();
00603   switch (errno)
00604     {
00605     case ERROR_IO_PENDING:
00606       /* FALLTHRU */
00607     case ERROR_MORE_DATA:
00608       // The IO will complete proactively: the OVERLAPPED will still
00609       // get queued.
00610       return 0;
00611 
00612     default:
00613       // Something else went wrong: the OVERLAPPED will not get
00614       // queued.
00615 
00616       if (ACE::debug ())
00617         {
00618           ACE_DEBUG ((LM_ERROR,
00619                       ACE_TEXT ("%p\n"),
00620                       ACE_TEXT ("ReadFile")));
00621         }
00622 
00623       return -1;
00624     }
00625 }
00626 
00627 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
00628 // methods are defined here to avoid VC++ warnings. They route the
00629 // call to the ACE_WIN32_Asynch_Operation base class.
00630 
00631 int
00632 ACE_WIN32_Asynch_Read_Stream::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
00633                                     ACE_HANDLE handle,
00634                                     const void *completion_key,
00635                                     ACE_Proactor *proactor)
00636 {
00637   return ACE_WIN32_Asynch_Operation::open (handler_proxy,
00638                                            handle,
00639                                            completion_key,
00640                                            proactor);
00641 }
00642 
00643 int
00644 ACE_WIN32_Asynch_Read_Stream::cancel (void)
00645 {
00646   return ACE_WIN32_Asynch_Operation::cancel ();
00647 }
00648 
00649 ACE_Proactor *
00650 ACE_WIN32_Asynch_Read_Stream::proactor (void) const
00651 {
00652   return ACE_WIN32_Asynch_Operation::proactor ();
00653 }
00654 
00655 size_t
00656 ACE_WIN32_Asynch_Write_Stream_Result::bytes_to_write (void) const
00657 {
00658   return this->bytes_to_write_;
00659 }
00660 
00661 ACE_Message_Block &
00662 ACE_WIN32_Asynch_Write_Stream_Result::message_block (void) const
00663 {
00664   return this->message_block_;
00665 }
00666 
00667 ACE_HANDLE
00668 ACE_WIN32_Asynch_Write_Stream_Result::handle (void) const
00669 {
00670   return this->handle_;
00671 }
00672 
00673 ACE_WIN32_Asynch_Write_Stream_Result::ACE_WIN32_Asynch_Write_Stream_Result (
00674   const ACE_Handler::Proxy_Ptr &handler_proxy,
00675   ACE_HANDLE handle,
00676   ACE_Message_Block &message_block,
00677   size_t bytes_to_write,
00678   const void* act,
00679   ACE_HANDLE event,
00680   int priority,
00681   int signal_number,
00682   int gather_enabled)
00683   : ACE_Asynch_Result_Impl (),
00684     ACE_Asynch_Write_Stream_Result_Impl (),
00685     ACE_WIN32_Asynch_Result
00686       (handler_proxy, act, event, 0, 0, priority, signal_number),
00687     bytes_to_write_ (bytes_to_write),
00688     message_block_ (message_block),
00689     handle_ (handle),
00690     gather_enabled_ (gather_enabled)
00691 {
00692 }
00693 
00694 void
00695 ACE_WIN32_Asynch_Write_Stream_Result::complete (size_t bytes_transferred,
00696                                                 int success,
00697                                                 const void *completion_key,
00698                                                 u_long error)
00699 {
00700   // Copy the data which was returned by <GetQueuedCompletionStatus>.
00701   this->bytes_transferred_ = bytes_transferred;
00702   this->success_ = success;
00703   this->completion_key_ = completion_key;
00704   this->error_ = error;
00705 
00706   // Appropriately move the pointers in the message block.
00707   if (!this->gather_enabled ())
00708     this->message_block_.rd_ptr (bytes_transferred);
00709   else
00710   {
00711     for (ACE_Message_Block* mb = &this->message_block_;
00712          (mb != 0) && (bytes_transferred > 0);
00713          mb = mb->cont ())
00714     {
00715       size_t len_part = mb->length ();
00716 
00717       if ( len_part > bytes_transferred)
00718         len_part = bytes_transferred;
00719 
00720       mb->rd_ptr (len_part);
00721 
00722       bytes_transferred -= len_part;
00723     }
00724   }
00725 
00726   // Create the interface result class.
00727   ACE_Asynch_Write_Stream::Result result (this);
00728 
00729   // Call the application handler.
00730   ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
00731   if (handler != 0)
00732     handler->handle_write_stream (result);
00733 }
00734 
00735 ACE_WIN32_Asynch_Write_Stream_Result::~ACE_WIN32_Asynch_Write_Stream_Result (void)
00736 {
00737 }
00738 
00739 // Base class operations. These operations are here to kill dominance
00740 // warnings. These methods call the base class methods.
00741 
00742 size_t
00743 ACE_WIN32_Asynch_Write_Stream_Result::bytes_transferred (void) const
00744 {
00745   return ACE_WIN32_Asynch_Result::bytes_transferred ();
00746 }
00747 
00748 const void *
00749 ACE_WIN32_Asynch_Write_Stream_Result::act (void) const
00750 {
00751   return ACE_WIN32_Asynch_Result::act ();
00752 }
00753 
00754 int
00755 ACE_WIN32_Asynch_Write_Stream_Result::success (void) const
00756 {
00757   return ACE_WIN32_Asynch_Result::success ();
00758 }
00759 
00760 const void *
00761 ACE_WIN32_Asynch_Write_Stream_Result::completion_key (void) const
00762 {
00763   return ACE_WIN32_Asynch_Result::completion_key ();
00764 }
00765 
00766 u_long
00767 ACE_WIN32_Asynch_Write_Stream_Result::error (void) const
00768 {
00769   return ACE_WIN32_Asynch_Result::error ();
00770 }
00771 
00772 ACE_HANDLE
00773 ACE_WIN32_Asynch_Write_Stream_Result::event (void) const
00774 {
00775   return ACE_WIN32_Asynch_Result::event ();
00776 }
00777 
00778 u_long
00779 ACE_WIN32_Asynch_Write_Stream_Result::offset (void) const
00780 {
00781   return ACE_WIN32_Asynch_Result::offset ();
00782 }
00783 
00784 u_long
00785 ACE_WIN32_Asynch_Write_Stream_Result::offset_high (void) const
00786 {
00787   return ACE_WIN32_Asynch_Result::offset_high ();
00788 }
00789 
00790 int
00791 ACE_WIN32_Asynch_Write_Stream_Result::priority (void) const
00792 {
00793   return ACE_WIN32_Asynch_Result::priority ();
00794 }
00795 
00796 int
00797 ACE_WIN32_Asynch_Write_Stream_Result::signal_number (void) const
00798 {
00799   return ACE_WIN32_Asynch_Result::signal_number ();
00800 }
00801 
00802 int
00803 ACE_WIN32_Asynch_Write_Stream_Result::post_completion (ACE_Proactor_Impl *proactor)
00804 {
00805   return ACE_WIN32_Asynch_Result::post_completion (proactor);
00806 }
00807 
00808 int
00809 ACE_WIN32_Asynch_Write_Stream_Result::gather_enabled (void) const
00810 {
00811   return this->gather_enabled_;
00812 }
00813 
00814 ACE_WIN32_Asynch_Write_Stream::ACE_WIN32_Asynch_Write_Stream (ACE_WIN32_Proactor *win32_proactor)
00815   : ACE_Asynch_Operation_Impl (),
00816     ACE_Asynch_Write_Stream_Impl (),
00817     ACE_WIN32_Asynch_Operation (win32_proactor)
00818 {
00819 }
00820 
00821 int
00822 ACE_WIN32_Asynch_Write_Stream::write (ACE_Message_Block &message_block,
00823                                       size_t bytes_to_write,
00824                                       const void *act,
00825                                       int priority,
00826                                       int signal_number)
00827 {
00828   size_t len = message_block.length();
00829 
00830   if (bytes_to_write > len)
00831      bytes_to_write = len ;
00832 
00833   if (bytes_to_write == 0)
00834     ACE_ERROR_RETURN
00835       ((LM_ERROR,
00836         ACE_TEXT ("ACE_WIN32_Asynch_Write_Stream::write:")
00837         ACE_TEXT ("Attempt to write 0 bytes\n")),
00838        -1);
00839 
00840   ACE_WIN32_Asynch_Write_Stream_Result *result = 0;
00841   ACE_NEW_RETURN (result,
00842                   ACE_WIN32_Asynch_Write_Stream_Result (this->handler_proxy_,
00843                                                         this->handle_,
00844                                                         message_block,
00845                                                         bytes_to_write,
00846                                                         act,
00847                                                         this->win32_proactor_->get_handle (),
00848                                                         priority,
00849                                                         signal_number),
00850                   -1);
00851 
00852   // Shared write
00853   int return_val = this->shared_write (result);
00854 
00855   // Upon errors
00856   if (return_val == -1)
00857     delete result;
00858 
00859   return return_val;
00860 }
00861 
00862 int
00863 ACE_WIN32_Asynch_Write_Stream::writev (ACE_Message_Block &message_block,
00864                                        size_t bytes_to_write,
00865                                        const void *act,
00866                                        int priority,
00867                                        int signal_number)
00868 {
00869 #if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
00870   iovec  iov[ACE_IOV_MAX];
00871   int    iovcnt = 0;
00872 
00873   // We should not write more than user requested,
00874   // but it is allowed to write less
00875 
00876   for (const ACE_Message_Block* msg = &message_block;
00877        msg != 0 && bytes_to_write > 0 && iovcnt < ACE_IOV_MAX;
00878        msg = msg->cont ())
00879   {
00880     size_t msg_len = msg->length ();
00881 
00882     // Skip 0-length blocks.
00883     if (msg_len == 0)
00884       continue;
00885     if (msg_len > bytes_to_write)
00886       msg_len = bytes_to_write;
00887     bytes_to_write -= msg_len;
00888 
00889     // Make as many iovec as needed to fit all of msg_len.
00890     size_t rd_ptr_offset = 0;
00891     while (msg_len > 0 && iovcnt < ACE_IOV_MAX)
00892       {
00893         u_long this_chunk_length;
00894         if (msg_len > ULONG_MAX)
00895           this_chunk_length = ULONG_MAX;
00896         else
00897           this_chunk_length = static_cast<u_long> (msg_len);
00898         // Collect the data in the iovec.
00899         iov[iovcnt].iov_base = msg->rd_ptr () + rd_ptr_offset;
00900         iov[iovcnt].iov_len  = this_chunk_length;
00901         msg_len -= this_chunk_length;
00902         rd_ptr_offset += this_chunk_length;
00903 
00904         // Increment iovec counter if there's more to do.
00905         if (msg_len > 0)
00906           iovcnt++;
00907       }
00908     if (msg_len > 0)       // Ran out of iovecs before msg_space exhausted
00909       {
00910         errno = ERANGE;
00911         return -1;
00912       }
00913     ++iovcnt;
00914   }
00915 
00916   // Re-calculate number bytes to write
00917   bytes_to_write = 0;
00918 
00919   for ( int i=0; i < iovcnt ; ++i )
00920     bytes_to_write += iov[i].iov_len;
00921 
00922   if ( bytes_to_write == 0 )
00923       ACE_ERROR_RETURN ((LM_ERROR,
00924                          ACE_TEXT ("ACE_WIN32_Asynch_Write_Stream::writev:")
00925                          ACE_TEXT ("Attempt to write 0 bytes\n")),
00926                         -1);
00927 
00928 
00929   ACE_WIN32_Asynch_Write_Stream_Result *result = 0;
00930   ACE_NEW_RETURN (result,
00931                   ACE_WIN32_Asynch_Write_Stream_Result (this->handler_proxy_,
00932                                                         this->handle_,
00933                                                         message_block,
00934                                                         bytes_to_write,
00935                                                         act,
00936                                                         this->win32_proactor_->get_handle (),
00937                                                         priority,
00938                                                         signal_number,
00939                                                         1), // gather write enabled
00940                   -1);
00941 
00942   // do the gather send
00943 
00944   u_long bytes_sent = 0;
00945 
00946   int initiate_result = ::WSASend (reinterpret_cast<SOCKET> (result->handle ()),
00947                                    reinterpret_cast<WSABUF *> (iov),
00948                                    iovcnt,
00949                                    &bytes_sent,
00950                                    0, // flags
00951                                    result,
00952                                    0);
00953 
00954   if (0 == initiate_result)
00955     // Immediate success: the OVERLAPPED will still get queued.
00956     return 1;
00957 
00958   ACE_ASSERT (initiate_result == SOCKET_ERROR);
00959 
00960   // If initiate failed, check for a bad error.
00961   ACE_OS::set_errno_to_last_error ();
00962   switch (errno)
00963   {
00964     case ERROR_IO_PENDING:
00965       // The IO will complete proactively: the OVERLAPPED will still
00966       // get queued.
00967       initiate_result = 0;
00968       break;
00969 
00970     default:
00971       // Something else went wrong: the OVERLAPPED will not get
00972       // queued.
00973 
00974       if (ACE::debug ())
00975       {
00976         ACE_DEBUG ((LM_ERROR,
00977                     ACE_TEXT ("%p\n"),
00978                     ACE_TEXT ("WSASend")));
00979       }
00980 
00981       delete result;
00982       initiate_result = -1;
00983       break;
00984   }
00985 
00986   return initiate_result;
00987 #else
00988   ACE_UNUSED_ARG (message_block);
00989   ACE_UNUSED_ARG (bytes_to_write);
00990   ACE_UNUSED_ARG (act);
00991   ACE_UNUSED_ARG (priority);
00992   ACE_UNUSED_ARG (signal_number);
00993   ACE_NOTSUP_RETURN (-1);
00994 #endif /* ACE_HAS_WINSOCK2 && ACE_HAS_WINSOCK2 != 0 */
00995 }
00996 
00997 ACE_WIN32_Asynch_Write_Stream::~ACE_WIN32_Asynch_Write_Stream (void)
00998 {
00999 }
01000 
01001 int
01002 ACE_WIN32_Asynch_Write_Stream::shared_write (ACE_WIN32_Asynch_Write_Stream_Result *result)
01003 {
01004   u_long bytes_written;
01005   if (result->bytes_to_write () > MAXDWORD)
01006     {
01007       errno = ERANGE;
01008       return -1;
01009     }
01010   DWORD bytes_to_write = static_cast<DWORD> (result->bytes_to_write ());
01011 
01012   result->set_error (0); // Clear error before starting IO.
01013 
01014   // Initiate the write
01015   int initiate_result = ::WriteFile (result->handle (),
01016                                      result->message_block ().rd_ptr (),
01017                                      bytes_to_write,
01018                                      &bytes_written,
01019                                      result);
01020   if (initiate_result == 1)
01021     // Immediate success: the OVERLAPPED will still get queued.
01022     return 0;
01023 
01024   // If initiate failed, check for a bad error.
01025   ACE_OS::set_errno_to_last_error ();
01026   switch (errno)
01027     {
01028     case ERROR_IO_PENDING:
01029       // The IO will complete proactively: the OVERLAPPED will still
01030       // get queued.
01031       return 0;
01032 
01033     default:
01034       // Something else went wrong: the OVERLAPPED will not get
01035       // queued.
01036 
01037       if (ACE::debug ())
01038         ACE_DEBUG ((LM_ERROR,
01039                     ACE_TEXT ("%p\n"),
01040                     ACE_TEXT ("WriteFile")));
01041       return -1;
01042     }
01043 }
01044 
01045 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
01046 // methods are defined here to avoid VC++ warnings. They route the
01047 // call to the ACE_WIN32_Asynch_Operation base class.
01048 
01049 int
01050 ACE_WIN32_Asynch_Write_Stream::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
01051                                      ACE_HANDLE handle,
01052                                      const void *completion_key,
01053                                      ACE_Proactor *proactor)
01054 {
01055   return ACE_WIN32_Asynch_Operation::open (handler_proxy,
01056                                            handle,
01057                                            completion_key,
01058                                            proactor);
01059 }
01060 
01061 int
01062 ACE_WIN32_Asynch_Write_Stream::cancel (void)
01063 {
01064   return ACE_WIN32_Asynch_Operation::cancel ();
01065 }
01066 
01067 ACE_Proactor *
01068 ACE_WIN32_Asynch_Write_Stream::proactor (void) const
01069 {
01070   return ACE_WIN32_Asynch_Operation::proactor ();
01071 }
01072 
01073 ACE_WIN32_Asynch_Read_File_Result::ACE_WIN32_Asynch_Read_File_Result (
01074   const ACE_Handler::Proxy_Ptr &handler_proxy,
01075   ACE_HANDLE handle,
01076   ACE_Message_Block &message_block,
01077   size_t bytes_to_read,
01078   const void* act,
01079   u_long offset,
01080   u_long offset_high,
01081   ACE_HANDLE event,
01082   int priority,
01083   int signal_number,
01084   int scatter_enabled)
01085   : ACE_Asynch_Result_Impl (),
01086     ACE_Asynch_Read_Stream_Result_Impl (),
01087     ACE_Asynch_Read_File_Result_Impl (),
01088     ACE_WIN32_Asynch_Read_Stream_Result (handler_proxy,
01089                                          handle,
01090                                          message_block,
01091                                          bytes_to_read,
01092                                          act,
01093                                          event,
01094                                          priority,
01095                                          signal_number,
01096                                          scatter_enabled)
01097 {
01098   this->Offset = offset;
01099   this->OffsetHigh = offset_high;
01100 }
01101 
01102 void
01103 ACE_WIN32_Asynch_Read_File_Result::complete (size_t bytes_transferred,
01104                                              int success,
01105                                              const void *completion_key,
01106                                              u_long error)
01107 {
01108   // Copy the data which was returned by GetQueuedCompletionStatus.
01109   this->bytes_transferred_ = bytes_transferred;
01110   this->success_ = success;
01111   this->completion_key_ = completion_key;
01112   this->error_ = error;
01113 
01114   // Appropriately move the pointers in the message block.
01115   if (!this->scatter_enabled ())
01116     this->message_block_.wr_ptr (bytes_transferred);
01117   else
01118   {
01119     static const size_t page_size = ACE_OS::getpagesize();
01120 
01121     for (ACE_Message_Block* mb = &this->message_block_;
01122          (mb != 0) && (bytes_transferred > 0);
01123          mb = mb->cont ())
01124     {
01125       // mb->space () is ought to be >= page_size.
01126       // this is verified in the readv method
01127       // ACE_ASSERT (mb->space () >= page_size);
01128 
01129       size_t len_part = page_size ;
01130 
01131       if ( len_part > bytes_transferred)
01132         len_part = bytes_transferred;
01133 
01134       mb->wr_ptr (len_part);
01135 
01136       bytes_transferred -= len_part;
01137     }
01138   }
01139 
01140   // Create the interface result class.
01141   ACE_Asynch_Read_File::Result result (this);
01142 
01143   // Call the application handler.
01144   ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
01145   if (handler != 0)
01146     handler->handle_read_file (result);
01147 }
01148 
01149 ACE_WIN32_Asynch_Read_File_Result::~ACE_WIN32_Asynch_Read_File_Result (void)
01150 {
01151 }
01152 
01153 // Base class operations. These operations are here to kill dominance
01154 // warnings. These methods call the base class methods.
01155 
01156 size_t
01157 ACE_WIN32_Asynch_Read_File_Result::bytes_transferred (void) const
01158 {
01159   return ACE_WIN32_Asynch_Result::bytes_transferred ();
01160 }
01161 
01162 const void *
01163 ACE_WIN32_Asynch_Read_File_Result::act (void) const
01164 {
01165   return ACE_WIN32_Asynch_Result::act ();
01166 }
01167 
01168 int
01169 ACE_WIN32_Asynch_Read_File_Result::success (void) const
01170 {
01171   return ACE_WIN32_Asynch_Result::success ();
01172 }
01173 
01174 const void *
01175 ACE_WIN32_Asynch_Read_File_Result::completion_key (void) const
01176 {
01177   return ACE_WIN32_Asynch_Result::completion_key ();
01178 }
01179 
01180 u_long
01181 ACE_WIN32_Asynch_Read_File_Result::error (void) const
01182 {
01183   return ACE_WIN32_Asynch_Result::error ();
01184 }
01185 
01186 ACE_HANDLE
01187 ACE_WIN32_Asynch_Read_File_Result::event (void) const
01188 {
01189   return ACE_WIN32_Asynch_Result::event ();
01190 }
01191 
01192 u_long
01193 ACE_WIN32_Asynch_Read_File_Result::offset (void) const
01194 {
01195   return ACE_WIN32_Asynch_Result::offset ();
01196 }
01197 
01198 u_long
01199 ACE_WIN32_Asynch_Read_File_Result::offset_high (void) const
01200 {
01201   return ACE_WIN32_Asynch_Result::offset_high ();
01202 }
01203 
01204 int
01205 ACE_WIN32_Asynch_Read_File_Result::priority (void) const
01206 {
01207   return ACE_WIN32_Asynch_Result::priority ();
01208 }
01209 
01210 int
01211 ACE_WIN32_Asynch_Read_File_Result::signal_number (void) const
01212 {
01213   return ACE_WIN32_Asynch_Result::signal_number ();
01214 }
01215 
01216 // The following methods belong to
01217 // ACE_WIN32_Asynch_Read_Stream_Result. They are here to avoid VC++
01218 // warnings. These methods route their call to the
01219 // ACE_WIN32_Asynch_Read_Stream_Result base class.
01220 
01221 size_t
01222 ACE_WIN32_Asynch_Read_File_Result::bytes_to_read (void) const
01223 {
01224   return ACE_WIN32_Asynch_Read_Stream_Result::bytes_to_read ();
01225 }
01226 
01227 ACE_Message_Block &
01228 ACE_WIN32_Asynch_Read_File_Result::message_block (void) const
01229 {
01230   return ACE_WIN32_Asynch_Read_Stream_Result::message_block ();
01231 }
01232 
01233 ACE_HANDLE
01234 ACE_WIN32_Asynch_Read_File_Result::handle (void) const
01235 {
01236   return ACE_WIN32_Asynch_Read_Stream_Result::handle ();
01237 }
01238 
01239 int
01240 ACE_WIN32_Asynch_Read_File_Result::post_completion (ACE_Proactor_Impl *proactor)
01241 {
01242   return ACE_WIN32_Asynch_Result::post_completion (proactor);
01243 }
01244 
01245 // ************************************************************
01246 
01247 ACE_WIN32_Asynch_Read_File::ACE_WIN32_Asynch_Read_File (ACE_WIN32_Proactor *win32_proactor)
01248   : ACE_Asynch_Operation_Impl (),
01249     ACE_Asynch_Read_Stream_Impl (),
01250     ACE_Asynch_Read_File_Impl (),
01251     ACE_WIN32_Asynch_Read_Stream (win32_proactor)
01252 {
01253 }
01254 
01255 int
01256 ACE_WIN32_Asynch_Read_File::read (ACE_Message_Block &message_block,
01257                                   size_t bytes_to_read,
01258                                   u_long offset,
01259                                   u_long offset_high,
01260                                   const void *act,
01261                                   int priority,
01262                                   int signal_number)
01263 {
01264   size_t space = message_block.space ();
01265   if ( bytes_to_read > space )
01266     bytes_to_read = space;
01267 
01268   if ( bytes_to_read == 0 )
01269     ACE_ERROR_RETURN
01270       ((LM_ERROR,
01271         ACE_TEXT ("ACE_WIN32_Asynch_Read_File::read:")
01272         ACE_TEXT ("Attempt to read 0 bytes or no space in the message block\n")),
01273        -1);
01274 
01275 
01276   ACE_WIN32_Asynch_Read_File_Result *result = 0;
01277   ACE_NEW_RETURN (result,
01278                   ACE_WIN32_Asynch_Read_File_Result (this->handler_proxy_,
01279                                                      this->handle_,
01280                                                      message_block,
01281                                                      bytes_to_read,
01282                                                      act,
01283                                                      offset,
01284                                                      offset_high,
01285                                                      this->win32_proactor_->get_handle (),
01286                                                      priority,
01287                                                      signal_number),
01288                   -1);
01289 
01290   // Shared read
01291   int return_val = this->shared_read (result);
01292 
01293   // Upon errors
01294   if (return_val == -1)
01295     delete result;
01296 
01297   return return_val;
01298 }
01299 
01300 int
01301 ACE_WIN32_Asynch_Read_File::readv (ACE_Message_Block &message_block,
01302                                    size_t bytes_to_read,
01303                                    u_long offset,
01304                                    u_long offset_high,
01305                                    const void *act,
01306                                    int priority,
01307                                    int signal_number)
01308 {
01309 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO)
01310   static const size_t page_size = ACE_OS::getpagesize();
01311 
01312   FILE_SEGMENT_ELEMENT buffer_pointers[ACE_IOV_MAX + 1];
01313   int buffer_pointers_count = 0;
01314 
01315   // Each buffer must be at least the size of a system memory page
01316   // and must be aligned on a system memory page size boundary
01317 
01318   // We should not read more than user requested,
01319   // but it is allowed to read less
01320 
01321   size_t total_space = 0;
01322 
01323   for (const ACE_Message_Block* msg = &message_block;
01324        msg != 0 && buffer_pointers_count < ACE_IOV_MAX && total_space < bytes_to_read;
01325        msg = msg->cont(), ++buffer_pointers_count )
01326   {
01327     size_t msg_space = msg->space ();
01328 
01329     if (msg_space < page_size)
01330       ACE_ERROR_RETURN ((LM_ERROR,
01331                          ACE_TEXT ("ACE_WIN32_Asynch_Read_File::readv:")
01332                          ACE_TEXT ("Invalid message block size\n")),
01333                         -1);
01334 
01335     buffer_pointers[buffer_pointers_count].Buffer = msg->wr_ptr ();
01336     total_space += page_size;
01337   }
01338 
01339   // not read more than buffers space
01340   if (bytes_to_read > total_space)
01341     bytes_to_read = total_space;
01342 
01343   // ReadFileScatter API limits us to DWORD range.
01344   if (bytes_to_read > MAXDWORD)
01345     {
01346       errno = ERANGE;
01347       return -1;
01348     }
01349   DWORD dword_bytes_to_read = static_cast<DWORD> (bytes_to_read);
01350 
01351   // last one should be completely 0
01352   buffer_pointers[buffer_pointers_count].Buffer = 0;
01353 
01354   ACE_WIN32_Asynch_Read_File_Result *result = 0;
01355   ACE_NEW_RETURN (result,
01356                   ACE_WIN32_Asynch_Read_File_Result (this->handler_proxy_,
01357                                                      this->handle_,
01358                                                      message_block,
01359                                                      bytes_to_read,
01360                                                      act,
01361                                                      offset,
01362                                                      offset_high,
01363                                                      this->win32_proactor_->get_handle (),
01364                                                      priority,
01365                                                      signal_number,
01366                                                      1), // scatter read enabled
01367                   -1);
01368 
01369   // do the scatter read
01370   result->set_error (0); // Clear error before starting IO.
01371 
01372   int initiate_result = ::ReadFileScatter (result->handle (),
01373                                            buffer_pointers,
01374                                            dword_bytes_to_read,
01375                                            0, // reserved, must be NULL
01376                                            result);
01377 
01378   if (0 != initiate_result)
01379     // Immediate success: the OVERLAPPED will still get queued.
01380     return 1;
01381 
01382   // If initiate failed, check for a bad error.
01383   ACE_OS::set_errno_to_last_error ();
01384   switch (errno)
01385   {
01386     case ERROR_IO_PENDING:
01387       // The IO will complete proactively: the OVERLAPPED will still
01388       // get queued.
01389       initiate_result = 0;
01390       break;
01391 
01392     default:
01393       // Something else went wrong: the OVERLAPPED will not get
01394       // queued.
01395 
01396       if (ACE::debug ())
01397       {
01398         ACE_DEBUG ((LM_ERROR,
01399                     ACE_TEXT ("%p\n"),
01400                     ACE_TEXT ("ReadFileScatter")));
01401       }
01402 
01403       delete result;
01404       initiate_result = -1;
01405       break;
01406   }
01407 
01408   return initiate_result;
01409 #else
01410   ACE_NOTSUP_RETURN (-1);
01411 #endif /* ACE_WIN32_OVERLAPPED_IO */
01412 }
01413 
01414 
01415 ACE_WIN32_Asynch_Read_File::~ACE_WIN32_Asynch_Read_File (void)
01416 {
01417 }
01418 
01419 int
01420 ACE_WIN32_Asynch_Read_File::read (ACE_Message_Block &message_block,
01421                                   size_t bytes_to_read,
01422                                   const void *act,
01423                                   int priority,
01424                                   int signal_number)
01425 {
01426   return ACE_WIN32_Asynch_Read_Stream::read (message_block,
01427                                              bytes_to_read,
01428                                              act,
01429                                              priority,
01430                                              signal_number);
01431 }
01432 
01433 int
01434 ACE_WIN32_Asynch_Read_File::readv (ACE_Message_Block &message_block,
01435                                    size_t bytes_to_read,
01436                                    const void *act,
01437                                    int priority,
01438                                    int signal_number)
01439 {
01440   return ACE_WIN32_Asynch_Read_Stream::readv (message_block,
01441                                               bytes_to_read,
01442                                               act,
01443                                               priority,
01444                                               signal_number);
01445 }
01446 
01447 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
01448 // methods are defined here to avoid VC++ warnings. They route the
01449 // call to the ACE_WIN32_Asynch_Operation base class.
01450 
01451 int
01452 ACE_WIN32_Asynch_Read_File::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
01453                                   ACE_HANDLE handle,
01454                                   const void *completion_key,
01455                                   ACE_Proactor *proactor)
01456 {
01457   return ACE_WIN32_Asynch_Operation::open (handler_proxy,
01458                                            handle,
01459                                            completion_key,
01460                                            proactor);
01461 }
01462 
01463 int
01464 ACE_WIN32_Asynch_Read_File::cancel (void)
01465 {
01466   return ACE_WIN32_Asynch_Operation::cancel ();
01467 }
01468 
01469 ACE_Proactor *
01470 ACE_WIN32_Asynch_Read_File::proactor (void) const
01471 {
01472   return ACE_WIN32_Asynch_Operation::proactor ();
01473 }
01474 
01475 ACE_WIN32_Asynch_Write_File_Result::ACE_WIN32_Asynch_Write_File_Result (
01476   const ACE_Handler::Proxy_Ptr &handler_proxy,
01477   ACE_HANDLE handle,
01478   ACE_Message_Block &message_block,
01479   size_t bytes_to_write,
01480   const void* act,
01481   u_long offset,
01482   u_long offset_high,
01483   ACE_HANDLE event,
01484   int priority,
01485   int signal_number,
01486   int gather_enabled)
01487   : ACE_Asynch_Result_Impl (),
01488     ACE_Asynch_Write_Stream_Result_Impl (),
01489     ACE_Asynch_Write_File_Result_Impl (),
01490     ACE_WIN32_Asynch_Write_Stream_Result (handler_proxy,
01491                                           handle,
01492                                           message_block,
01493                                           bytes_to_write,
01494                                           act,
01495                                           event,
01496                                           priority,
01497                                           signal_number,
01498                                           gather_enabled)
01499 {
01500   this->Offset = offset;
01501   this->OffsetHigh = offset_high;
01502 }
01503 
01504 void
01505 ACE_WIN32_Asynch_Write_File_Result::complete (size_t bytes_transferred,
01506                                               int success,
01507                                               const void *completion_key,
01508                                               u_long error)
01509 {
01510   // Copy the data which was returned by GetQueuedCompletionStatus
01511   this->bytes_transferred_ = bytes_transferred;
01512   this->success_ = success;
01513   this->completion_key_ = completion_key;
01514   this->error_ = error;
01515 
01516   // Appropriately move the pointers in the message block.
01517   if (!this->gather_enabled ())
01518     this->message_block_.rd_ptr (bytes_transferred);
01519   else
01520   {
01521     static const size_t page_size = ACE_OS::getpagesize();
01522 
01523     for (ACE_Message_Block* mb = &this->message_block_;
01524          (mb != 0) && (bytes_transferred > 0);
01525          mb = mb->cont ())
01526     {
01527       // mb->length () is ought to be >= page_size.
01528       // this is verified in the writev method
01529       // ACE_ASSERT (mb->length () >= page_size);
01530 
01531       size_t len_part = page_size;
01532 
01533       if ( len_part > bytes_transferred)
01534         len_part = bytes_transferred;
01535 
01536       mb->rd_ptr (len_part);
01537 
01538       bytes_transferred -= len_part;
01539     }
01540 
01541   }
01542 
01543   // Create the interface result class.
01544   ACE_Asynch_Write_File::Result result (this);
01545 
01546   // Call the application handler.
01547   ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
01548   if (handler != 0)
01549     handler->handle_write_file (result);
01550 }
01551 
01552 ACE_WIN32_Asynch_Write_File_Result::~ACE_WIN32_Asynch_Write_File_Result  (void)
01553 {
01554 }
01555 
01556 // Base class operations. These operations are here to kill dominance
01557 // warnings. These methods call the base class methods.
01558 
01559 size_t
01560 ACE_WIN32_Asynch_Write_File_Result::bytes_transferred (void) const
01561 {
01562   return ACE_WIN32_Asynch_Result::bytes_transferred ();
01563 }
01564 
01565 const void *
01566 ACE_WIN32_Asynch_Write_File_Result::act (void) const
01567 {
01568   return ACE_WIN32_Asynch_Result::act ();
01569 }
01570 
01571 int
01572 ACE_WIN32_Asynch_Write_File_Result::success (void) const
01573 {
01574   return ACE_WIN32_Asynch_Result::success ();
01575 }
01576 
01577 const void *
01578 ACE_WIN32_Asynch_Write_File_Result::completion_key (void) const
01579 {
01580   return ACE_WIN32_Asynch_Result::completion_key ();
01581 }
01582 
01583 u_long
01584 ACE_WIN32_Asynch_Write_File_Result::error (void) const
01585 {
01586   return ACE_WIN32_Asynch_Result::error ();
01587 }
01588 
01589 ACE_HANDLE
01590 ACE_WIN32_Asynch_Write_File_Result::event (void) const
01591 {
01592   return ACE_WIN32_Asynch_Result::event ();
01593 }
01594 
01595 u_long
01596 ACE_WIN32_Asynch_Write_File_Result::offset (void) const
01597 {
01598   return ACE_WIN32_Asynch_Result::offset ();
01599 }
01600 
01601 u_long
01602 ACE_WIN32_Asynch_Write_File_Result::offset_high (void) const
01603 {
01604   return ACE_WIN32_Asynch_Result::offset_high ();
01605 }
01606 
01607 int
01608 ACE_WIN32_Asynch_Write_File_Result::priority (void) const
01609 {
01610   return ACE_WIN32_Asynch_Result::priority ();
01611 }
01612 
01613 int
01614 ACE_WIN32_Asynch_Write_File_Result::signal_number (void) const
01615 {
01616   return ACE_WIN32_Asynch_Result::signal_number ();
01617 }
01618 
01619 // The following methods belong to
01620 // ACE_WIN32_Asynch_Write_Stream_Result. They are here to avoid VC++
01621 // warnings. These methods route their call to the
01622 // ACE_WIN32_Asynch_Write_Stream_Result base class.
01623 
01624 size_t
01625 ACE_WIN32_Asynch_Write_File_Result::bytes_to_write (void) const
01626 {
01627   return ACE_WIN32_Asynch_Write_Stream_Result::bytes_to_write ();
01628 }
01629 
01630 ACE_Message_Block &
01631 ACE_WIN32_Asynch_Write_File_Result::message_block (void) const
01632 {
01633   return ACE_WIN32_Asynch_Write_Stream_Result::message_block ();
01634 }
01635 
01636 ACE_HANDLE
01637 ACE_WIN32_Asynch_Write_File_Result::handle (void) const
01638 {
01639   return ACE_WIN32_Asynch_Write_Stream_Result::handle ();
01640 }
01641 
01642 int
01643 ACE_WIN32_Asynch_Write_File_Result::post_completion (ACE_Proactor_Impl *proactor)
01644 {
01645   return ACE_WIN32_Asynch_Result::post_completion (proactor);
01646 }
01647 
01648 ACE_WIN32_Asynch_Write_File::ACE_WIN32_Asynch_Write_File (ACE_WIN32_Proactor *win32_proactor)
01649   : ACE_Asynch_Operation_Impl (),
01650     ACE_Asynch_Write_Stream_Impl (),
01651     ACE_Asynch_Write_File_Impl (),
01652     ACE_WIN32_Asynch_Write_Stream (win32_proactor)
01653 {
01654 }
01655 
01656 int
01657 ACE_WIN32_Asynch_Write_File::write (ACE_Message_Block &message_block,
01658                                     size_t bytes_to_write,
01659                                     u_long offset,
01660                                     u_long offset_high,
01661                                     const void *act,
01662                                     int priority,
01663                                     int signal_number)
01664 {
01665   size_t len = message_block.length ();
01666   if ( bytes_to_write > len )
01667      bytes_to_write = len;
01668 
01669   if ( bytes_to_write == 0 )
01670     ACE_ERROR_RETURN
01671       ((LM_ERROR,
01672         ACE_TEXT ("ACE_WIN32_Asynch_Write_File::write:")
01673         ACE_TEXT ("Attempt to read 0 bytes\n")),
01674        -1);
01675 
01676   ACE_WIN32_Asynch_Write_File_Result *result = 0;
01677   ACE_NEW_RETURN (result,
01678                   ACE_WIN32_Asynch_Write_File_Result (this->handler_proxy_,
01679                                                       this->handle_,
01680                                                       message_block,
01681                                                       bytes_to_write,
01682                                                       act,
01683                                                       offset,
01684                                                       offset_high,
01685                                                       this->win32_proactor_->get_handle (),
01686                                                       priority,
01687                                                       signal_number),
01688                   -1);
01689 
01690   // Shared write
01691   int return_val = this->shared_write (result);
01692 
01693   // Upon errors
01694   if (return_val == -1)
01695     delete result;
01696 
01697   return return_val;
01698 }
01699 
01700 int
01701 ACE_WIN32_Asynch_Write_File::writev (ACE_Message_Block &message_block,
01702                                      size_t bytes_to_write,
01703                                      u_long offset,
01704                                      u_long offset_high,
01705                                      const void *act,
01706                                      int priority,
01707                                      int signal_number)
01708 {
01709 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO)
01710   static const size_t page_size = ACE_OS::getpagesize();
01711 
01712   FILE_SEGMENT_ELEMENT buffer_pointers[ACE_IOV_MAX + 1];
01713   int buffer_pointers_count = 0;
01714 
01715   // Each buffer must be at least the size of a system memory page
01716   // and must be aligned on a system memory page size boundary
01717 
01718   // We should not read more than user requested,
01719   // but it is allowed to read less
01720 
01721   size_t total_len = 0;
01722 
01723   for (const ACE_Message_Block* msg = &message_block;
01724        msg != 0 && buffer_pointers_count < ACE_IOV_MAX && total_len < bytes_to_write;
01725        msg = msg->cont (), ++buffer_pointers_count )
01726   {
01727     size_t msg_len = msg->length ();
01728 
01729     // Don't allow writing less than page_size, unless
01730     // the size of the message block is big enough (so we don't write from
01731     // memory which does not belong to the message block), and the message
01732     // block is the last in the chain.
01733     if (msg_len < page_size &&
01734         (msg->size () - (msg->rd_ptr () - msg->base ()) < page_size || // message block too small
01735          bytes_to_write - total_len > page_size ))// NOT last chunk
01736       ACE_ERROR_RETURN ((LM_ERROR,
01737                          ACE_TEXT ("ACE_WIN32_Asynch_Write_File::writev:")
01738                          ACE_TEXT ("Invalid message block length\n")),
01739                         -1);
01740 
01741     buffer_pointers[buffer_pointers_count].Buffer = msg->rd_ptr ();
01742     total_len += page_size;
01743   }
01744 
01745   // not write more than we have in buffers
01746   if (bytes_to_write > total_len)
01747     bytes_to_write = total_len;
01748   // WriteFileGather API limits us to DWORD range.
01749   if (bytes_to_write > MAXDWORD)
01750     {
01751       errno = ERANGE;
01752       return -1;
01753     }
01754   DWORD dword_bytes_to_write = static_cast<DWORD> (bytes_to_write);
01755 
01756   // last one should be completely 0
01757   buffer_pointers[buffer_pointers_count].Buffer = 0;
01758 
01759   ACE_WIN32_Asynch_Write_File_Result *result = 0;
01760   ACE_NEW_RETURN (result,
01761                   ACE_WIN32_Asynch_Write_File_Result (this->handler_proxy_,
01762                                                       this->handle_,
01763                                                       message_block,
01764                                                       bytes_to_write,
01765                                                       act,
01766                                                       offset,
01767                                                       offset_high,
01768                                                       this->win32_proactor_->get_handle (),
01769                                                       priority,
01770                                                       signal_number,
01771                                                       1), // gather write enabled
01772                   -1);
01773 
01774   result->set_error(0);
01775 
01776   // do the gather write
01777   int initiate_result = ::WriteFileGather (result->handle (),
01778                                            buffer_pointers,
01779                                            dword_bytes_to_write,
01780                                            0, // reserved, must be NULL
01781                                            result);
01782 
01783   if (0 != initiate_result)
01784     // Immediate success: the OVERLAPPED will still get queued.
01785     return 1;
01786 
01787   // If initiate failed, check for a bad error.
01788   ACE_OS::set_errno_to_last_error ();
01789   switch (errno)
01790   {
01791     case ERROR_IO_PENDING:
01792       // The IO will complete proactively: the OVERLAPPED will still
01793       // get queued.
01794       initiate_result = 0;
01795       break;
01796 
01797     default:
01798       // Something else went wrong: the OVERLAPPED will not get
01799       // queued.
01800 
01801       if (ACE::debug ())
01802       {
01803         ACE_DEBUG ((LM_ERROR,
01804                     ACE_TEXT ("%p\n"),
01805                     ACE_TEXT ("WriteFileGather")));
01806       }
01807 
01808       delete result;
01809       initiate_result = -1;
01810       break;
01811   }
01812 
01813   return initiate_result;
01814 #else
01815 
01816   ACE_NOTSUP_RETURN (-1);
01817 
01818 #endif /* ACE_HAS_WIN32_OVERLAPPED_IO */
01819 }
01820 
01821 
01822 ACE_WIN32_Asynch_Write_File::~ACE_WIN32_Asynch_Write_File (void)
01823 {
01824 }
01825 
01826 int
01827 ACE_WIN32_Asynch_Write_File::write (ACE_Message_Block &message_block,
01828                                     size_t bytes_to_write,
01829                                     const void *act,
01830                                     int priority,
01831                                     int signal_number)
01832 {
01833   return ACE_WIN32_Asynch_Write_Stream::write (message_block,
01834                                                bytes_to_write,
01835                                                act,
01836                                                priority,
01837                                                signal_number);
01838 }
01839 
01840 int
01841 ACE_WIN32_Asynch_Write_File::writev (ACE_Message_Block &message_block,
01842                                      size_t bytes_to_write,
01843                                      const void *act,
01844                                      int priority,
01845                                      int signal_number)
01846 {
01847   return ACE_WIN32_Asynch_Write_Stream::writev (message_block,
01848                                                 bytes_to_write,
01849                                                 act,
01850                                                 priority,
01851                                                 signal_number);
01852 }
01853 
01854 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
01855 // methods are defined here to avoid VC++ warnings. They route the
01856 // call to the ACE_WIN32_Asynch_Operation base class.
01857 
01858 int
01859 ACE_WIN32_Asynch_Write_File::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
01860                                    ACE_HANDLE handle,
01861                                    const void *completion_key,
01862                                    ACE_Proactor *proactor)
01863 {
01864   return ACE_WIN32_Asynch_Operation::open (handler_proxy,
01865                                            handle,
01866                                            completion_key,
01867                                            proactor);
01868 }
01869 
01870 int
01871 ACE_WIN32_Asynch_Write_File::cancel (void)
01872 {
01873   return ACE_WIN32_Asynch_Operation::cancel ();
01874 }
01875 
01876 ACE_Proactor *
01877 ACE_WIN32_Asynch_Write_File::proactor (void) const
01878 {
01879   return ACE_WIN32_Asynch_Operation::proactor ();
01880 }
01881 
01882 size_t
01883 ACE_WIN32_Asynch_Accept_Result::bytes_to_read (void) const
01884 {
01885   return this->bytes_to_read_;
01886 }
01887 
01888 ACE_Message_Block &
01889 ACE_WIN32_Asynch_Accept_Result::message_block (void) const
01890 {
01891   return this->message_block_;
01892 }
01893 
01894 ACE_HANDLE
01895 ACE_WIN32_Asynch_Accept_Result::listen_handle (void) const
01896 {
01897   return this->listen_handle_;
01898 }
01899 
01900 ACE_HANDLE
01901 ACE_WIN32_Asynch_Accept_Result::accept_handle (void) const
01902 {
01903   return this->accept_handle_;
01904 }
01905 
01906 ACE_WIN32_Asynch_Accept_Result::ACE_WIN32_Asynch_Accept_Result (
01907   const ACE_Handler::Proxy_Ptr &handler_proxy,
01908   ACE_HANDLE listen_handle,
01909   ACE_HANDLE accept_handle,
01910   ACE_Message_Block &message_block,
01911   size_t bytes_to_read,
01912   const void* act,
01913   ACE_HANDLE event,
01914   int priority,
01915   int signal_number)
01916   : ACE_Asynch_Result_Impl (),
01917     ACE_Asynch_Accept_Result_Impl (),
01918     ACE_WIN32_Asynch_Result (handler_proxy,
01919                              act,
01920                              event,
01921                              0,
01922                              0,
01923                              priority,
01924                              signal_number),
01925     bytes_to_read_ (bytes_to_read),
01926     message_block_ (message_block),
01927     listen_handle_ (listen_handle),
01928     accept_handle_ (accept_handle)
01929 {
01930 }
01931 
01932 void
01933 ACE_WIN32_Asynch_Accept_Result::complete (size_t bytes_transferred,
01934                                           int success,
01935                                           const void *completion_key,
01936                                           u_long error)
01937 {
01938   // Copy the data which was returned by GetQueuedCompletionStatus
01939   this->bytes_transferred_ = bytes_transferred;
01940   this->success_ = success;
01941   this->completion_key_ = completion_key;
01942   this->error_ = error;
01943 
01944   // Appropriately move the pointers in the message block.
01945   this->message_block_.wr_ptr (bytes_transferred);
01946 
01947   if (!success && this->accept_handle_ != ACE_INVALID_HANDLE)
01948     {
01949       ACE_OS::closesocket (this->accept_handle_);
01950       this->accept_handle_ = ACE_INVALID_HANDLE;
01951     }
01952 
01953   // Create the interface result class.
01954   ACE_Asynch_Accept::Result result (this);
01955 
01956   // Call the application handler.
01957   ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
01958   if (handler != 0)
01959     handler->handle_accept (result);
01960 }
01961 
01962 ACE_WIN32_Asynch_Accept_Result::~ACE_WIN32_Asynch_Accept_Result (void)
01963 {
01964 }
01965 
01966 // Base class operations. These operations are here to kill dominance
01967 // warnings. These methods call the base class methods.
01968 
01969 size_t
01970 ACE_WIN32_Asynch_Accept_Result::bytes_transferred (void) const
01971 {
01972   return ACE_WIN32_Asynch_Result::bytes_transferred ();
01973 }
01974 
01975 const void *
01976 ACE_WIN32_Asynch_Accept_Result::act (void) const
01977 {
01978   return ACE_WIN32_Asynch_Result::act ();
01979 }
01980 
01981 int
01982 ACE_WIN32_Asynch_Accept_Result::success (void) const
01983 {
01984   return ACE_WIN32_Asynch_Result::success ();
01985 }
01986 
01987 const void *
01988 ACE_WIN32_Asynch_Accept_Result::completion_key (void) const
01989 {
01990   return ACE_WIN32_Asynch_Result::completion_key ();
01991 }
01992 
01993 u_long
01994 ACE_WIN32_Asynch_Accept_Result::error (void) const
01995 {
01996   return ACE_WIN32_Asynch_Result::error ();
01997 }
01998 
01999 ACE_HANDLE
02000 ACE_WIN32_Asynch_Accept_Result::event (void) const
02001 {
02002   return ACE_WIN32_Asynch_Result::event ();
02003 }
02004 
02005 u_long
02006 ACE_WIN32_Asynch_Accept_Result::offset (void) const
02007 {
02008   return ACE_WIN32_Asynch_Result::offset ();
02009 }
02010 
02011 u_long
02012 ACE_WIN32_Asynch_Accept_Result::offset_high (void) const
02013 {
02014   return ACE_WIN32_Asynch_Result::offset_high ();
02015 }
02016 
02017 int
02018 ACE_WIN32_Asynch_Accept_Result::priority (void) const
02019 {
02020   return ACE_WIN32_Asynch_Result::priority ();
02021 }
02022 
02023 int
02024 ACE_WIN32_Asynch_Accept_Result::signal_number (void) const
02025 {
02026   return ACE_WIN32_Asynch_Result::signal_number ();
02027 }
02028 
02029 int
02030 ACE_WIN32_Asynch_Accept_Result::post_completion (ACE_Proactor_Impl *proactor)
02031 {
02032   return ACE_WIN32_Asynch_Result::post_completion (proactor);
02033 }
02034 
02035 ACE_WIN32_Asynch_Accept::ACE_WIN32_Asynch_Accept (ACE_WIN32_Proactor *win32_proactor)
02036   : ACE_Asynch_Operation_Impl (),
02037     ACE_Asynch_Accept_Impl (),
02038     ACE_WIN32_Asynch_Operation (win32_proactor)
02039 {
02040 }
02041 
02042 int
02043 ACE_WIN32_Asynch_Accept::accept (ACE_Message_Block &message_block,
02044                                  size_t bytes_to_read,
02045                                  ACE_HANDLE accept_handle,
02046                                  const void *act,
02047                                  int priority,
02048                                  int signal_number,
02049                                  int addr_family)
02050 {
02051 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
02052   // Sanity check: make sure that enough space has been allocated by
02053   // the caller.
02054   size_t address_size =
02055 #if defined (ACE_HAS_IPV6)
02056     addr_family == AF_INET ? sizeof (sockaddr_in) : sizeof (sockaddr_in6);
02057 #else
02058     sizeof (sockaddr_in);
02059 #endif /* ACE_HAS_IPV6 */
02060   address_size += 16;     // AcceptEx requires address size + 16 (minimum)
02061   size_t available_space = message_block.space ();
02062   size_t space_needed = bytes_to_read + 2 * address_size;
02063   if (available_space < space_needed)
02064     ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Buffer too small\n")), -1);
02065 
02066   // WIN Specific.
02067 
02068   // AcceptEx API limits us to DWORD range.
02069   if (bytes_to_read > MAXDWORD)
02070     {
02071       errno = ERANGE;
02072       return -1;
02073     }
02074   DWORD dword_bytes_to_read = static_cast<DWORD> (bytes_to_read);
02075 
02076   int close_accept_handle = 0;
02077   // If the <accept_handle> is invalid, we will create a new socket.
02078   if (accept_handle == ACE_INVALID_HANDLE)
02079     {
02080       accept_handle = ACE_OS::socket (addr_family,
02081                                       SOCK_STREAM,
02082                                       0);
02083       if (accept_handle == ACE_INVALID_HANDLE)
02084         {
02085           if (ACE::debug ())
02086             {
02087               ACE_DEBUG ((LM_ERROR,
02088                           ACE_TEXT ("%p\n"),
02089                           ACE_TEXT ("ACE_OS::socket")));
02090             }
02091           return -1;
02092         }
02093       else
02094         // Remember to close the socket down if failures occur.
02095         close_accept_handle = 1;
02096     }
02097 
02098   // Common code for both WIN and POSIX.
02099   ACE_WIN32_Asynch_Accept_Result *result = 0;
02100   ACE_NEW_RETURN (result,
02101                   ACE_WIN32_Asynch_Accept_Result (this->handler_proxy_,
02102                                                   this->handle_,
02103                                                   accept_handle,
02104                                                   message_block,
02105                                                   bytes_to_read,
02106                                                   act,
02107                                                   this->win32_proactor_->get_handle (),
02108                                                   priority,
02109                                                   signal_number),
02110                   -1);
02111 
02112   u_long bytes_read;
02113 
02114   // Initiate the accept.
02115   int initiate_result = ::AcceptEx ((SOCKET) result->listen_handle (),
02116                                     (SOCKET) result->accept_handle (),
02117                                     result->message_block ().wr_ptr (),
02118                                     dword_bytes_to_read,
02119                                     static_cast<DWORD> (address_size),
02120                                     static_cast<DWORD> (address_size),
02121                                     &bytes_read,
02122                                     result);
02123   if (initiate_result == 1)
02124     // Immediate success: the OVERLAPPED will still get queued.
02125     return 1;
02126 
02127   // If initiate failed, check for a bad error.
02128   ACE_OS::set_errno_to_last_error ();
02129   switch (errno)
02130     {
02131     case ERROR_IO_PENDING:
02132       // The IO will complete proactively: the OVERLAPPED will still
02133       // get queued.
02134       return 0;
02135 
02136     default:
02137       // Something else went wrong: the OVERLAPPED will not get
02138       // queued.
02139 
02140       if (close_accept_handle == 1)
02141         // Close the newly created socket
02142         ACE_OS::closesocket (accept_handle);
02143 
02144       // Cleanup dynamically allocated Asynch_Result.
02145       delete result;
02146 
02147       if (ACE::debug ())
02148         {
02149           ACE_DEBUG ((LM_ERROR,
02150                       ACE_TEXT ("%p\n"),
02151                       ACE_TEXT ("AcceptEx")));
02152         }
02153       return -1;
02154     }
02155 #else
02156   ACE_UNUSED_ARG (message_block);
02157   ACE_UNUSED_ARG (bytes_to_read);
02158   ACE_UNUSED_ARG (accept_handle);
02159   ACE_UNUSED_ARG (act);
02160   ACE_UNUSED_ARG (priority);
02161   ACE_UNUSED_ARG (signal_number);
02162   ACE_UNUSED_ARG (addr_family);
02163   ACE_NOTSUP_RETURN (-1);
02164 #endif /* defined (ACE_HAS_WIN32_OVERLAPPED_IO) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)) */
02165 }
02166 
02167 ACE_WIN32_Asynch_Accept::~ACE_WIN32_Asynch_Accept (void)
02168 {
02169 }
02170 
02171 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
02172 // methods are defined here to avoid VC++ warnings. They route the
02173 // call to the ACE_WIN32_Asynch_Operation base class.
02174 
02175 int
02176 ACE_WIN32_Asynch_Accept::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
02177                                ACE_HANDLE handle,
02178                                const void *completion_key,
02179                                ACE_Proactor *proactor)
02180 {
02181   return ACE_WIN32_Asynch_Operation::open (handler_proxy,
02182                                            handle,
02183                                            completion_key,
02184                                            proactor);
02185 }
02186 
02187 int
02188 ACE_WIN32_Asynch_Accept::cancel (void)
02189 {
02190   return ACE_WIN32_Asynch_Operation::cancel ();
02191 }
02192 
02193 ACE_Proactor *
02194 ACE_WIN32_Asynch_Accept::proactor (void) const
02195 {
02196   return ACE_WIN32_Asynch_Operation::proactor ();
02197 }
02198 
02199 // *********************************************************************
02200 
02201 ACE_HANDLE
02202 ACE_WIN32_Asynch_Connect_Result::connect_handle (void) const
02203 {
02204   return this->connect_handle_;
02205 }
02206 
02207 void ACE_WIN32_Asynch_Connect_Result::connect_handle ( ACE_HANDLE handle )
02208 {
02209   this->connect_handle_ = handle;
02210 }
02211 
02212 
02213 ACE_WIN32_Asynch_Connect_Result::ACE_WIN32_Asynch_Connect_Result
02214             (const ACE_Handler::Proxy_Ptr &handler_proxy,
02215              ACE_HANDLE connect_handle,
02216              const void* act,
02217              ACE_HANDLE event,
02218              int priority,
02219              int signal_number)
02220   : ACE_Asynch_Result_Impl (),
02221     ACE_Asynch_Connect_Result_Impl (),
02222     ACE_WIN32_Asynch_Result
02223       (handler_proxy, act, event, 0, 0, priority, signal_number),
02224     connect_handle_ (connect_handle)
02225 {
02226   ;
02227 }
02228 
02229 void
02230 ACE_WIN32_Asynch_Connect_Result::complete (size_t bytes_transferred,
02231                                            int success,
02232                                            const void *completion_key,
02233                                            u_long error)
02234 {
02235   // Copy the data.
02236   this->bytes_transferred_ = bytes_transferred;
02237   this->success_ = success;
02238   this->completion_key_ = completion_key;
02239   this->error_ = error;
02240 
02241   // Create the interface result class.
02242   ACE_Asynch_Connect::Result result (this);
02243 
02244   // Call the application handler.
02245   ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
02246   if (handler != 0)
02247     handler->handle_connect (result);
02248 }
02249 
02250 ACE_WIN32_Asynch_Connect_Result::~ACE_WIN32_Asynch_Connect_Result (void)
02251 {
02252 }
02253 
02254 // Base class operations. These operations are here to kill dominance
02255 // warnings. These methods call the base class methods.
02256 
02257 size_t
02258 ACE_WIN32_Asynch_Connect_Result::bytes_transferred (void) const
02259 {
02260   return ACE_WIN32_Asynch_Result::bytes_transferred ();
02261 }
02262 
02263 const void *
02264 ACE_WIN32_Asynch_Connect_Result::act (void) const
02265 {
02266   return ACE_WIN32_Asynch_Result::act ();
02267 }
02268 
02269 int
02270 ACE_WIN32_Asynch_Connect_Result::success (void) const
02271 {
02272   return ACE_WIN32_Asynch_Result::success ();
02273 }
02274 
02275 const void *
02276 ACE_WIN32_Asynch_Connect_Result::completion_key (void) const
02277 {
02278   return ACE_WIN32_Asynch_Result::completion_key ();
02279 }
02280 
02281 u_long
02282 ACE_WIN32_Asynch_Connect_Result::error (void) const
02283 {
02284   return ACE_WIN32_Asynch_Result::error ();
02285 }
02286 
02287 ACE_HANDLE
02288 ACE_WIN32_Asynch_Connect_Result::event (void) const
02289 {
02290   return ACE_WIN32_Asynch_Result::event ();
02291 }
02292 
02293 u_long
02294 ACE_WIN32_Asynch_Connect_Result::offset (void) const
02295 {
02296   return ACE_WIN32_Asynch_Result::offset ();
02297 }
02298 
02299 u_long
02300 ACE_WIN32_Asynch_Connect_Result::offset_high (void) const
02301 {
02302   return ACE_WIN32_Asynch_Result::offset_high ();
02303 }
02304 
02305 int
02306 ACE_WIN32_Asynch_Connect_Result::priority (void) const
02307 {
02308   return ACE_WIN32_Asynch_Result::priority ();
02309 }
02310 
02311 int
02312 ACE_WIN32_Asynch_Connect_Result::signal_number (void) const
02313 {
02314   return ACE_WIN32_Asynch_Result::signal_number ();
02315 }
02316 
02317 int
02318 ACE_WIN32_Asynch_Connect_Result::post_completion (ACE_Proactor_Impl *proactor)
02319 {
02320   return ACE_WIN32_Asynch_Result::post_completion (proactor);
02321 }
02322 
02323 // *********************************************************************
02324 
02325 ACE_WIN32_Asynch_Connect::ACE_WIN32_Asynch_Connect (ACE_WIN32_Proactor * win32_proactor)
02326   : ACE_Asynch_Operation_Impl (),
02327     ACE_Asynch_Connect_Impl (),
02328     ACE_WIN32_Asynch_Operation (win32_proactor),
02329     flg_open_ (false)
02330 {
02331 }
02332 
02333 ACE_WIN32_Asynch_Connect::~ACE_WIN32_Asynch_Connect (void)
02334 {
02335   this->close ();
02336   this->reactor (0); // to avoid purge_pending_notifications
02337 }
02338 
02339 ACE_Proactor *
02340 ACE_WIN32_Asynch_Connect::proactor (void) const
02341 {
02342   return ACE_WIN32_Asynch_Operation::proactor ();
02343 }
02344 
02345 ACE_HANDLE
02346 ACE_WIN32_Asynch_Connect::get_handle (void) const
02347 {
02348 
02349   ACE_ASSERT (0);
02350   return ACE_INVALID_HANDLE;
02351 }
02352 
02353 void
02354 ACE_WIN32_Asynch_Connect::set_handle (ACE_HANDLE)
02355 {
02356   ACE_ASSERT (0) ;
02357 }
02358 
02359 int
02360 ACE_WIN32_Asynch_Connect::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
02361                                 ACE_HANDLE,
02362                                 const void *completion_key,
02363                                 ACE_Proactor *proactor)
02364 {
02365   ACE_TRACE ("ACE_WIN32_Asynch_Connect::open");
02366 
02367   // if we are already opened,
02368   // we could not create a new handler without closing the previous
02369   if (this->flg_open_)
02370     ACE_ERROR_RETURN ((LM_ERROR,
02371                        ACE_TEXT ("%N:%l:ACE_WIN32_Asynch_Connect::open:")
02372                        ACE_TEXT ("connector already open \n")),
02373                       -1);
02374 
02375   //int result =
02376   ACE_WIN32_Asynch_Operation::open (handler_proxy,
02377                                     ACE_INVALID_HANDLE,
02378                                     completion_key,
02379                                     proactor);
02380 
02381   // Ignore result as we pass ACE_INVALID_HANDLE
02382   //if (result == -1)
02383   //  return result;
02384 
02385   this->flg_open_ = true;
02386 
02387   return 0;
02388 }
02389 
02390 int
02391 ACE_WIN32_Asynch_Connect::connect (ACE_HANDLE connect_handle,
02392                                    const ACE_Addr & remote_sap,
02393                                    const ACE_Addr & local_sap,
02394                                    int reuse_addr,
02395                                    const void *act,
02396                                    int priority,
02397                                    int signal_number)
02398 {
02399   ACE_TRACE ("ACE_WIN32_Asynch_Connect::connect");
02400 
02401   if (!this->flg_open_)
02402     ACE_ERROR_RETURN ((LM_ERROR,
02403                        ACE_TEXT ("%N:%l:ACE_WIN32_Asynch_Connect::connect")
02404                        ACE_TEXT ("connector was not opened before\n")),
02405                       -1);
02406 
02407   // Common code for both WIN and WIN32.
02408   // Create future Asynch_Connect_Result
02409   ACE_WIN32_Asynch_Connect_Result *result = 0;
02410   ACE_NEW_RETURN (result,
02411                   ACE_WIN32_Asynch_Connect_Result (this->handler_proxy_,
02412                                                    connect_handle,
02413                                                    act,
02414                                                    this->win32_proactor_->get_handle (),
02415                                                    priority,
02416                                                    signal_number),
02417                   -1);
02418 
02419   int rc = connect_i (result,
02420                       remote_sap,
02421                       local_sap,
02422                       reuse_addr);
02423 
02424   // update handle
02425   connect_handle = result->connect_handle ();
02426 
02427   if (rc != 0)
02428     return post_result (result, true);
02429 
02430   //  Enqueue result we will wait for completion
02431   {
02432     ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
02433 
02434     if (this->result_map_.bind (connect_handle, result) == -1)
02435       {
02436         ACE_ERROR ((LM_ERROR,
02437                     ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect: %p\n"),
02438                     ACE_TEXT ("bind")));
02439         result->set_error (EFAULT);
02440         return post_result (result, true);
02441       }
02442   }
02443 
02444   ACE_Asynch_Pseudo_Task & task =
02445     this->win32_proactor_->get_asynch_pseudo_task ();
02446 
02447   if (-1 == task.register_io_handler (connect_handle,
02448                                       this,
02449                                       ACE_Event_Handler::CONNECT_MASK,
02450                                       0))  // not to suspend after register
02451     {
02452       result = 0;
02453       {
02454         ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
02455         this->result_map_.unbind (connect_handle, result);
02456       }
02457       if (result != 0)
02458         {
02459           result->set_error (EFAULT);
02460           this->post_result (result, true);
02461         }
02462     }
02463 
02464   return 0;
02465 }
02466 
02467 int ACE_WIN32_Asynch_Connect::post_result (ACE_WIN32_Asynch_Connect_Result * result,
02468                                            bool post_enable)
02469 {
02470   ACE_HANDLE handle = result->connect_handle ();
02471   if (this->flg_open_ && post_enable)
02472     {
02473       // NOTE: result is invalid after post_completion(). It's either deleted
02474       // or will be shortly via the proactor dispatch, regardless of success
02475       // or fail of the call.
02476       if (this->win32_proactor_ ->post_completion (result) == 0)
02477         return 0;
02478 
02479       ACE_ERROR ((LM_ERROR,
02480                   ACE_TEXT ("Error:(%P | %t):%p\n"),
02481                   ACE_TEXT ("ACE_WIN32_Asynch_Connect::post_result: ")
02482                   ACE_TEXT (" <post_completion> failed")));
02483     }
02484   else
02485     {
02486       // There was no call to post_completion() so manually delete result.
02487       delete result;
02488     }
02489 
02490    if (handle != ACE_INVALID_HANDLE)
02491      ACE_OS::closesocket (handle);
02492 
02493    return -1;
02494 }
02495 
02496 // connect_i
02497 //  return code :
02498 //   -1   errors  before  attempt to connect
02499 //    0   connect started
02500 //    1   connect finished ( may be unsuccessfully)
02501 
02502 int
02503 ACE_WIN32_Asynch_Connect::connect_i (ACE_WIN32_Asynch_Connect_Result *result,
02504                                      const ACE_Addr & remote_sap,
02505                                      const ACE_Addr & local_sap,
02506                                      int  reuse_addr)
02507 {
02508   result->set_bytes_transferred (0);
02509 
02510   ACE_HANDLE handle = result->connect_handle ();
02511   if (handle == ACE_INVALID_HANDLE)
02512     {
02513       int protocol_family = remote_sap.get_type ();
02514       handle = ACE_OS::socket (protocol_family,
02515                                SOCK_STREAM,
02516                                0);
02517 
02518       // save it
02519       result->connect_handle (handle);
02520       if (handle == ACE_INVALID_HANDLE)
02521         {
02522           result->set_error (errno);
02523           ACE_ERROR_RETURN
02524             ((LM_ERROR,
02525               ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"),
02526               ACE_TEXT ("socket")),
02527              -1);
02528         }
02529 
02530       // Reuse the address
02531       int one = 1;
02532       if (protocol_family != PF_UNIX  &&
02533           reuse_addr != 0 &&
02534           ACE_OS::setsockopt (handle,
02535                               SOL_SOCKET,
02536                               SO_REUSEADDR,
02537                               (const char*) &one,
02538                               sizeof one) == -1)
02539         {
02540           result->set_error (errno);
02541           ACE_ERROR_RETURN
02542             ((LM_ERROR,
02543               ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"),
02544               ACE_TEXT ("setsockopt")),
02545              -1);
02546         }
02547     }
02548 
02549   if (local_sap != ACE_Addr::sap_any)
02550     {
02551       sockaddr * laddr = reinterpret_cast<sockaddr *> (local_sap.get_addr ());
02552       int size = local_sap.get_size ();
02553       if (ACE_OS::bind (handle, laddr, size) == -1)
02554         {
02555            result->set_error (errno);
02556            ACE_ERROR_RETURN
02557              ((LM_ERROR,
02558                ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"),
02559                ACE_TEXT ("bind")),
02560               -1);
02561         }
02562     }
02563 
02564   // set non blocking mode
02565   if (ACE::set_flags (handle, ACE_NONBLOCK) != 0)
02566     {
02567       result->set_error (errno);
02568       ACE_ERROR_RETURN
02569         ((LM_ERROR,
02570           ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"),
02571           ACE_TEXT ("set_flags")),
02572          -1);
02573     }
02574 
02575   for (;;)
02576     {
02577       int rc = ACE_OS::connect
02578         (handle,
02579          reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
02580          remote_sap.get_size ());
02581 
02582       if (rc < 0)  // failure
02583         {
02584           if (errno == EWOULDBLOCK || errno == EINPROGRESS)
02585             return 0; // connect started
02586 
02587           if (errno == EINTR)
02588              continue;
02589 
02590           result->set_error (errno);
02591         }
02592       return 1 ;  // connect finished
02593     }
02594 }
02595 
02596 
02597 // cancel_uncompleted
02598 // It performs cancellation of all pending requests
02599 //
02600 // Parameter flg_notify can be
02601 //     0  - don't send notifications about canceled accepts
02602 //    !0  - notify user about canceled accepts
02603 //          according WIN32 standards we should receive notifications
02604 //          on canceled AIO requests
02605 //
02606 //  Return value : number of cancelled requests
02607 //
02608 
02609 int
02610 ACE_WIN32_Asynch_Connect::cancel_uncompleted (bool flg_notify,
02611                                               ACE_Handle_Set &set)
02612 {
02613   ACE_TRACE ("ACE_WIN32_Asynch_Connect::cancel_uncompleted");
02614 
02615   int retval = 0;
02616 
02617   MAP_MANAGER::ITERATOR iter (result_map_);
02618   MAP_MANAGER::ENTRY *   me = 0;
02619 
02620   set.reset ();
02621 
02622   for (; iter.next (me) != 0; retval++, iter.advance ())
02623     {
02624        ACE_HANDLE handle = me->ext_id_;
02625        ACE_WIN32_Asynch_Connect_Result* result = me->int_id_ ;
02626 
02627        set.set_bit (handle);
02628 
02629        result->set_bytes_transferred (0);
02630        result->set_error (ERROR_OPERATION_ABORTED);
02631        this->post_result (result, flg_notify);
02632     }
02633 
02634   result_map_.unbind_all ();
02635 
02636   return retval;
02637 }
02638 
02639 int
02640 ACE_WIN32_Asynch_Connect::cancel (void)
02641 {
02642   ACE_TRACE ("ACE_WIN32_Asynch_Connect::cancel");
02643 
02644   int rc = -1 ;  // ERRORS
02645 
02646   ACE_Handle_Set set;
02647   int num_cancelled = 0;
02648   {
02649     ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
02650 
02651     num_cancelled = cancel_uncompleted (flg_open_, set);
02652   }
02653   if (num_cancelled == 0)
02654     rc = 1;        // AIO_ALLDONE
02655   else if (num_cancelled > 0)
02656     rc = 0;        // AIO_CANCELED
02657 
02658   if (!this->flg_open_)
02659     return rc;
02660 
02661   ACE_Asynch_Pseudo_Task & task =
02662     this->win32_proactor_->get_asynch_pseudo_task ();
02663 
02664   task.remove_io_handler (set);
02665   return rc;
02666 }
02667 
02668 int
02669 ACE_WIN32_Asynch_Connect::close (void)
02670 {
02671   ACE_TRACE ("ACE_WIN32_Asynch_Connect::close");
02672 
02673   ACE_Handle_Set set;
02674   int num_cancelled = 0;
02675   {
02676     ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
02677 
02678     num_cancelled = cancel_uncompleted (flg_open_, set);
02679   }
02680   if (num_cancelled == 0 || this->flg_open_ == 0)
02681     {
02682       this->flg_open_ = false;
02683       return 0;
02684     }
02685 
02686   ACE_Asynch_Pseudo_Task & task =
02687     this->win32_proactor_->get_asynch_pseudo_task ();
02688 
02689   task.remove_io_handler (set);
02690   return 0;
02691 }
02692 
02693 int
02694 ACE_WIN32_Asynch_Connect::handle_exception (ACE_HANDLE fd)
02695 {
02696   ACE_TRACE ("ACE_WIN32_Asynch_Connect::handle_exception");
02697   return handle_output (fd);
02698 }
02699 
02700 int
02701 ACE_WIN32_Asynch_Connect::handle_input (ACE_HANDLE fd)
02702 {
02703   ACE_TRACE ("ACE_WIN32_Asynch_Connect::handle_input");
02704   return handle_output (fd);
02705 }
02706 
02707 int
02708 ACE_WIN32_Asynch_Connect::handle_output (ACE_HANDLE fd)
02709 {
02710   ACE_TRACE ("ACE_WIN32_Asynch_Connect::handle_output");
02711 
02712   ACE_WIN32_Asynch_Connect_Result* result = 0;
02713 
02714   {
02715     ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0));
02716     if (this->result_map_.unbind (fd, result) != 0) // not found
02717       return -1;
02718   }
02719 
02720   int sockerror  = 0 ;
02721   int lsockerror = sizeof sockerror;
02722 
02723   ACE_OS::getsockopt (fd,
02724                       SOL_SOCKET,
02725                       SO_ERROR,
02726                       (char*) & sockerror,
02727                       & lsockerror);
02728 
02729   // This previously just did a "return -1" and let handle_close() clean
02730   // things up. However, this entire object may be gone as a result of
02731   // the application's completion handler, so don't count on 'this' being
02732   // legitimate on return from post_result().
02733   // remove_io_handler() contains flag DONT_CALL
02734   this->win32_proactor_->get_asynch_pseudo_task().remove_io_handler (fd);
02735 
02736   result->set_bytes_transferred (0);
02737   result->set_error (sockerror);
02738   this->post_result (result, this->flg_open_);
02739   return 0;
02740 }
02741 
02742 
02743 int
02744 ACE_WIN32_Asynch_Connect::handle_close (ACE_HANDLE fd, ACE_Reactor_Mask)
02745 {
02746   ACE_TRACE ("ACE_WIN32_Asynch_Connect::handle_close");
02747 
02748   ACE_Asynch_Pseudo_Task & task =
02749          this->win32_proactor_->get_asynch_pseudo_task ();
02750   task.remove_io_handler (fd);
02751 
02752   ACE_WIN32_Asynch_Connect_Result* result = 0;
02753 
02754   {
02755     ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0));
02756     if (this->result_map_.unbind (fd, result) != 0) // not found
02757       return -1;
02758   }
02759 
02760   result->set_bytes_transferred (0);
02761   result->set_error (ERROR_OPERATION_ABORTED);
02762   this->post_result (result, this->flg_open_);
02763 
02764   return 0;
02765 }
02766 
02767 // *********************************************************************
02768 
02769 ACE_HANDLE
02770 ACE_WIN32_Asynch_Transmit_File_Result::socket (void) const
02771 {
02772   return this->socket_;
02773 }
02774 
02775 ACE_HANDLE
02776 ACE_WIN32_Asynch_Transmit_File_Result::file (void) const
02777 {
02778   return this->file_;
02779 }
02780 
02781 ACE_Asynch_Transmit_File::Header_And_Trailer *
02782 ACE_WIN32_Asynch_Transmit_File_Result::header_and_trailer (void) const
02783 {
02784   return this->header_and_trailer_;
02785 }
02786 
02787 size_t
02788 ACE_WIN32_Asynch_Transmit_File_Result::bytes_to_write (void) const
02789 {
02790   return this->bytes_to_write_;
02791 }
02792 
02793 size_t
02794 ACE_WIN32_Asynch_Transmit_File_Result::bytes_per_send (void) const
02795 {
02796   return this->bytes_per_send_;
02797 }
02798 
02799 u_long
02800 ACE_WIN32_Asynch_Transmit_File_Result::flags (void) const
02801 {
02802   return this->flags_;
02803 }
02804 
02805 ACE_WIN32_Asynch_Transmit_File_Result::ACE_WIN32_Asynch_Transmit_File_Result (
02806   const ACE_Handler::Proxy_Ptr &handler_proxy,
02807   ACE_HANDLE socket,
02808   ACE_HANDLE file,
02809   ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer,
02810   size_t bytes_to_write,
02811   u_long offset,
02812   u_long offset_high,
02813   size_t bytes_per_send,
02814   u_long flags,
02815   const void *act,
02816   ACE_HANDLE event,
02817   int priority,
02818   int signal_number)
02819   : ACE_Asynch_Result_Impl (),
02820     ACE_Asynch_Transmit_File_Result_Impl (),
02821     ACE_WIN32_Asynch_Result (handler_proxy,
02822                              act,
02823                              event,
02824                              offset,
02825                              offset_high,
02826                              priority,
02827                              signal_number),
02828     socket_ (socket),
02829     file_ (file),
02830     header_and_trailer_ (header_and_trailer),
02831     bytes_to_write_ (bytes_to_write),
02832     bytes_per_send_ (bytes_per_send),
02833     flags_ (flags)
02834 {
02835 }
02836 
02837 void
02838 ACE_WIN32_Asynch_Transmit_File_Result::complete (size_t bytes_transferred,
02839                                                  int success,
02840                                                  const void *completion_key,
02841                                                  u_long error)
02842 {
02843   // Copy the data which was returned by GetQueuedCompletionStatus
02844   this->bytes_transferred_ = bytes_transferred;
02845   this->success_ = success;
02846   this->completion_key_ = completion_key;
02847   this->error_ = error;
02848 
02849   // We will not do this because (a) the header and trailer blocks may
02850   // be the same message_blocks and (b) in cases of failures we have
02851   // no idea how much of what (header, data, trailer) was sent.
02852   /*
02853     if (this->success_ && this->header_and_trailer_ != 0)
02854     {
02855     ACE_Message_Block *header = this->header_and_trailer_->header ();
02856     if (header != 0)
02857     header->rd_ptr (this->header_and_trailer_->header_bytes ());
02858 
02859     ACE_Message_Block *trailer = this->header_and_trailer_->trailer ();
02860     if (trailer != 0)
02861     trailer->rd_ptr (this->header_and_trailer_->trailer_bytes ());
02862     }
02863   */
02864 
02865   // Create the interface result class.
02866   ACE_Asynch_Transmit_File::Result result (this);
02867 
02868   // Call the application handler.
02869   ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
02870   if (handler != 0)
02871     handler->handle_transmit_file (result);
02872 }
02873 
02874 ACE_WIN32_Asynch_Transmit_File_Result::~ACE_WIN32_Asynch_Transmit_File_Result (void)
02875 {
02876 }
02877 
02878 // Base class operations. These operations are here to kill dominance
02879 // warnings. These methods call the base class methods.
02880 
02881 size_t
02882 ACE_WIN32_Asynch_Transmit_File_Result::bytes_transferred (void) const
02883 {
02884   return ACE_WIN32_Asynch_Result::bytes_transferred ();
02885 }
02886 
02887 const void *
02888 ACE_WIN32_Asynch_Transmit_File_Result::act (void) const
02889 {
02890   return ACE_WIN32_Asynch_Result::act ();
02891 }
02892 
02893 int
02894 ACE_WIN32_Asynch_Transmit_File_Result::success (void) const
02895 {
02896   return ACE_WIN32_Asynch_Result::success ();
02897 }
02898 
02899 const void *
02900 ACE_WIN32_Asynch_Transmit_File_Result::completion_key (void) const
02901 {
02902   return ACE_WIN32_Asynch_Result::completion_key ();
02903 }
02904 
02905 u_long
02906 ACE_WIN32_Asynch_Transmit_File_Result::error (void) const
02907 {
02908   return ACE_WIN32_Asynch_Result::error ();
02909 }
02910 
02911 ACE_HANDLE
02912 ACE_WIN32_Asynch_Transmit_File_Result::event (void) const
02913 {
02914   return ACE_WIN32_Asynch_Result::event ();
02915 }
02916 
02917 u_long
02918 ACE_WIN32_Asynch_Transmit_File_Result::offset (void) const
02919 {
02920   return ACE_WIN32_Asynch_Result::offset ();
02921 }
02922 
02923 u_long
02924 ACE_WIN32_Asynch_Transmit_File_Result::offset_high (void) const
02925 {
02926   return ACE_WIN32_Asynch_Result::offset_high ();
02927 }
02928 
02929 int
02930 ACE_WIN32_Asynch_Transmit_File_Result::priority (void) const
02931 {
02932   return ACE_WIN32_Asynch_Result::priority ();
02933 }
02934 
02935 int
02936 ACE_WIN32_Asynch_Transmit_File_Result::signal_number (void) const
02937 {
02938   return ACE_WIN32_Asynch_Result::signal_number ();
02939 }
02940 
02941 int
02942 ACE_WIN32_Asynch_Transmit_File_Result::post_completion (ACE_Proactor_Impl *proactor)
02943 {
02944   return ACE_WIN32_Asynch_Result::post_completion (proactor);
02945 }
02946 
02947 ACE_WIN32_Asynch_Transmit_File::ACE_WIN32_Asynch_Transmit_File (ACE_WIN32_Proactor *win32_proactor)
02948   : ACE_Asynch_Operation_Impl (),
02949     ACE_Asynch_Transmit_File_Impl (),
02950     ACE_WIN32_Asynch_Operation (win32_proactor)
02951 {
02952 }
02953 
02954 int
02955 ACE_WIN32_Asynch_Transmit_File::transmit_file (ACE_HANDLE file,
02956                                                ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer,
02957                                                size_t bytes_to_write,
02958                                                u_long offset,
02959                                                u_long offset_high,
02960                                                size_t bytes_per_send,
02961                                                u_long flags,
02962                                                const void *act,
02963                                                int priority,
02964                                                int signal_number)
02965 {
02966 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
02967 
02968   // TransmitFile API limits us to DWORD range.
02969   if (bytes_to_write > MAXDWORD || bytes_per_send > MAXDWORD)
02970     {
02971       errno = ERANGE;
02972       return -1;
02973     }
02974   DWORD dword_bytes_to_write = static_cast<DWORD> (bytes_to_write);
02975   DWORD dword_bytes_per_send = static_cast<DWORD> (bytes_per_send);
02976 
02977   ACE_WIN32_Asynch_Transmit_File_Result *result = 0;
02978   ACE_NEW_RETURN (result,
02979                   ACE_WIN32_Asynch_Transmit_File_Result (this->handler_proxy_,
02980                                                          this->handle_,
02981                                                          file,
02982                                                          header_and_trailer,
02983                                                          bytes_to_write,
02984                                                          offset,
02985                                                          offset_high,
02986                                                          bytes_per_send,
02987                                                          flags,
02988                                                          act,
02989                                                          this->win32_proactor_->get_handle (),
02990                                                          priority,
02991                                                          signal_number),
02992                   -1);
02993 
02994   ACE_LPTRANSMIT_FILE_BUFFERS transmit_buffers = 0;
02995   if (result->header_and_trailer () != 0)
02996     transmit_buffers = result->header_and_trailer ()->transmit_buffers ();
02997 
02998   // Initiate the transmit file
02999   int initiate_result = ::TransmitFile ((SOCKET) result->socket (),
03000                                         result->file (),
03001                                         dword_bytes_to_write,
03002                                         dword_bytes_per_send,
03003                                         result,
03004                                         transmit_buffers,
03005                                         result->flags ());
03006   if (initiate_result == 1)
03007     // Immediate success: the OVERLAPPED will still get queued.
03008     return 1;
03009 
03010   // If initiate failed, check for a bad error.
03011   ACE_OS::set_errno_to_last_error ();
03012   switch (errno)
03013     {
03014     case ERROR_IO_PENDING:
03015       // The IO will complete proactively: the OVERLAPPED will still
03016       // get queued.
03017       return 0;
03018 
03019     default:
03020       // Something else went wrong: the OVERLAPPED will not get
03021       // queued.
03022 
03023       // Cleanup dynamically allocated Asynch_Result
03024       delete result;
03025 
03026       if (ACE::debug ())
03027         {
03028           ACE_DEBUG ((LM_ERROR,
03029                       ACE_TEXT ("%p\n"),
03030                       ACE_TEXT ("TransmitFile")));
03031         }
03032       return -1;
03033     }
03034 #else
03035   ACE_UNUSED_ARG (file);
03036   ACE_UNUSED_ARG (header_and_trailer);
03037   ACE_UNUSED_ARG (bytes_to_write);
03038   ACE_UNUSED_ARG (offset);
03039   ACE_UNUSED_ARG (offset_high);
03040   ACE_UNUSED_ARG (bytes_per_send);
03041   ACE_UNUSED_ARG (flags);
03042   ACE_UNUSED_ARG (act);
03043   ACE_UNUSED_ARG (priority);
03044   ACE_UNUSED_ARG (signal_number);
03045   ACE_NOTSUP_RETURN (-1);
03046 #endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_WINSOCK2 */
03047 }
03048 
03049 ACE_WIN32_Asynch_Transmit_File::~ACE_WIN32_Asynch_Transmit_File (void)
03050 {
03051 }
03052 
03053 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
03054 // methods are defined here to avoid VC++ warnings. They route the
03055 // call to the ACE_WIN32_Asynch_Operation base class.
03056 
03057 int
03058 ACE_WIN32_Asynch_Transmit_File::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
03059                                       ACE_HANDLE handle,
03060                                       const void *completion_key,
03061                                       ACE_Proactor *proactor)
03062 {
03063   return ACE_WIN32_Asynch_Operation::open (handler_proxy,
03064                                            handle,
03065                                            completion_key,
03066                                            proactor);
03067 }
03068 
03069 int
03070 ACE_WIN32_Asynch_Transmit_File::cancel (void)
03071 {
03072   return ACE_WIN32_Asynch_Operation::cancel ();
03073 }
03074 
03075 ACE_Proactor *
03076 ACE_WIN32_Asynch_Transmit_File::proactor (void) const
03077 {
03078   return ACE_WIN32_Asynch_Operation::proactor ();
03079 }
03080 
03081 size_t
03082 ACE_WIN32_Asynch_Read_Dgram_Result::bytes_to_read (void) const
03083 {
03084   return this->bytes_to_read_;
03085 }
03086 
03087 ACE_Message_Block*
03088 ACE_WIN32_Asynch_Read_Dgram_Result::message_block (void) const
03089 {
03090   return this->message_block_;
03091 }
03092 
03093 
03094 int
03095 ACE_WIN32_Asynch_Read_Dgram_Result::remote_address (ACE_Addr& addr) const
03096 {
03097  int retVal = -1;  // failure
03098 
03099   // make sure the addresses are of the same type
03100   if (addr.get_type () == this->remote_address_->get_type ())
03101   { // copy the remote_address_ into addr
03102     addr.set_addr (this->remote_address_->get_addr (),
03103                    this->remote_address_->get_size ());
03104     retVal = 0; // success
03105   }
03106 
03107   return retVal;
03108 }
03109 
03110 sockaddr *
03111 ACE_WIN32_Asynch_Read_Dgram_Result::saddr () const
03112 {
03113   return (sockaddr *) this->remote_address_->get_addr ();
03114 }
03115 
03116 
03117 int
03118 ACE_WIN32_Asynch_Read_Dgram_Result::flags (void) const
03119 {
03120   return this->flags_;
03121 }
03122 
03123 ACE_HANDLE
03124 ACE_WIN32_Asynch_Read_Dgram_Result::handle (void) const
03125 {
03126   return this->handle_;
03127 }
03128 
03129 size_t
03130 ACE_WIN32_Asynch_Read_Dgram_Result::bytes_transferred (void) const
03131 {
03132   return ACE_WIN32_Asynch_Result::bytes_transferred ();
03133 }
03134 
03135 const void *
03136 ACE_WIN32_Asynch_Read_Dgram_Result::act (void) const
03137 {
03138   return ACE_WIN32_Asynch_Result::act ();
03139 }
03140 
03141 int
03142 ACE_WIN32_Asynch_Read_Dgram_Result::success (void) const
03143 {
03144   return ACE_WIN32_Asynch_Result::success ();
03145 }
03146 
03147 const void *
03148 ACE_WIN32_Asynch_Read_Dgram_Result::completion_key (void) const
03149 {
03150   return ACE_WIN32_Asynch_Result::completion_key ();
03151 }
03152 
03153 u_long
03154 ACE_WIN32_Asynch_Read_Dgram_Result::error (void) const
03155 {
03156   return ACE_WIN32_Asynch_Result::error ();
03157 }
03158 
03159 ACE_HANDLE
03160 ACE_WIN32_Asynch_Read_Dgram_Result::event (void) const
03161 {
03162   return ACE_WIN32_Asynch_Result::event ();
03163 }
03164 
03165 u_long
03166 ACE_WIN32_Asynch_Read_Dgram_Result::offset (void) const
03167 {
03168   return ACE_WIN32_Asynch_Result::offset ();
03169 }
03170 
03171 u_long
03172 ACE_WIN32_Asynch_Read_Dgram_Result::offset_high (void) const
03173 {
03174   return ACE_WIN32_Asynch_Result::offset_high ();
03175 }
03176 
03177 int
03178 ACE_WIN32_Asynch_Read_Dgram_Result::priority (void) const
03179 {
03180   return ACE_WIN32_Asynch_Result::priority ();
03181 }
03182 
03183 int
03184 ACE_WIN32_Asynch_Read_Dgram_Result::signal_number (void) const
03185 {
03186   return ACE_WIN32_Asynch_Result::signal_number ();
03187 }
03188 
03189 int
03190 ACE_WIN32_Asynch_Read_Dgram_Result::post_completion (ACE_Proactor_Impl *proactor)
03191 {
03192   return ACE_WIN32_Asynch_Result::post_completion (proactor);
03193 }
03194 
03195 ACE_WIN32_Asynch_Read_Dgram_Result::ACE_WIN32_Asynch_Read_Dgram_Result (
03196   const ACE_Handler::Proxy_Ptr &handler_proxy,
03197   ACE_HANDLE handle,
03198   ACE_Message_Block *message_block,
03199   size_t bytes_to_read,
03200   int flags,
03201   int protocol_family,
03202   const void* act,
03203   ACE_HANDLE event,
03204   int priority,
03205   int signal_number)
03206   : ACE_Asynch_Result_Impl (),
03207     ACE_Asynch_Read_Dgram_Result_Impl(),
03208     ACE_WIN32_Asynch_Result (handler_proxy, act, event, 0, 0, priority, signal_number),
03209     bytes_to_read_ (bytes_to_read),
03210     message_block_ (message_block),
03211     remote_address_ (0),
03212     addr_len_ (0),
03213     flags_ (flags),
03214     handle_ (handle)
03215 {
03216   ACE_ASSERT (protocol_family == PF_INET); // only supporting INET addresses
03217 
03218   ACE_NEW (remote_address_, ACE_INET_Addr);
03219   addr_len_ = remote_address_->get_size ();
03220 
03221   ACE_UNUSED_ARG (protocol_family);
03222 }
03223 
03224 void
03225 ACE_WIN32_Asynch_Read_Dgram_Result::complete (size_t bytes_transferred,
03226                                               int success,
03227                                               const void *completion_key,
03228                                               u_long error)
03229 {
03230   // Copy the data which was returned by GetQueuedCompletionStatus
03231   this->bytes_transferred_ = bytes_transferred;
03232   this->success_ = success;
03233   this->completion_key_ = completion_key;
03234   this->error_ = error;
03235 
03236   // Appropriately move the pointers in the message block.
03237   for (ACE_Message_Block* mb = this->message_block_;
03238        (mb != 0) && (bytes_transferred > 0);
03239        mb = mb->cont ())
03240     {
03241       size_t len_part = mb->space ();
03242 
03243       if ( len_part > bytes_transferred)
03244         len_part = bytes_transferred;
03245 
03246       mb->wr_ptr (len_part);
03247 
03248       bytes_transferred -= len_part;
03249     }
03250 
03251   // Adjust the address length
03252   this->remote_address_->set_size (this->addr_len_);
03253 
03254   // Create the interface result class.
03255   ACE_Asynch_Read_Dgram::Result result (this);
03256 
03257   // Call the application handler.
03258   ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
03259   if (handler != 0)
03260     handler->handle_read_dgram (result);
03261 }
03262 
03263 ACE_WIN32_Asynch_Read_Dgram_Result::~ACE_WIN32_Asynch_Read_Dgram_Result (void)
03264 {
03265   delete this->remote_address_;
03266 }
03267 
03268 //***************************************************************************
03269 
03270 ACE_WIN32_Asynch_Read_Dgram::~ACE_WIN32_Asynch_Read_Dgram (void)
03271 {
03272 }
03273 
03274 ssize_t
03275 ACE_WIN32_Asynch_Read_Dgram::recv (ACE_Message_Block *message_block,
03276                                    size_t & number_of_bytes_recvd,
03277                                    int flags,
03278                                    int protocol_family,
03279                                    const void *act,
03280                                    int priority,
03281                                    int signal_number)
03282 {
03283   number_of_bytes_recvd = 0;
03284 
03285   size_t bytes_to_read = 0;
03286 
03287   iovec  iov[ACE_IOV_MAX];
03288   int    iovcnt = 0;
03289 
03290   for (const ACE_Message_Block* msg = message_block;
03291        msg != 0 && iovcnt < ACE_IOV_MAX;
03292        msg = msg->cont () , ++iovcnt )
03293   {
03294     size_t msg_space = msg->space ();
03295 
03296     // OS should correctly process zero length buffers
03297     // if ( msg_space == 0 )
03298     //   ACE_ERROR_RETURN ((LM_ERROR,
03299     //                      ACE_TEXT ("ACE_WIN32_Asynch_Read_Dgram::recv:")
03300     //                      ACE_TEXT ("No space in the message block\n")),
03301     //                     -1);
03302 
03303     bytes_to_read += msg_space;
03304 
03305     // Make as many iovec as needed to fit all of msg_len.
03306     size_t wr_ptr_offset = 0;
03307     while (msg_space > 0 && iovcnt < ACE_IOV_MAX)
03308       {
03309         u_long this_chunk_length;
03310         if (msg_space > ULONG_MAX)
03311           this_chunk_length = ULONG_MAX;
03312         else
03313           this_chunk_length = static_cast<u_long> (msg_space);
03314         // Collect the data in the iovec.
03315         iov[iovcnt].iov_base = msg->wr_ptr () + wr_ptr_offset;
03316         iov[iovcnt].iov_len  = this_chunk_length;
03317         msg_space -= this_chunk_length;
03318         wr_ptr_offset += this_chunk_length;
03319 
03320         // Increment iovec counter if there's more to do.
03321         if (msg_space > 0)
03322           iovcnt++;
03323       }
03324     if (msg_space > 0)       // Ran out of iovecs before msg_space exhausted
03325       {
03326         errno = ERANGE;
03327         return -1;
03328       }
03329   }
03330 
03331   if (bytes_to_read == 0)
03332       ACE_ERROR_RETURN ((LM_ERROR,
03333                          ACE_TEXT ("ACE_WIN32_Asynch_Read_Dgram::recv:")
03334                          ACE_TEXT ("Attempt to read 0 bytes\n")),
03335                         -1);
03336 
03337   // Create the Asynch_Result.
03338   ACE_WIN32_Asynch_Read_Dgram_Result *result = 0;
03339   ACE_NEW_RETURN (result,
03340                   ACE_WIN32_Asynch_Read_Dgram_Result (this->handler_proxy_,
03341                                                       this->handle_,
03342                                                       message_block,
03343                                                       bytes_to_read,
03344                                                       flags,
03345                                                       protocol_family,
03346                                                       act,
03347                                                       this->win32_proactor_->get_handle (),
03348                                                       priority,
03349                                                       signal_number),
03350                   -1);
03351 
03352   // do the scatter/gather recv
03353   ssize_t initiate_result = ACE_OS::recvfrom (result->handle (),
03354                                               iov,
03355                                               iovcnt,
03356                                               number_of_bytes_recvd,
03357                                               result->flags_,
03358                                               result->saddr (),
03359                                               &(result->addr_len_),
03360                                               result,
03361                                               0);
03362   if (initiate_result == SOCKET_ERROR)
03363   {
03364     // If initiate failed, check for a bad error.
03365     ACE_OS::set_errno_to_last_error ();
03366     switch (errno)
03367     {
03368       case ERROR_IO_PENDING:
03369         // The IO will complete proactively: the OVERLAPPED will still
03370         // get queued.
03371         initiate_result = 0;
03372         break;
03373 
03374       default:
03375         // Something else went wrong: the OVERLAPPED will not get
03376         // queued.
03377 
03378         if (ACE::debug ())
03379         {
03380           ACE_DEBUG ((LM_ERROR,
03381                       ACE_TEXT ("%p\n"),
03382                       ACE_TEXT ("WSARecvFrom")));
03383         }
03384 
03385         delete result;
03386         initiate_result = -1;
03387         break;
03388     }
03389 
03390   }
03391   else
03392   {
03393     // Immediate success: the OVERLAPPED will still get queued.
03394     // number_of_bytes_recvd contains the number of bytes recvd
03395     // addr contains the peer address
03396     // flags was updated
03397 
03398     // number_of_bytes_recvd = bytes_recvd;
03399     initiate_result = 1;
03400   }
03401 
03402   return initiate_result;
03403 }
03404 
03405 int
03406 ACE_WIN32_Asynch_Read_Dgram::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
03407                                    ACE_HANDLE handle,
03408                                    const void *completion_key,
03409                                    ACE_Proactor *proactor)
03410 {
03411   return ACE_WIN32_Asynch_Operation::open (handler_proxy,
03412                                            handle,
03413                                            completion_key,
03414                                            proactor);
03415 }
03416 
03417 int
03418 ACE_WIN32_Asynch_Read_Dgram::cancel (void)
03419 {
03420   return ACE_WIN32_Asynch_Operation::cancel ();
03421 }
03422 
03423 ACE_Proactor *
03424 ACE_WIN32_Asynch_Read_Dgram::proactor (void) const
03425 {
03426   return ACE_WIN32_Asynch_Operation::proactor ();
03427 }
03428 
03429 ACE_WIN32_Asynch_Read_Dgram::ACE_WIN32_Asynch_Read_Dgram (ACE_WIN32_Proactor *win32_proactor)
03430   : ACE_Asynch_Operation_Impl (),
03431     ACE_Asynch_Read_Dgram_Impl (),
03432     ACE_WIN32_Asynch_Operation (win32_proactor)
03433 {
03434 }
03435 
03436 //***********************************************
03437 
03438 size_t
03439 ACE_WIN32_Asynch_Write_Dgram_Result::bytes_to_write (void) const
03440 {
03441   return this->bytes_to_write_;
03442 }
03443 
03444 ACE_Message_Block*
03445 ACE_WIN32_Asynch_Write_Dgram_Result::message_block () const
03446 {
03447   return this->message_block_;
03448 }
03449 
03450 int
03451 ACE_WIN32_Asynch_Write_Dgram_Result::flags (void) const
03452 {
03453   return this->flags_;
03454 }
03455 
03456 ACE_HANDLE
03457 ACE_WIN32_Asynch_Write_Dgram_Result::handle (void) const
03458 {
03459   return this->handle_;
03460 }
03461 
03462 size_t
03463 ACE_WIN32_Asynch_Write_Dgram_Result::bytes_transferred (void) const
03464 {
03465   return ACE_WIN32_Asynch_Result::bytes_transferred ();
03466 }
03467 
03468 const void *
03469 ACE_WIN32_Asynch_Write_Dgram_Result::act (void) const
03470 {
03471   return ACE_WIN32_Asynch_Result::act ();
03472 }
03473 
03474 int
03475 ACE_WIN32_Asynch_Write_Dgram_Result::success (void) const
03476 {
03477   return ACE_WIN32_Asynch_Result::success ();
03478 }
03479 
03480 const void *
03481 ACE_WIN32_Asynch_Write_Dgram_Result::completion_key (void) const
03482 {
03483   return ACE_WIN32_Asynch_Result::completion_key ();
03484 }
03485 
03486 u_long
03487 ACE_WIN32_Asynch_Write_Dgram_Result::error (void) const
03488 {
03489   return ACE_WIN32_Asynch_Result::error ();
03490 }
03491 
03492 ACE_HANDLE
03493 ACE_WIN32_Asynch_Write_Dgram_Result::event (void) const
03494 {
03495   return ACE_WIN32_Asynch_Result::event ();
03496 }
03497 
03498 u_long
03499 ACE_WIN32_Asynch_Write_Dgram_Result::offset (void) const
03500 {
03501   return ACE_WIN32_Asynch_Result::offset ();
03502 }
03503 
03504 u_long
03505 ACE_WIN32_Asynch_Write_Dgram_Result::offset_high (void) const
03506 {
03507   return ACE_WIN32_Asynch_Result::offset_high ();
03508 }
03509 
03510 int
03511 ACE_WIN32_Asynch_Write_Dgram_Result::priority (void) const
03512 {
03513   return ACE_WIN32_Asynch_Result::priority ();
03514 }
03515 
03516 int
03517 ACE_WIN32_Asynch_Write_Dgram_Result::signal_number (void) const
03518 {
03519   return ACE_WIN32_Asynch_Result::signal_number ();
03520 }
03521 
03522 int
03523 ACE_WIN32_Asynch_Write_Dgram_Result::post_completion (ACE_Proactor_Impl *proactor)
03524 {
03525   return ACE_WIN32_Asynch_Result::post_completion (proactor);
03526 }
03527 
03528 ACE_WIN32_Asynch_Write_Dgram_Result::ACE_WIN32_Asynch_Write_Dgram_Result (
03529   const ACE_Handler::Proxy_Ptr &handler_proxy,
03530   ACE_HANDLE handle,
03531   ACE_Message_Block *message_block,
03532   size_t bytes_to_write,
03533   int flags,
03534   const void* act,
03535   ACE_HANDLE event,
03536   int priority,
03537   int signal_number)
03538   : ACE_Asynch_Result_Impl (),
03539     ACE_Asynch_Write_Dgram_Result_Impl(),
03540     ACE_WIN32_Asynch_Result (handler_proxy,
03541                              act,
03542                              event,
03543                              0,
03544                              0,
03545                              priority,
03546                              signal_number),
03547     bytes_to_write_ (bytes_to_write),
03548     message_block_ (message_block),
03549     flags_ (flags),
03550     handle_ (handle)
03551 {
03552 }
03553 
03554 void
03555 ACE_WIN32_Asynch_Write_Dgram_Result::complete (size_t bytes_transferred,
03556                                                int success,
03557                                                const void *completion_key,
03558                                                u_long error)
03559 {
03560   // Copy the data which was returned by GetQueuedCompletionStatus
03561   this->bytes_transferred_ = bytes_transferred;
03562   this->success_ = success;
03563   this->completion_key_ = completion_key;
03564   this->error_ = error;
03565 
03566   // Appropriately move the pointers in the message block.
03567   for (ACE_Message_Block* mb = this->message_block_;
03568        (mb != 0) && (bytes_transferred > 0);
03569        mb = mb->cont ())
03570     {
03571       size_t len_part = mb->length ();
03572 
03573       if ( len_part > bytes_transferred)
03574         len_part = bytes_transferred;
03575 
03576       mb->rd_ptr (len_part);
03577 
03578       bytes_transferred -= len_part;
03579     }
03580 
03581   // Create the interface result class.
03582   ACE_Asynch_Write_Dgram::Result result (this);
03583 
03584   // Call the application handler.
03585   ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
03586   if (handler != 0)
03587     handler->handle_write_dgram (result);
03588 }
03589 
03590 ACE_WIN32_Asynch_Write_Dgram_Result::~ACE_WIN32_Asynch_Write_Dgram_Result (void)
03591 {
03592 }
03593 
03594 
03595 //***********************************************
03596 
03597 ACE_WIN32_Asynch_Write_Dgram::~ACE_WIN32_Asynch_Write_Dgram (void)
03598 {
03599 }
03600 
03601 ssize_t
03602 ACE_WIN32_Asynch_Write_Dgram::send (ACE_Message_Block *message_block,
03603                                     size_t &number_of_bytes_sent,
03604                                     int flags,
03605                                     const ACE_Addr &addr,
03606                                     const void *act,
03607                                     int priority,
03608                                     int signal_number)
03609 {
03610   number_of_bytes_sent = 0;
03611 
03612   size_t bytes_to_write = 0;
03613 
03614   iovec  iov[ACE_IOV_MAX];
03615   int    iovcnt = 0;
03616 
03617   for (const ACE_Message_Block* msg = message_block;
03618        msg != 0 && iovcnt < ACE_IOV_MAX;
03619        msg = msg->cont () , ++iovcnt )
03620   {
03621     size_t msg_len = msg->length ();
03622 
03623     // OS should process zero length block correctly
03624     // if ( msg_len == 0 )
03625     //   ACE_ERROR_RETURN ((LM_ERROR,
03626     //                      ACE_TEXT ("ACE_WIN32_Asynch_Write_Dgram::send:")
03627     //                      ACE_TEXT ("Zero-length message block\n")),
03628     //                     -1);
03629 
03630     bytes_to_write += msg_len;
03631 
03632     // Make as many iovec as needed to fit all of msg_len.
03633     size_t rd_ptr_offset = 0;
03634     while (msg_len > 0 && iovcnt < ACE_IOV_MAX)
03635       {
03636         u_long this_chunk_length;
03637         if (msg_len > ULONG_MAX)
03638           this_chunk_length = ULONG_MAX;
03639         else
03640           this_chunk_length = static_cast<u_long> (msg_len);
03641         // Collect the data in the iovec.
03642         iov[iovcnt].iov_base = msg->rd_ptr () + rd_ptr_offset;
03643         iov[iovcnt].iov_len  = this_chunk_length;
03644         msg_len -= this_chunk_length;
03645         rd_ptr_offset += this_chunk_length;
03646 
03647         // Increment iovec counter if there's more to do.
03648         if (msg_len > 0)
03649           iovcnt++;
03650       }
03651     if (msg_len > 0)       // Ran out of iovecs before msg_space exhausted
03652       {
03653         errno = ERANGE;
03654         return -1;
03655       }
03656   }
03657 
03658   if ( bytes_to_write == 0 )
03659       ACE_ERROR_RETURN ((LM_ERROR,
03660                          ACE_TEXT ("ACE_WIN32_Asynch_Write_Dgram::send:")
03661                          ACE_TEXT ("Attempt to write 0 bytes\n")),
03662                         -1);
03663 
03664   // Create the Asynch_Result.
03665   ACE_WIN32_Asynch_Write_Dgram_Result *result = 0;
03666   ACE_NEW_RETURN (result,
03667                   ACE_WIN32_Asynch_Write_Dgram_Result (this->handler_proxy_,
03668                                                        this->handle_,
03669                                                        message_block,
03670                                                        bytes_to_write,
03671                                                        flags,
03672                                                        act,
03673                                                        this->win32_proactor_->get_handle (),
03674                                                        priority,
03675                                                        signal_number),
03676                   -1);
03677 
03678   // do the scatter/gather send
03679 
03680   ssize_t initiate_result = ACE_OS::sendto (result->handle (),
03681                                             iov,
03682                                             iovcnt,
03683                                             number_of_bytes_sent,
03684                                             result->flags_,
03685                                             (sockaddr *) addr.get_addr (),
03686                                             addr.get_size(),
03687                                             result,
03688                                             0);
03689 
03690 
03691   if (initiate_result == SOCKET_ERROR)
03692   {
03693     // If initiate failed, check for a bad error.
03694     ACE_OS::set_errno_to_last_error ();
03695     switch (errno)
03696     {
03697       case ERROR_IO_PENDING:
03698         // The IO will complete proactively: the OVERLAPPED will still
03699         // get queued.
03700         initiate_result = 0;
03701         break;
03702 
03703       default:
03704         // Something else went wrong: the OVERLAPPED will not get
03705         // queued.
03706 
03707         if (ACE::debug ())
03708         {
03709           ACE_DEBUG ((LM_ERROR,
03710                       ACE_TEXT ("%p\n"),
03711                       ACE_TEXT ("WSASendTo")));
03712         }
03713 
03714         delete result;
03715         initiate_result = -1;
03716         break;
03717     }
03718 
03719   }
03720   else
03721   {
03722     // Immediate success: the OVERLAPPED will still get queued.
03723     // number_of_bytes_recvd contains the number of bytes recvd
03724     // addr contains the peer address
03725     // flags was updated
03726 
03727     // number_of_bytes_sent = bytes_sent;
03728     initiate_result = 1;
03729   }
03730 
03731   return initiate_result;
03732 }
03733 
03734 int
03735 ACE_WIN32_Asynch_Write_Dgram::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
03736                                     ACE_HANDLE handle,
03737                                     const void *completion_key,
03738                                     ACE_Proactor *proactor)
03739 {
03740   return ACE_WIN32_Asynch_Operation::open (handler_proxy,
03741                                            handle,
03742                                            completion_key,
03743                                            proactor);
03744 }
03745 
03746 int
03747 ACE_WIN32_Asynch_Write_Dgram::cancel (void)
03748 {
03749   return ACE_WIN32_Asynch_Operation::cancel ();
03750 }
03751 
03752 ACE_Proactor *
03753 ACE_WIN32_Asynch_Write_Dgram::proactor (void) const
03754 {
03755   return ACE_WIN32_Asynch_Operation::proactor ();
03756 }
03757 
03758 ACE_WIN32_Asynch_Write_Dgram::ACE_WIN32_Asynch_Write_Dgram (ACE_WIN32_Proactor *win32_proactor)
03759   : ACE_Asynch_Operation_Impl (),
03760     ACE_Asynch_Write_Dgram_Impl (),
03761     ACE_WIN32_Asynch_Operation (win32_proactor)
03762 {
03763 }
03764 
03765 ACE_END_VERSIONED_NAMESPACE_DECL
03766 
03767 #endif /* ACE_HAS_WIN32_OVERLAPPED_IO && ACE_HAS_WINSOCK2 */

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