Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

WIN32_Asynch_IO.cpp

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

Generated on Mon Jun 16 11:22:10 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002