#include <WIN32_Asynch_IO.h>
Inheritance diagram for ACE_WIN32_Asynch_Write_Dgram:


Public Methods | |
| ACE_WIN32_Asynch_Write_Dgram (ACE_WIN32_Proactor *win32_proactor) | |
| Constructor. More... | |
| virtual | ~ACE_WIN32_Asynch_Write_Dgram (void) |
| Destructor. More... | |
| 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 (ACE_Handler &handler, ACE_HANDLE handle, const void *completion_key, ACE_Proactor *proactor) |
| int | cancel (void) |
| ACE_Proactor * | proactor (void) const |
| Return the underlying proactor. More... | |
Protected Methods | |
| ACE_WIN32_Asynch_Write_Dgram (void) | |
| Do-nothing constructor. More... | |
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 1876 of file WIN32_Asynch_IO.h.
|
|
Constructor.
Definition at line 3741 of file WIN32_Asynch_IO.cpp.
03742 : ACE_Asynch_Operation_Impl (), 03743 ACE_Asynch_Write_Dgram_Impl (), 03744 ACE_WIN32_Asynch_Operation (win32_proactor) 03745 { 03746 } |
|
|
Destructor.
Definition at line 3580 of file WIN32_Asynch_IO.cpp.
03581 {
03582 }
|
|
|
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 3730 of file WIN32_Asynch_IO.cpp. References ACE_WIN32_Asynch_Operation::cancel.
03731 {
03732 return ACE_WIN32_Asynch_Operation::cancel ();
03733 }
|
|
||||||||||||||||||||
|
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. Definition at line 3718 of file WIN32_Asynch_IO.cpp. References ACE_WIN32_Asynch_Operation::open.
03722 {
03723 return ACE_WIN32_Asynch_Operation::open (handler,
03724 handle,
03725 completion_key,
03726 proactor);
03727 }
|
|
|
Return the underlying proactor.
Reimplemented from ACE_WIN32_Asynch_Operation. Definition at line 3736 of file WIN32_Asynch_IO.cpp. References ACE_WIN32_Asynch_Operation::proactor.
03737 {
03738 return ACE_WIN32_Asynch_Operation::proactor ();
03739 }
|
|
||||||||||||||||||||||||||||||||
|
This starts off an asynchronous send. Upto <message_block->total_length()> will be sent. <message_block>'s <rd_ptr> will be updated to reflect the sent bytes if the send operation is successfully completed. Return code of 1 means immediate success and <number_of_bytes_sent> 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 <message_block>'s are supported. Upto <message_block->length()> bytes will be sent from each <message block> for a total of <message_block->total_length()> bytes. All <message_block>'s <rd_ptr>'s will be updated to reflect the bytes sent from each <message_block>. Implements ACE_Asynch_Write_Dgram_Impl. Definition at line 3585 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, and ACE_OS::set_errno_to_last_error.
03592 {
03593 number_of_bytes_sent = 0;
03594
03595 size_t bytes_to_write = 0;
03596
03597 iovec iov[ACE_IOV_MAX];
03598 int iovcnt = 0;
03599
03600 for (const ACE_Message_Block* msg = message_block;
03601 msg != 0 && iovcnt < ACE_IOV_MAX;
03602 msg = msg->cont () , ++iovcnt )
03603 {
03604 size_t msg_len = msg->length ();
03605
03606 // OS should process zero length block correctly
03607 // if ( msg_len == 0 )
03608 // ACE_ERROR_RETURN ((LM_ERROR,
03609 // ACE_LIB_TEXT ("ACE_WIN32_Asynch_Write_Dgram::send:")
03610 // ACE_LIB_TEXT ("Zero-length message block\n")),
03611 // -1);
03612
03613 bytes_to_write += msg_len;
03614
03615 // Make as many iovec as needed to fit all of msg_len.
03616 size_t rd_ptr_offset = 0;
03617 while (msg_len > 0 && iovcnt < ACE_IOV_MAX)
03618 {
03619 u_long this_chunk_length;
03620 if (msg_len > ULONG_MAX)
03621 this_chunk_length = ULONG_MAX;
03622 else
03623 this_chunk_length = ACE_static_cast (u_long, msg_len);
03624 // Collect the data in the iovec.
03625 iov[iovcnt].iov_base = msg->rd_ptr () + rd_ptr_offset;
03626 iov[iovcnt].iov_len = this_chunk_length;
03627 msg_len -= this_chunk_length;
03628 rd_ptr_offset += this_chunk_length;
03629
03630 // Increment iovec counter if there's more to do.
03631 if (msg_len > 0)
03632 iovcnt++;
03633 }
03634 if (msg_len > 0) // Ran out of iovecs before msg_space exhausted
03635 {
03636 errno = ERANGE;
03637 return -1;
03638 }
03639 }
03640
03641 if ( bytes_to_write == 0 )
03642 ACE_ERROR_RETURN ((LM_ERROR,
03643 ACE_LIB_TEXT ("ACE_WIN32_Asynch_Write_Dgram::send:")
03644 ACE_LIB_TEXT ("Attempt to write 0 bytes\n")),
03645 -1);
03646
03647 // Create the Asynch_Result.
03648 ACE_WIN32_Asynch_Write_Dgram_Result *result = 0;
03649 ACE_NEW_RETURN (result,
03650 ACE_WIN32_Asynch_Write_Dgram_Result (*this->handler_,
03651 this->handle_,
03652 message_block,
03653 bytes_to_write,
03654 flags,
03655 act,
03656 this->win32_proactor_->get_handle (),
03657 priority,
03658 signal_number),
03659 -1);
03660
03661 // do the scatter/gather send
03662
03663 int initiate_result = ACE_OS::sendto (result->handle (),
03664 iov,
03665 iovcnt,
03666 number_of_bytes_sent,
03667 result->flags_,
03668 (sockaddr *) addr.get_addr (),
03669 addr.get_size(),
03670 result,
03671 0);
03672
03673
03674 if (initiate_result == SOCKET_ERROR)
03675 {
03676 // If initiate failed, check for a bad error.
03677 ACE_OS::set_errno_to_last_error ();
03678 switch (errno)
03679 {
03680 case ERROR_IO_PENDING:
03681 // The IO will complete proactively: the OVERLAPPED will still
03682 // get queued.
03683 initiate_result = 0;
03684 break;
03685
03686 default:
03687 // Something else went wrong: the OVERLAPPED will not get
03688 // queued.
03689
03690 if (ACE::debug ())
03691 {
03692 ACE_DEBUG ((LM_ERROR,
03693 ACE_LIB_TEXT ("%p\n"),
03694 ACE_LIB_TEXT ("WSASendTo")));
03695 }
03696
03697 delete result;
03698 initiate_result = -1;
03699 break;
03700 }
03701
03702 }
03703 else
03704 {
03705 // Immediate success: the OVERLAPPED will still get queued.
03706 // number_of_bytes_recvd contains the number of bytes recvd
03707 // addr contains the peer address
03708 // flags was updated
03709
03710 // number_of_bytes_sent = bytes_sent;
03711 initiate_result = 1;
03712 }
03713
03714 return initiate_result;
03715 }
|
1.2.14 written by Dimitri van Heesch,
© 1997-2002