#include <WIN32_Asynch_IO.h>
Inheritance diagram for ACE_WIN32_Asynch_Write_Stream:
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_Proactor * | proactor (void) const |
Return the underlying proactor. | |
Protected Member Functions | |
int | shared_write (ACE_WIN32_Asynch_Write_Stream_Result *result) |
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.
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 } |
|
Destructor.
Definition at line 990 of file WIN32_Asynch_IO.cpp.
00991 { 00992 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |