WIN32_Asynch_IO.cpp

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

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