ACE_WIN32_Asynch_Write_Dgram Class Reference

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

#include <WIN32_Asynch_IO.h>

Inheritance diagram for ACE_WIN32_Asynch_Write_Dgram:

Inheritance graph
[legend]
Collaboration diagram for ACE_WIN32_Asynch_Write_Dgram:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 ACE_WIN32_Asynch_Write_Dgram (ACE_WIN32_Proactor *win32_proactor)
 Constructor.

virtual ~ACE_WIN32_Asynch_Write_Dgram (void)
 Destructor.

virtual ssize_t send (ACE_Message_Block *message_block, size_t &number_of_bytes_sent, int flags, const ACE_Addr &addr, const void *act, int priority, int signal_number)
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

 ACE_WIN32_Asynch_Write_Dgram (void)
 Do-nothing constructor.


Detailed Description

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

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 1866 of file WIN32_Asynch_IO.h.


Constructor & Destructor Documentation

ACE_WIN32_Asynch_Write_Dgram::ACE_WIN32_Asynch_Write_Dgram ACE_WIN32_Proactor win32_proactor  ) 
 

Constructor.

Definition at line 3746 of file WIN32_Asynch_IO.cpp.

03747   : ACE_Asynch_Operation_Impl (),
03748     ACE_Asynch_Write_Dgram_Impl (),
03749     ACE_WIN32_Asynch_Operation (win32_proactor)
03750 {
03751 }

ACE_WIN32_Asynch_Write_Dgram::~ACE_WIN32_Asynch_Write_Dgram void   )  [virtual]
 

Destructor.

Definition at line 3585 of file WIN32_Asynch_IO.cpp.

03586 {
03587 }

ACE_WIN32_Asynch_Write_Dgram::ACE_WIN32_Asynch_Write_Dgram void   )  [protected]
 

Do-nothing constructor.


Member Function Documentation

int ACE_WIN32_Asynch_Write_Dgram::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.

Definition at line 3735 of file WIN32_Asynch_IO.cpp.

References ACE_WIN32_Asynch_Operation::cancel().

03736 {
03737   return ACE_WIN32_Asynch_Operation::cancel ();
03738 }

int ACE_WIN32_Asynch_Write_Dgram::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.

Definition at line 3723 of file WIN32_Asynch_IO.cpp.

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

03727 {
03728   return ACE_WIN32_Asynch_Operation::open (handler_proxy,
03729                                            handle,
03730                                            completion_key,
03731                                            proactor);
03732 }

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

Return the underlying proactor.

Reimplemented from ACE_WIN32_Asynch_Operation.

Definition at line 3741 of file WIN32_Asynch_IO.cpp.

References ACE_WIN32_Asynch_Operation::proactor().

03742 {
03743   return ACE_WIN32_Asynch_Operation::proactor ();
03744 }

ssize_t ACE_WIN32_Asynch_Write_Dgram::send ACE_Message_Block message_block,
size_t &  number_of_bytes_sent,
int  flags,
const ACE_Addr addr,
const void *  act,
int  priority,
int  signal_number
[virtual]
 

This starts off an asynchronous send. Upto <message_block->total_length()> will be sent. 's will be updated to reflect the sent bytes if the send operation is successfully completed. Return code of 1 means immediate success and is updated to number of bytes sent. The <ACE_Handler::handle_write_dgram> method will still be called. Return code of 0 means the IO will complete proactively. Return code of -1 means there was an error, use errno to get the error code.

Scatter/gather is supported on WIN32 by using the <message_block->cont()> method. Up to ACE_IOV_MAX 's are supported. Upto <message_block->length()> bytes will be sent from each for a total of <message_block->total_length()> bytes. All 's 's will be updated to reflect the bytes sent from each .

Implements ACE_Asynch_Write_Dgram_Impl.

Definition at line 3590 of file WIN32_Asynch_IO.cpp.

References ACE_DEBUG, ACE_ERROR_RETURN, ACE_IOV_MAX, ACE_LIB_TEXT, ACE_NEW_RETURN, ACE_Message_Block::cont(), ACE::debug(), ACE_WIN32_Asynch_Write_Dgram_Result::flags_, ACE_Addr::get_addr(), ACE_Addr::get_size(), ACE_WIN32_Asynch_Write_Dgram_Result::handle(), iovec::iov_base, iovec::iov_len, ACE_Message_Block::length(), LM_ERROR, ACE_Message_Block::rd_ptr(), ACE_OS::sendto(), ACE_OS::set_errno_to_last_error(), and ssize_t.

03597 {
03598   number_of_bytes_sent = 0;
03599 
03600   size_t bytes_to_write = 0;
03601 
03602   iovec  iov[ACE_IOV_MAX];
03603   int    iovcnt = 0;
03604 
03605   for (const ACE_Message_Block* msg = message_block;
03606        msg != 0 && iovcnt < ACE_IOV_MAX;
03607        msg = msg->cont () , ++iovcnt )
03608   {
03609     size_t msg_len = msg->length ();
03610 
03611     // OS should process zero length block correctly
03612     // if ( msg_len == 0 )
03613     //   ACE_ERROR_RETURN ((LM_ERROR,
03614     //                      ACE_LIB_TEXT ("ACE_WIN32_Asynch_Write_Dgram::send:")
03615     //                      ACE_LIB_TEXT ("Zero-length message block\n")),
03616     //                     -1);
03617 
03618     bytes_to_write += msg_len;
03619 
03620     // Make as many iovec as needed to fit all of msg_len.
03621     size_t rd_ptr_offset = 0;
03622     while (msg_len > 0 && iovcnt < ACE_IOV_MAX)
03623       {
03624         u_long this_chunk_length;
03625         if (msg_len > ULONG_MAX)
03626           this_chunk_length = ULONG_MAX;
03627         else
03628           this_chunk_length = static_cast<u_long> (msg_len);
03629         // Collect the data in the iovec.
03630         iov[iovcnt].iov_base = msg->rd_ptr () + rd_ptr_offset;
03631         iov[iovcnt].iov_len  = this_chunk_length;
03632         msg_len -= this_chunk_length;
03633         rd_ptr_offset += this_chunk_length;
03634 
03635         // Increment iovec counter if there's more to do.
03636         if (msg_len > 0)
03637           iovcnt++;
03638       }
03639     if (msg_len > 0)       // Ran out of iovecs before msg_space exhausted
03640       {
03641         errno = ERANGE;
03642         return -1;
03643       }
03644   }
03645 
03646   if ( bytes_to_write == 0 )
03647       ACE_ERROR_RETURN ((LM_ERROR,
03648                          ACE_LIB_TEXT ("ACE_WIN32_Asynch_Write_Dgram::send:")
03649                          ACE_LIB_TEXT ("Attempt to write 0 bytes\n")),
03650                         -1);
03651 
03652   // Create the Asynch_Result.
03653   ACE_WIN32_Asynch_Write_Dgram_Result *result = 0;
03654   ACE_NEW_RETURN (result,
03655                   ACE_WIN32_Asynch_Write_Dgram_Result (this->handler_proxy_,
03656                                                        this->handle_,
03657                                                        message_block,
03658                                                        bytes_to_write,
03659                                                        flags,
03660                                                        act,
03661                                                        this->win32_proactor_->get_handle (),
03662                                                        priority,
03663                                                        signal_number),
03664                   -1);
03665 
03666   // do the scatter/gather send
03667 
03668   ssize_t initiate_result = ACE_OS::sendto (result->handle (),
03669                                             iov,
03670                                             iovcnt,
03671                                             number_of_bytes_sent,
03672                                             result->flags_,
03673                                             (sockaddr *) addr.get_addr (),
03674                                             addr.get_size(),
03675                                             result,
03676                                             0);
03677 
03678 
03679   if (initiate_result == SOCKET_ERROR)
03680   {
03681     // If initiate failed, check for a bad error.
03682     ACE_OS::set_errno_to_last_error ();
03683     switch (errno)
03684     {
03685       case ERROR_IO_PENDING:
03686         // The IO will complete proactively: the OVERLAPPED will still
03687         // get queued.
03688         initiate_result = 0;
03689         break;
03690 
03691       default:
03692         // Something else went wrong: the OVERLAPPED will not get
03693         // queued.
03694 
03695         if (ACE::debug ())
03696         {
03697           ACE_DEBUG ((LM_ERROR,
03698                       ACE_LIB_TEXT ("%p\n"),
03699                       ACE_LIB_TEXT ("WSASendTo")));
03700         }
03701 
03702         delete result;
03703         initiate_result = -1;
03704         break;
03705     }
03706 
03707   }
03708   else
03709   {
03710     // Immediate success: the OVERLAPPED will still get queued.
03711     // number_of_bytes_recvd contains the number of bytes recvd
03712     // addr contains the peer address
03713     // flags was updated
03714 
03715     // number_of_bytes_sent = bytes_sent;
03716     initiate_result = 1;
03717   }
03718 
03719   return initiate_result;
03720 }


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