#include <WIN32_Asynch_IO.h>
Inheritance diagram for ACE_WIN32_Asynch_Write_Dgram:
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_Proactor * | proactor (void) const |
Return the underlying proactor. | |
Protected Member Functions | |
ACE_WIN32_Asynch_Write_Dgram (void) | |
Do-nothing constructor. |
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.
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 } |
|
Destructor.
Definition at line 3585 of file WIN32_Asynch_IO.cpp.
03586 { 03587 } |
|
Do-nothing constructor.
|
|
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 } |
|
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 } |
|
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 } |
|
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 } |