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

ACE_WIN32_Asynch_Write_Stream Class Reference

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

#include <WIN32_Asynch_IO.h>

Inheritance diagram for ACE_WIN32_Asynch_Write_Stream:

Inheritance graph
[legend]
Collaboration diagram for ACE_WIN32_Asynch_Write_Stream:

Collaboration graph
[legend]
List of all members.

Public Methods

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

int write (ACE_Message_Block &message_block, size_t bytes_to_write, const void *act, int priority, int signal_number=0)
 This starts off an asynchronous write. Upto <bytes_to_write> will be written from the <message_block>. More...

int writev (ACE_Message_Block &message_block, size_t bytes_to_write, const void *act, int priority, int signal_number=0)
virtual ~ACE_WIN32_Asynch_Write_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_write (ACE_WIN32_Asynch_Write_Stream_Result *result)
 This is the method which does the real work and is there so that the ACE_Asynch_Write_File class can use it too. More...


Detailed Description

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

Once <open> is called, multiple asynchronous <writes>s can started using this class. A ACE_Asynch_Write_Stream::Result will be passed back to the <handler> when the asynchronous write completes through the <ACE_Handler::handle_write_stream> callback.

Definition at line 495 of file WIN32_Asynch_IO.h.


Constructor & Destructor Documentation

ACE_WIN32_Asynch_Write_Stream::ACE_WIN32_Asynch_Write_Stream ACE_WIN32_Proactor   win32_proactor
 

Constructor.

Definition at line 774 of file WIN32_Asynch_IO.cpp.

00775   : ACE_Asynch_Operation_Impl (),
00776     ACE_Asynch_Write_Stream_Impl (),
00777     ACE_WIN32_Asynch_Operation (win32_proactor)
00778 {
00779 }

ACE_WIN32_Asynch_Write_Stream::~ACE_WIN32_Asynch_Write_Stream void    [virtual]
 

Destructor.

Definition at line 951 of file WIN32_Asynch_IO.cpp.

00952 {
00953 }


Member Function Documentation

int ACE_WIN32_Asynch_Write_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_Write_File.

Definition at line 1018 of file WIN32_Asynch_IO.cpp.

References ACE_WIN32_Asynch_Operation::cancel.

01019 {
01020   return ACE_WIN32_Asynch_Operation::cancel ();
01021 }

int ACE_WIN32_Asynch_Write_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_Write_File.

Definition at line 1006 of file WIN32_Asynch_IO.cpp.

References ACE_WIN32_Asynch_Operation::open.

01010 {
01011   return ACE_WIN32_Asynch_Operation::open (handler,
01012                                            handle,
01013                                            completion_key,
01014                                            proactor);
01015 }

ACE_Proactor * ACE_WIN32_Asynch_Write_Stream::proactor void    const [virtual]
 

Return the underlying proactor.

Reimplemented from ACE_WIN32_Asynch_Operation.

Reimplemented in ACE_WIN32_Asynch_Write_File.

Definition at line 1024 of file WIN32_Asynch_IO.cpp.

References ACE_WIN32_Asynch_Operation::proactor.

01025 {
01026   return ACE_WIN32_Asynch_Operation::proactor ();
01027 }

int ACE_WIN32_Asynch_Write_Stream::shared_write ACE_WIN32_Asynch_Write_Stream_Result   result [protected]
 

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

Definition at line 956 of file WIN32_Asynch_IO.cpp.

References ACE_DEBUG, ACE_LIB_TEXT, ACE_WIN32_Asynch_Write_Stream_Result::bytes_to_write, ACE::debug, ACE_WIN32_Asynch_Write_Stream_Result::handle, LM_ERROR, ACE_WIN32_Asynch_Write_Stream_Result::message_block, ACE_Message_Block::rd_ptr, ACE_OS::set_errno_to_last_error, and ACE_WIN32_Asynch_Result::set_error.

Referenced by ACE_WIN32_Asynch_Write_File::write, and write.

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 }

int ACE_WIN32_Asynch_Write_Stream::write ACE_Message_Block   message_block,
size_t    bytes_to_write,
const void *    act,
int    priority,
int    signal_number = 0
[virtual]
 

This starts off an asynchronous write. Upto <bytes_to_write> will be written from the <message_block>.

Implements ACE_Asynch_Write_Stream_Impl.

Reimplemented in ACE_WIN32_Asynch_Write_File.

Definition at line 782 of file WIN32_Asynch_IO.cpp.

References ACE_ERROR_RETURN, ACE_LIB_TEXT, ACE_NEW_RETURN, ACE_Message_Block::length, LM_ERROR, shared_write, and ssize_t.

Referenced by ACE_WIN32_Asynch_Write_File::write.

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 }

int ACE_WIN32_Asynch_Write_Stream::writev ACE_Message_Block   message_block,
size_t    bytes_to_write,
const void *    act,
int    priority,
int    signal_number = 0
[virtual]
 

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

Implements ACE_Asynch_Write_Stream_Impl.

Reimplemented in ACE_WIN32_Asynch_Write_File.

Definition at line 823 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_Write_Stream_Result::handle, iovec::iov_base, iovec::iov_len, ACE_Message_Block::length, LM_ERROR, ACE_Message_Block::rd_ptr, and ACE_OS::set_errno_to_last_error.

Referenced by ACE_WIN32_Asynch_Write_File::writev.

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 }


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