ACE_WIN32_Asynch_Read_Stream Class Reference

This class is a factory for starting off asynchronous reads on a stream. More...

#include <WIN32_Asynch_IO.h>

Inheritance diagram for ACE_WIN32_Asynch_Read_Stream:

Inheritance graph
[legend]
Collaboration diagram for ACE_WIN32_Asynch_Read_Stream:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 ACE_WIN32_Asynch_Read_Stream (ACE_WIN32_Proactor *win32_proactor)
 Constructor.

int read (ACE_Message_Block &message_block, size_t bytes_to_read, const void *act, int priority, int signal_number=0)
int readv (ACE_Message_Block &message_block, size_t bytes_to_read, const void *act, int priority, int signal_number=0)
virtual ~ACE_WIN32_Asynch_Read_Stream (void)
 Destructor.

int open (const ACE_Handler::Proxy_Ptr &handler_proxy, ACE_HANDLE handle, const void *completion_key, ACE_Proactor *proactor)
int cancel (void)
ACE_Proactorproactor (void) const
 Return the underlying proactor.


Protected Member Functions

int shared_read (ACE_WIN32_Asynch_Read_Stream_Result *result)

Detailed Description

This class is a factory for starting off asynchronous reads on a stream.

Once is called, multiple asynchronous s can started using this class. An ACE_Asynch_Read_Stream::Result will be passed back to the when the asynchronous reads completes through the <ACE_Handler::handle_read_stream> callback.

Definition at line 318 of file WIN32_Asynch_IO.h.


Constructor & Destructor Documentation

ACE_WIN32_Asynch_Read_Stream::ACE_WIN32_Asynch_Read_Stream ACE_WIN32_Proactor win32_proactor  ) 
 

Constructor.

Definition at line 378 of file WIN32_Asynch_IO.cpp.

00379   : ACE_Asynch_Operation_Impl (),
00380     ACE_Asynch_Read_Stream_Impl (),
00381     ACE_WIN32_Asynch_Operation (win32_proactor)
00382 {
00383 }

ACE_WIN32_Asynch_Read_Stream::~ACE_WIN32_Asynch_Read_Stream void   )  [virtual]
 

Destructor.

Definition at line 566 of file WIN32_Asynch_IO.cpp.

00567 {
00568 }


Member Function Documentation

int ACE_WIN32_Asynch_Read_Stream::cancel void   )  [virtual]
 

This cancels all pending accepts operations that were issued by the calling thread. The function does not cancel asynchronous operations issued by other threads.

Reimplemented from ACE_WIN32_Asynch_Operation.

Reimplemented in ACE_WIN32_Asynch_Read_File.

Definition at line 637 of file WIN32_Asynch_IO.cpp.

References ACE_WIN32_Asynch_Operation::cancel().

00638 {
00639   return ACE_WIN32_Asynch_Operation::cancel ();
00640 }

int ACE_WIN32_Asynch_Read_Stream::open const ACE_Handler::Proxy_Ptr handler_proxy,
ACE_HANDLE  handle,
const void *  completion_key,
ACE_Proactor proactor
[virtual]
 

Initializes the factory with information which will be used with each asynchronous call. If ( == ACE_INVALID_HANDLE), <ACE_Handler::handle> will be called on the to get the correct handle.

Reimplemented from ACE_WIN32_Asynch_Operation.

Reimplemented in ACE_WIN32_Asynch_Read_File.

Definition at line 625 of file WIN32_Asynch_IO.cpp.

References ACE_WIN32_Asynch_Operation::open(), and ACE_Handler::Proxy_Ptr.

00629 {
00630   return ACE_WIN32_Asynch_Operation::open (handler_proxy,
00631                                            handle,
00632                                            completion_key,
00633                                            proactor);
00634 }

ACE_Proactor * ACE_WIN32_Asynch_Read_Stream::proactor void   )  const [virtual]
 

Return the underlying proactor.

Reimplemented from ACE_WIN32_Asynch_Operation.

Reimplemented in ACE_WIN32_Asynch_Read_File.

Definition at line 643 of file WIN32_Asynch_IO.cpp.

References ACE_WIN32_Asynch_Operation::proactor().

00644 {
00645   return ACE_WIN32_Asynch_Operation::proactor ();
00646 }

int ACE_WIN32_Asynch_Read_Stream::read ACE_Message_Block message_block,
size_t  bytes_to_read,
const void *  act,
int  priority,
int  signal_number = 0
[virtual]
 

This starts off an asynchronous read. Upto will be read and stored in the .

Implements ACE_Asynch_Read_Stream_Impl.

Reimplemented in ACE_WIN32_Asynch_Read_File.

Definition at line 386 of file WIN32_Asynch_IO.cpp.

References ACE_NEW_RETURN, shared_read(), and ACE_Message_Block::space().

Referenced by ACE_WIN32_Asynch_Read_File::read().

00391 {
00392   size_t space = message_block.space ();
00393   if (bytes_to_read > space)
00394     bytes_to_read = space;
00395 
00396   if (bytes_to_read == 0)
00397     {
00398       errno = ENOSPC;
00399       return -1;
00400     }
00401 
00402   // Create the Asynch_Result.
00403   ACE_WIN32_Asynch_Read_Stream_Result *result = 0;
00404   ACE_NEW_RETURN (result,
00405                   ACE_WIN32_Asynch_Read_Stream_Result (this->handler_proxy_,
00406                                                        this->handle_,
00407                                                        message_block,
00408                                                        bytes_to_read,
00409                                                        act,
00410                                                        this->win32_proactor_->get_handle (),
00411                                                        priority,
00412                                                        signal_number),
00413                   -1);
00414 
00415   // Shared read
00416   int const return_val = this->shared_read (result);
00417 
00418   // Upon errors
00419   if (return_val == -1)
00420     delete result;
00421 
00422   return return_val;
00423 }

int ACE_WIN32_Asynch_Read_Stream::readv ACE_Message_Block message_block,
size_t  bytes_to_read,
const void *  act,
int  priority,
int  signal_number = 0
[virtual]
 

Same as above but with scatter support, through chaining of composite message blocks using the continuation field.

Implements ACE_Asynch_Read_Stream_Impl.

Reimplemented in ACE_WIN32_Asynch_Read_File.

Definition at line 426 of file WIN32_Asynch_IO.cpp.

References ACE_ASSERT, ACE_DEBUG, ACE_ERROR_RETURN, ACE_IOV_MAX, ACE_LIB_TEXT, ACE_NEW_RETURN, ACE_NOTSUP_RETURN, ACE_Message_Block::cont(), ACE::debug(), ACE_WIN32_Asynch_Read_Stream_Result::handle(), iovec::iov_base, iovec::iov_len, LM_ERROR, ACE_OS::set_errno_to_last_error(), ACE_WIN32_Asynch_Result::set_error(), ACE_Message_Block::space(), and ACE_Message_Block::wr_ptr().

Referenced by ACE_WIN32_Asynch_Read_File::readv().

00431 {
00432 #if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
00433   iovec  iov[ACE_IOV_MAX];
00434   int    iovcnt = 0;
00435 
00436   // We should not read more than user requested,
00437   // but it is allowed to read less
00438 
00439   for (const ACE_Message_Block* msg = &message_block;
00440        msg != 0 && bytes_to_read > 0 && iovcnt < ACE_IOV_MAX;
00441        msg = msg->cont () , ++iovcnt )
00442   {
00443     size_t msg_space = msg->space ();
00444 
00445     // OS should correctly process zero length buffers
00446     // if ( msg_space == 0 )
00447     //   ACE_ERROR_RETURN ((LM_ERROR,
00448     //                      ACE_LIB_TEXT ("ACE_WIN32_Asynch_Read_Stream::readv:")
00449     //                      ACE_LIB_TEXT ("No space in the message block\n")),
00450     //                     -1);
00451 
00452     if (msg_space > bytes_to_read)
00453       msg_space = bytes_to_read;
00454     bytes_to_read -= msg_space;
00455 
00456     // Make as many iovec as needed to fit all of msg_space.
00457     size_t wr_ptr_offset = 0;
00458     while (msg_space > 0 && iovcnt < ACE_IOV_MAX)
00459       {
00460         u_long this_chunk_length;
00461         if (msg_space > ULONG_MAX)
00462           this_chunk_length = ULONG_MAX;
00463         else
00464           this_chunk_length = static_cast<u_long> (msg_space);
00465         // Collect the data in the iovec.
00466         iov[iovcnt].iov_base = msg->wr_ptr () + wr_ptr_offset;
00467         iov[iovcnt].iov_len  = this_chunk_length;
00468         msg_space -= this_chunk_length;
00469         wr_ptr_offset += this_chunk_length;
00470 
00471         // Increment iovec counter if there's more to do.
00472         if (msg_space > 0)
00473           ++iovcnt;
00474       }
00475     if (msg_space > 0)       // Ran out of iovecs before msg_space exhausted
00476       {
00477         errno = ERANGE;
00478         return -1;
00479       }
00480   }
00481 
00482   // Re-calculate number bytes to read
00483   bytes_to_read = 0;
00484 
00485   for (int i = 0; i < iovcnt ; ++i)
00486     bytes_to_read += iov[i].iov_len;
00487 
00488   if (bytes_to_read == 0)
00489       ACE_ERROR_RETURN ((LM_ERROR,
00490                          ACE_LIB_TEXT ("ACE_WIN32_Asynch_Read_Stream::readv:")
00491                          ACE_LIB_TEXT ("Attempt to read 0 bytes\n")),
00492                         -1);
00493 
00494   // Create the Asynch_Result.
00495   ACE_WIN32_Asynch_Read_Stream_Result *result = 0;
00496   ACE_NEW_RETURN (result,
00497                   ACE_WIN32_Asynch_Read_Stream_Result (this->handler_proxy_,
00498                                                        this->handle_,
00499                                                        message_block,
00500                                                        bytes_to_read,
00501                                                        act,
00502                                                        this->win32_proactor_->get_handle (),
00503                                                        priority,
00504                                                        signal_number,
00505                                                        1), // scatter read enabled
00506                   -1);
00507 
00508   // do the scatter recv
00509 
00510   result->set_error (0); // Clear error before starting IO.
00511 
00512   DWORD bytes_recvd = 0;
00513   u_long flags = 0;
00514 
00515   int initiate_result = ::WSARecv (reinterpret_cast<SOCKET> (result->handle ()),
00516                                    reinterpret_cast<WSABUF *> (iov),
00517                                    iovcnt,
00518                                    &bytes_recvd,
00519                                    &flags,
00520                                    result,
00521                                    0);
00522 
00523   if (0 == initiate_result)
00524     // Immediate success: the OVERLAPPED will still get queued.
00525     return 1;
00526 
00527   ACE_ASSERT (initiate_result == SOCKET_ERROR);
00528 
00529   // If initiate failed, check for a bad error.
00530   ACE_OS::set_errno_to_last_error ();
00531   switch (errno)
00532   {
00533     case ERROR_IO_PENDING:
00534       // The IO will complete proactively: the OVERLAPPED will still
00535       // get queued.
00536       initiate_result = 0;
00537       break;
00538 
00539     default:
00540       // Something else went wrong: the OVERLAPPED will not get
00541       // queued.
00542 
00543       if (ACE::debug ())
00544       {
00545         ACE_DEBUG ((LM_ERROR,
00546                     ACE_LIB_TEXT ("%p\n"),
00547                     ACE_LIB_TEXT ("WSARecv")));
00548       }
00549 
00550       delete result;
00551       initiate_result = -1;
00552       break;
00553   }
00554 
00555   return initiate_result;
00556 #else
00557   ACE_UNUSED_ARG (message_block);
00558   ACE_UNUSED_ARG (bytes_to_read);
00559   ACE_UNUSED_ARG (act);
00560   ACE_UNUSED_ARG (priority);
00561   ACE_UNUSED_ARG (signal_number);
00562   ACE_NOTSUP_RETURN (-1);
00563 #endif /* ACE_HAS_WINSOCK2 && ACE_HAS_WINSOCK2 != 0 */
00564 }

int ACE_WIN32_Asynch_Read_Stream::shared_read ACE_WIN32_Asynch_Read_Stream_Result result  )  [protected]
 

This is the method which does the real work and is there so that the ACE_Asynch_Read_File class can use it too.

Definition at line 571 of file WIN32_Asynch_IO.cpp.

References ACE_DEBUG, ACE_LIB_TEXT, ACE_WIN32_Asynch_Read_Stream_Result::bytes_to_read(), ACE::debug(), ACE_WIN32_Asynch_Read_Stream_Result::handle(), LM_ERROR, ACE_WIN32_Asynch_Read_Stream_Result::message_block(), ACE_OS::set_errno_to_last_error(), ACE_WIN32_Asynch_Result::set_error(), and ACE_Message_Block::wr_ptr().

Referenced by ACE_WIN32_Asynch_Read_File::read(), and read().

00572 {
00573   // ReadFile API limits us to DWORD range.
00574   if (result->bytes_to_read () > MAXDWORD)
00575     {
00576       errno = ERANGE;
00577       return -1;
00578     }
00579   DWORD bytes_to_read = static_cast<DWORD> (result->bytes_to_read ());
00580   u_long bytes_read;
00581 
00582   result->set_error (0); // Clear error before starting IO.
00583 
00584   // Initiate the read
00585   int initiate_result = ::ReadFile (result->handle (),
00586                                     result->message_block ().wr_ptr (),
00587                                     bytes_to_read,
00588                                     &bytes_read,
00589                                     result);
00590   if (initiate_result == 1)
00591     // Immediate success: the OVERLAPPED will still get queued.
00592     return 0;
00593 
00594   // If initiate failed, check for a bad error.
00595   ACE_OS::set_errno_to_last_error ();
00596   switch (errno)
00597     {
00598     case ERROR_IO_PENDING:
00599       /* FALLTHRU */
00600     case ERROR_MORE_DATA:
00601       // The IO will complete proactively: the OVERLAPPED will still
00602       // get queued.
00603       return 0;
00604 
00605     default:
00606       // Something else went wrong: the OVERLAPPED will not get
00607       // queued.
00608 
00609       if (ACE::debug ())
00610         {
00611           ACE_DEBUG ((LM_ERROR,
00612                       ACE_LIB_TEXT ("%p\n"),
00613                       ACE_LIB_TEXT ("ReadFile")));
00614         }
00615 
00616       return -1;
00617     }
00618 }


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 11:33:01 2006 for ACE by doxygen 1.3.6