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

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 Methods

 ACE_WIN32_Asynch_Read_Stream (ACE_WIN32_Proactor *win32_proactor)
 Constructor. More...

int read (ACE_Message_Block &message_block, size_t bytes_to_read, const void *act, int priority, int signal_number=0)
 This starts off an asynchronous read. Upto <bytes_to_read> will be read and stored in the <message_block>. More...

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. More...

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


Protected Methods

int shared_read (ACE_WIN32_Asynch_Read_Stream_Result *result)
 This is the method which does the real work and is there so that the ACE_Asynch_Read_File class can use it too. More...


Detailed Description

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

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

Definition at line 316 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 359 of file WIN32_Asynch_IO.cpp.

00360   : ACE_Asynch_Operation_Impl (),
00361     ACE_Asynch_Read_Stream_Impl (),
00362     ACE_WIN32_Asynch_Operation (win32_proactor)
00363 {
00364 }

ACE_WIN32_Asynch_Read_Stream::~ACE_WIN32_Asynch_Read_Stream void    [virtual]
 

Destructor.

Definition at line 539 of file WIN32_Asynch_IO.cpp.

00540 {
00541 }


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 608 of file WIN32_Asynch_IO.cpp.

References ACE_WIN32_Asynch_Operation::cancel.

00609 {
00610   return ACE_WIN32_Asynch_Operation::cancel ();
00611 }

int ACE_WIN32_Asynch_Read_Stream::open ACE_Handler   handler,
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 (<handle> == ACE_INVALID_HANDLE), <ACE_Handler::handle> will be called on the <handler> to get the correct handle.

Reimplemented from ACE_WIN32_Asynch_Operation.

Reimplemented in ACE_WIN32_Asynch_Read_File.

Definition at line 596 of file WIN32_Asynch_IO.cpp.

References ACE_WIN32_Asynch_Operation::open.

00600 {
00601   return ACE_WIN32_Asynch_Operation::open (handler,
00602                                            handle,
00603                                            completion_key,
00604                                            proactor);
00605 }

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 614 of file WIN32_Asynch_IO.cpp.

References ACE_WIN32_Asynch_Operation::proactor.

00615 {
00616   return ACE_WIN32_Asynch_Operation::proactor ();
00617 }

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 <bytes_to_read> will be read and stored in the <message_block>.

Implements ACE_Asynch_Read_Stream_Impl.

Reimplemented in ACE_WIN32_Asynch_Read_File.

Definition at line 367 of file WIN32_Asynch_IO.cpp.

References ACE_NEW_RETURN, shared_read, ACE_Message_Block::space, and ssize_t.

Referenced by ACE_WIN32_Asynch_Read_File::read.

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 }

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 407 of file WIN32_Asynch_IO.cpp.

References ACE_ASSERT, ACE_DEBUG, ACE_ERROR_RETURN, ACE_IOV_MAX, ACE_LIB_TEXT, ACE_NEW_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.

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 }

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 544 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.

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 }


The documentation for this class was generated from the following files:
Generated on Mon Jun 16 13:00:10 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002