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 Member Functions

 ACE_WIN32_Asynch_Write_Stream (ACE_WIN32_Proactor *win32_proactor)
 Constructor.

int write (ACE_Message_Block &message_block, size_t bytes_to_write, const void *act, int priority, int signal_number=0)
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.

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_write (ACE_WIN32_Asynch_Write_Stream_Result *result)

Detailed Description

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

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

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

00808   : ACE_Asynch_Operation_Impl (),
00809     ACE_Asynch_Write_Stream_Impl (),
00810     ACE_WIN32_Asynch_Operation (win32_proactor)
00811 {
00812 }

ACE_WIN32_Asynch_Write_Stream::~ACE_WIN32_Asynch_Write_Stream void   )  [virtual]
 

Destructor.

Definition at line 990 of file WIN32_Asynch_IO.cpp.

00991 {
00992 }


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

References ACE_WIN32_Asynch_Operation::cancel().

01056 {
01057   return ACE_WIN32_Asynch_Operation::cancel ();
01058 }

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

Definition at line 1043 of file WIN32_Asynch_IO.cpp.

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

01047 {
01048   return ACE_WIN32_Asynch_Operation::open (handler_proxy,
01049                                            handle,
01050                                            completion_key,
01051                                            proactor);
01052 }

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

References ACE_WIN32_Asynch_Operation::proactor().

01062 {
01063   return ACE_WIN32_Asynch_Operation::proactor ();
01064 }

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 995 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().

00996 {
00997   u_long bytes_written;
00998   if (result->bytes_to_write () > MAXDWORD)
00999     {
01000       errno = ERANGE;
01001       return -1;
01002     }
01003   DWORD bytes_to_write = static_cast<DWORD> (result->bytes_to_write ());
01004 
01005   result->set_error (0); // Clear error before starting IO.
01006 
01007   // Initiate the write
01008   int initiate_result = ::WriteFile (result->handle (),
01009                                      result->message_block ().rd_ptr (),
01010                                      bytes_to_write,
01011                                      &bytes_written,
01012                                      result);
01013   if (initiate_result == 1)
01014     // Immediate success: the OVERLAPPED will still get queued.
01015     return 0;
01016 
01017   // If initiate failed, check for a bad error.
01018   ACE_OS::set_errno_to_last_error ();
01019   switch (errno)
01020     {
01021     case ERROR_IO_PENDING:
01022       // The IO will complete proactively: the OVERLAPPED will still
01023       // get queued.
01024       return 0;
01025 
01026     default:
01027       // Something else went wrong: the OVERLAPPED will not get
01028       // queued.
01029 
01030       if (ACE::debug ())
01031         ACE_DEBUG ((LM_ERROR,
01032                     ACE_LIB_TEXT ("%p\n"),
01033                     ACE_LIB_TEXT ("WriteFile")));
01034       return -1;
01035     }
01036 }

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 will be written from the .

Implements ACE_Asynch_Write_Stream_Impl.

Reimplemented in ACE_WIN32_Asynch_Write_File.

Definition at line 815 of file WIN32_Asynch_IO.cpp.

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

Referenced by ACE_WIN32_Asynch_Write_File::write().

00820 {
00821   size_t len = message_block.length();
00822 
00823   if (bytes_to_write > len)
00824      bytes_to_write = len ;
00825 
00826   if (bytes_to_write == 0)
00827     ACE_ERROR_RETURN
00828       ((LM_ERROR,
00829         ACE_LIB_TEXT ("ACE_WIN32_Asynch_Write_Stream::write:")
00830         ACE_LIB_TEXT ("Attempt to write 0 bytes\n")),
00831        -1);
00832 
00833   ACE_WIN32_Asynch_Write_Stream_Result *result = 0;
00834   ACE_NEW_RETURN (result,
00835                   ACE_WIN32_Asynch_Write_Stream_Result (this->handler_proxy_,
00836                                                         this->handle_,
00837                                                         message_block,
00838                                                         bytes_to_write,
00839                                                         act,
00840                                                         this->win32_proactor_->get_handle (),
00841                                                         priority,
00842                                                         signal_number),
00843                   -1);
00844 
00845   // Shared write
00846   int return_val = this->shared_write (result);
00847 
00848   // Upon errors
00849   if (return_val == -1)
00850     delete result;
00851 
00852   return return_val;
00853 }

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 856 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_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().

00861 {
00862 #if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
00863   iovec  iov[ACE_IOV_MAX];
00864   int    iovcnt = 0;
00865 
00866   // We should not write more than user requested,
00867   // but it is allowed to write less
00868 
00869   for (const ACE_Message_Block* msg = &message_block;
00870        msg != 0 && bytes_to_write > 0 && iovcnt < ACE_IOV_MAX;
00871        msg = msg->cont ())
00872   {
00873     size_t msg_len = msg->length ();
00874 
00875     // Skip 0-length blocks.
00876     if (msg_len == 0)
00877       continue;
00878     if (msg_len > bytes_to_write)
00879       msg_len = bytes_to_write;
00880     bytes_to_write -= msg_len;
00881 
00882     // Make as many iovec as needed to fit all of msg_len.
00883     size_t rd_ptr_offset = 0;
00884     while (msg_len > 0 && iovcnt < ACE_IOV_MAX)
00885       {
00886         u_long this_chunk_length;
00887         if (msg_len > ULONG_MAX)
00888           this_chunk_length = ULONG_MAX;
00889         else
00890           this_chunk_length = static_cast<u_long> (msg_len);
00891         // Collect the data in the iovec.
00892         iov[iovcnt].iov_base = msg->rd_ptr () + rd_ptr_offset;
00893         iov[iovcnt].iov_len  = this_chunk_length;
00894         msg_len -= this_chunk_length;
00895         rd_ptr_offset += this_chunk_length;
00896 
00897         // Increment iovec counter if there's more to do.
00898         if (msg_len > 0)
00899           iovcnt++;
00900       }
00901     if (msg_len > 0)       // Ran out of iovecs before msg_space exhausted
00902       {
00903         errno = ERANGE;
00904         return -1;
00905       }
00906     ++iovcnt;
00907   }
00908 
00909   // Re-calculate number bytes to write
00910   bytes_to_write = 0;
00911 
00912   for ( int i=0; i < iovcnt ; ++i )
00913     bytes_to_write += iov[i].iov_len;
00914 
00915   if ( bytes_to_write == 0 )
00916       ACE_ERROR_RETURN ((LM_ERROR,
00917                          ACE_LIB_TEXT ("ACE_WIN32_Asynch_Write_Stream::writev:")
00918                          ACE_LIB_TEXT ("Attempt to write 0 bytes\n")),
00919                         -1);
00920 
00921 
00922   ACE_WIN32_Asynch_Write_Stream_Result *result = 0;
00923   ACE_NEW_RETURN (result,
00924                   ACE_WIN32_Asynch_Write_Stream_Result (this->handler_proxy_,
00925                                                         this->handle_,
00926                                                         message_block,
00927                                                         bytes_to_write,
00928                                                         act,
00929                                                         this->win32_proactor_->get_handle (),
00930                                                         priority,
00931                                                         signal_number,
00932                                                         1), // gather write enabled
00933                   -1);
00934 
00935   // do the gather send
00936 
00937   u_long bytes_sent = 0;
00938 
00939   int initiate_result = ::WSASend (reinterpret_cast<SOCKET> (result->handle ()),
00940                                    reinterpret_cast<WSABUF *> (iov),
00941                                    iovcnt,
00942                                    &bytes_sent,
00943                                    0, // flags
00944                                    result,
00945                                    0);
00946 
00947   if (0 == initiate_result)
00948     // Immediate success: the OVERLAPPED will still get queued.
00949     return 1;
00950 
00951   ACE_ASSERT (initiate_result == SOCKET_ERROR);
00952 
00953   // If initiate failed, check for a bad error.
00954   ACE_OS::set_errno_to_last_error ();
00955   switch (errno)
00956   {
00957     case ERROR_IO_PENDING:
00958       // The IO will complete proactively: the OVERLAPPED will still
00959       // get queued.
00960       initiate_result = 0;
00961       break;
00962 
00963     default:
00964       // Something else went wrong: the OVERLAPPED will not get
00965       // queued.
00966 
00967       if (ACE::debug ())
00968       {
00969         ACE_DEBUG ((LM_ERROR,
00970                     ACE_LIB_TEXT ("%p\n"),
00971                     ACE_LIB_TEXT ("WSASend")));
00972       }
00973 
00974       delete result;
00975       initiate_result = -1;
00976       break;
00977   }
00978 
00979   return initiate_result;
00980 #else
00981   ACE_UNUSED_ARG (message_block);
00982   ACE_UNUSED_ARG (bytes_to_write);
00983   ACE_UNUSED_ARG (act);
00984   ACE_UNUSED_ARG (priority);
00985   ACE_UNUSED_ARG (signal_number);
00986   ACE_NOTSUP_RETURN (-1);
00987 #endif /* ACE_HAS_WINSOCK2 && ACE_HAS_WINSOCK2 != 0 */
00988 }


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