WIN32_Asynch_IO.cpp

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

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