1 #include "ace/WIN32_Asynch_IO.h"
3 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) && \
4 (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 == 1))
6 #include "ace/WIN32_Proactor.h"
7 #include "ace/Proactor.h"
8 #include "ace/Message_Block.h"
9 #include "ace/Service_Config.h"
10 #include "ace/Flag_Manip.h"
11 #include "ace/INET_Addr.h"
12 #include "ace/Task_T.h"
13 #include "ace/OS_NS_errno.h"
14 #include "ace/OS_NS_unistd.h"
15 #include "ace/OS_NS_sys_socket.h"
17 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
20 ACE_WIN32_Asynch_Result::bytes_transferred () const
22 return this->bytes_transferred_
;
26 ACE_WIN32_Asynch_Result::act () const
32 ACE_WIN32_Asynch_Result::success () const
34 return this->success_
;
38 ACE_WIN32_Asynch_Result::completion_key () const
40 return this->completion_key_
;
44 ACE_WIN32_Asynch_Result::error () const
50 ACE_WIN32_Asynch_Result::event () const
56 ACE_WIN32_Asynch_Result::offset () const
62 ACE_WIN32_Asynch_Result::offset_high () const
64 return this->OffsetHigh
;
68 ACE_WIN32_Asynch_Result::priority () const
70 ACE_NOTSUP_RETURN (0);
74 ACE_WIN32_Asynch_Result::signal_number () const
76 ACE_NOTSUP_RETURN (0);
80 ACE_WIN32_Asynch_Result::post_completion (ACE_Proactor_Impl
*proactor
)
82 // Get to the platform specific implementation.
83 ACE_WIN32_Proactor
*win32_proactor
= dynamic_cast<ACE_WIN32_Proactor
*> (proactor
);
85 if (win32_proactor
== 0)
86 ACELIB_ERROR_RETURN ((LM_ERROR
,
87 ACE_TEXT ("Dynamic cast to WIN32 Proactor failed\n")),
91 return win32_proactor
->post_completion (this);
95 ACE_WIN32_Asynch_Result::set_bytes_transferred (size_t nbytes
)
97 this->bytes_transferred_
= nbytes
;
101 ACE_WIN32_Asynch_Result::set_error (u_long errcode
)
103 this->error_
= errcode
;
106 ACE_WIN32_Asynch_Result::~ACE_WIN32_Asynch_Result ()
110 ACE_WIN32_Asynch_Result::ACE_WIN32_Asynch_Result
111 (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
118 : ACE_Asynch_Result_Impl (),
120 handler_proxy_ (handler_proxy
),
122 bytes_transferred_ (0),
127 // Set the ACE_OVERLAPPED structure
129 this->InternalHigh
= 0;
130 this->Offset
= offset
;
131 this->OffsetHigh
= offset_high
;
132 this->hEvent
= event
;
134 ACE_UNUSED_ARG (priority
);
135 ACE_UNUSED_ARG (signal_number
);
139 ACE_WIN32_Asynch_Operation::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
141 const void *completion_key
,
142 ACE_Proactor
*proactor
)
144 this->proactor_
= proactor
;
145 this->handler_proxy_
= handler_proxy
;
146 this->handle_
= handle
;
148 // Grab the handle from the <handler> if <handle> is invalid
149 if (this->handle_
== ACE_INVALID_HANDLE
)
151 ACE_Handler
*handler
= handler_proxy
.get ()->handler ();
153 this->handle_
= handler
->handle ();
155 if (this->handle_
== ACE_INVALID_HANDLE
)
158 if (this->proactor_
!= 0)
159 // update implementation.
160 this->win32_proactor_
=
161 dynamic_cast <ACE_WIN32_Proactor
*>(this->proactor_
->implementation ());
163 // Register with the <proactor>.
164 return this->win32_proactor_
->register_handle (this->handle_
,
169 ACE_WIN32_Asynch_Operation::cancel ()
171 #if defined (ACE_HAS_CANCEL_IO)
172 // All I/O operations that are canceled will complete with the error
173 // ERROR_OPERATION_ABORTED. All completion notifications for the I/O
174 // operations will occur normally.
176 #if (_WIN32_WINNT < 0x0600)
177 int const result
= (int) ::CancelIo (this->handle_
);
179 int const result
= (int) ::CancelIoEx (this->handle_
, 0);
180 #endif // < _WIN32_WINNT_VISTA
182 // Couldn't cancel the operations.
185 // result is non-zero. All the operations are cancelled then.
187 #else /* !ACE_HAS_CANCEL_IO */
188 ACE_NOTSUP_RETURN (-1);
189 #endif /* ACE_HAS_CANCEL_IO */
193 ACE_WIN32_Asynch_Operation::proactor () const
195 return this->proactor_
;
198 ACE_WIN32_Asynch_Operation::ACE_WIN32_Asynch_Operation (ACE_WIN32_Proactor
*win32_proactor
)
199 : ACE_Asynch_Operation_Impl (),
200 win32_proactor_ (win32_proactor
),
202 handle_ (ACE_INVALID_HANDLE
)
206 ACE_WIN32_Asynch_Operation::~ACE_WIN32_Asynch_Operation ()
210 // ************************************************************
213 ACE_WIN32_Asynch_Read_Stream_Result::bytes_to_read () const
215 return this->bytes_to_read_
;
219 ACE_WIN32_Asynch_Read_Stream_Result::message_block () const
221 return this->message_block_
;
225 ACE_WIN32_Asynch_Read_Stream_Result::handle () const
227 return this->handle_
;
230 ACE_WIN32_Asynch_Read_Stream_Result::ACE_WIN32_Asynch_Read_Stream_Result (
231 const ACE_Handler::Proxy_Ptr
&handler_proxy
,
233 ACE_Message_Block
&message_block
,
234 size_t bytes_to_read
,
240 : ACE_Asynch_Result_Impl (),
241 ACE_Asynch_Read_Stream_Result_Impl (),
242 ACE_WIN32_Asynch_Result (handler_proxy
,
249 bytes_to_read_ (bytes_to_read
),
250 message_block_ (message_block
),
252 scatter_enabled_ (scatter_enabled
)
257 ACE_WIN32_Asynch_Read_Stream_Result::complete (size_t bytes_transferred
,
259 const void *completion_key
,
262 // Copy the data which was returned by GetQueuedCompletionStatus
263 this->bytes_transferred_
= bytes_transferred
;
264 this->success_
= success
;
265 this->completion_key_
= completion_key
;
266 this->error_
= error
;
268 // Appropriately move the pointers in the message block.
269 if (!this->scatter_enabled ())
270 this->message_block_
.wr_ptr (bytes_transferred
);
273 for (ACE_Message_Block
* mb
= &this->message_block_
;
274 (mb
!= 0) && (bytes_transferred
> 0);
277 size_t len_part
= mb
->space ();
279 if (len_part
> bytes_transferred
)
280 len_part
= bytes_transferred
;
282 mb
->wr_ptr (len_part
);
284 bytes_transferred
-= len_part
;
288 // Create the interface result class.
289 ACE_Asynch_Read_Stream::Result
result (this);
291 // Call the application handler.
292 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
294 handler
->handle_read_stream (result
);
297 ACE_WIN32_Asynch_Read_Stream_Result::~ACE_WIN32_Asynch_Read_Stream_Result ()
301 // Base class operations. These operations are here to kill dominance
302 // warnings. These methods call the base class methods.
305 ACE_WIN32_Asynch_Read_Stream_Result::bytes_transferred () const
307 return ACE_WIN32_Asynch_Result::bytes_transferred ();
311 ACE_WIN32_Asynch_Read_Stream_Result::act () const
313 return ACE_WIN32_Asynch_Result::act ();
317 ACE_WIN32_Asynch_Read_Stream_Result::success () const
319 return ACE_WIN32_Asynch_Result::success ();
323 ACE_WIN32_Asynch_Read_Stream_Result::completion_key () const
325 return ACE_WIN32_Asynch_Result::completion_key ();
329 ACE_WIN32_Asynch_Read_Stream_Result::error () const
331 return ACE_WIN32_Asynch_Result::error ();
335 ACE_WIN32_Asynch_Read_Stream_Result::event () const
337 return ACE_WIN32_Asynch_Result::event ();
341 ACE_WIN32_Asynch_Read_Stream_Result::offset () const
343 return ACE_WIN32_Asynch_Result::offset ();
347 ACE_WIN32_Asynch_Read_Stream_Result::offset_high () const
349 return ACE_WIN32_Asynch_Result::offset_high ();
353 ACE_WIN32_Asynch_Read_Stream_Result::priority () const
355 return ACE_WIN32_Asynch_Result::priority ();
359 ACE_WIN32_Asynch_Read_Stream_Result::signal_number () const
361 return ACE_WIN32_Asynch_Result::signal_number ();
365 ACE_WIN32_Asynch_Read_Stream_Result::post_completion (ACE_Proactor_Impl
*proactor
)
367 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
371 ACE_WIN32_Asynch_Read_Stream_Result::scatter_enabled () const
373 return this->scatter_enabled_
;
376 ACE_WIN32_Asynch_Read_Stream::ACE_WIN32_Asynch_Read_Stream (ACE_WIN32_Proactor
*win32_proactor
)
377 : ACE_Asynch_Operation_Impl (),
378 ACE_Asynch_Read_Stream_Impl (),
379 ACE_WIN32_Asynch_Operation (win32_proactor
)
384 ACE_WIN32_Asynch_Read_Stream::read (ACE_Message_Block
&message_block
,
385 size_t bytes_to_read
,
390 size_t space
= message_block
.space ();
391 if (bytes_to_read
> space
)
392 bytes_to_read
= space
;
394 if (bytes_to_read
== 0)
400 // Create the Asynch_Result.
401 ACE_WIN32_Asynch_Read_Stream_Result
*result
= 0;
402 ACE_NEW_RETURN (result
,
403 ACE_WIN32_Asynch_Read_Stream_Result (this->handler_proxy_
,
408 this->win32_proactor_
->get_handle (),
414 int const return_val
= this->shared_read (result
);
417 if (return_val
== -1)
424 ACE_WIN32_Asynch_Read_Stream::readv (ACE_Message_Block
&message_block
,
425 size_t bytes_to_read
,
430 #if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
431 iovec iov
[ACE_IOV_MAX
];
434 // We should not read more than user requested,
435 // but it is allowed to read less
437 for (const ACE_Message_Block
* msg
= &message_block
;
438 msg
!= 0 && bytes_to_read
> 0 && iovcnt
< ACE_IOV_MAX
;
439 msg
= msg
->cont () , ++iovcnt
)
441 size_t msg_space
= msg
->space ();
443 // OS should correctly process zero length buffers
444 // if ( msg_space == 0 )
445 // ACELIB_ERROR_RETURN ((LM_ERROR,
446 // ACE_TEXT ("ACE_WIN32_Asynch_Read_Stream::readv:")
447 // ACE_TEXT ("No space in the message block\n")),
450 if (msg_space
> bytes_to_read
)
451 msg_space
= bytes_to_read
;
452 bytes_to_read
-= msg_space
;
454 // Make as many iovec as needed to fit all of msg_space.
455 size_t wr_ptr_offset
= 0;
457 while (msg_space
> 0 && iovcnt
< ACE_IOV_MAX
)
459 u_long this_chunk_length
;
460 if (msg_space
> ULONG_MAX
)
461 this_chunk_length
= ULONG_MAX
;
463 this_chunk_length
= static_cast<u_long
> (msg_space
);
464 // Collect the data in the iovec.
465 iov
[iovcnt
].iov_base
= msg
->wr_ptr () + wr_ptr_offset
;
466 iov
[iovcnt
].iov_len
= this_chunk_length
;
467 msg_space
-= this_chunk_length
;
468 wr_ptr_offset
+= this_chunk_length
;
470 // Increment iovec counter if there's more to do.
474 if (msg_space
> 0) // Ran out of iovecs before msg_space exhausted
481 // Re-calculate number bytes to read
484 for (int i
= 0; i
< iovcnt
; ++i
)
485 bytes_to_read
+= iov
[i
].iov_len
;
487 if (bytes_to_read
== 0)
488 ACELIB_ERROR_RETURN ((LM_ERROR
,
489 ACE_TEXT ("ACE_WIN32_Asynch_Read_Stream::readv:")
490 ACE_TEXT ("Attempt to read 0 bytes\n")),
493 // Create the Asynch_Result.
494 ACE_WIN32_Asynch_Read_Stream_Result
*result
= 0;
495 ACE_NEW_RETURN (result
,
496 ACE_WIN32_Asynch_Read_Stream_Result (this->handler_proxy_
,
501 this->win32_proactor_
->get_handle (),
504 1), // scatter read enabled
507 // do the scatter recv
509 result
->set_error (0); // Clear error before starting IO.
511 DWORD bytes_recvd
= 0;
514 int initiate_result
= ::WSARecv (reinterpret_cast<SOCKET
> (result
->handle ()),
515 reinterpret_cast<WSABUF
*> (iov
),
522 if (0 == initiate_result
)
523 // Immediate success: the OVERLAPPED will still get queued.
526 ACE_ASSERT (initiate_result
== SOCKET_ERROR
);
528 // If initiate failed, check for a bad error.
529 ACE_OS::set_errno_to_last_error ();
532 case ERROR_IO_PENDING
:
533 // The IO will complete proactively: the OVERLAPPED will still
539 // Something else went wrong: the OVERLAPPED will not get
544 ACELIB_DEBUG ((LM_ERROR
,
546 ACE_TEXT ("WSARecv")));
550 initiate_result
= -1;
554 return initiate_result
;
556 ACE_UNUSED_ARG (message_block
);
557 ACE_UNUSED_ARG (bytes_to_read
);
558 ACE_UNUSED_ARG (act
);
559 ACE_UNUSED_ARG (priority
);
560 ACE_UNUSED_ARG (signal_number
);
561 ACE_NOTSUP_RETURN (-1);
562 #endif /* ACE_HAS_WINSOCK2 && ACE_HAS_WINSOCK2 != 0 */
565 ACE_WIN32_Asynch_Read_Stream::~ACE_WIN32_Asynch_Read_Stream ()
570 ACE_WIN32_Asynch_Read_Stream::shared_read (ACE_WIN32_Asynch_Read_Stream_Result
*result
)
572 // ReadFile API limits us to DWORD range.
573 if (result
->bytes_to_read () > MAXDWORD
)
578 DWORD bytes_to_read
= static_cast<DWORD
> (result
->bytes_to_read ());
580 result
->set_error (0); // Clear error before starting IO.
583 int initiate_result
= ::ReadFile (result
->handle (),
584 result
->message_block ().wr_ptr (),
588 if (initiate_result
== 1)
589 // Immediate success: the OVERLAPPED will still get queued.
592 // If initiate failed, check for a bad error.
593 ACE_OS::set_errno_to_last_error ();
596 case ERROR_IO_PENDING
:
598 case ERROR_MORE_DATA
:
599 // The IO will complete proactively: the OVERLAPPED will still
604 // Something else went wrong: the OVERLAPPED will not get
609 ACELIB_DEBUG ((LM_ERROR
,
611 ACE_TEXT ("ReadFile")));
618 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
619 // methods are defined here to avoid VC++ warnings. They route the
620 // call to the ACE_WIN32_Asynch_Operation base class.
623 ACE_WIN32_Asynch_Read_Stream::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
625 const void *completion_key
,
626 ACE_Proactor
*proactor
)
628 return ACE_WIN32_Asynch_Operation::open (handler_proxy
,
635 ACE_WIN32_Asynch_Read_Stream::cancel ()
637 return ACE_WIN32_Asynch_Operation::cancel ();
641 ACE_WIN32_Asynch_Read_Stream::proactor () const
643 return ACE_WIN32_Asynch_Operation::proactor ();
647 ACE_WIN32_Asynch_Write_Stream_Result::bytes_to_write () const
649 return this->bytes_to_write_
;
653 ACE_WIN32_Asynch_Write_Stream_Result::message_block () const
655 return this->message_block_
;
659 ACE_WIN32_Asynch_Write_Stream_Result::handle () const
661 return this->handle_
;
664 ACE_WIN32_Asynch_Write_Stream_Result::ACE_WIN32_Asynch_Write_Stream_Result (
665 const ACE_Handler::Proxy_Ptr
&handler_proxy
,
667 ACE_Message_Block
&message_block
,
668 size_t bytes_to_write
,
674 : ACE_Asynch_Result_Impl (),
675 ACE_Asynch_Write_Stream_Result_Impl (),
676 ACE_WIN32_Asynch_Result
677 (handler_proxy
, act
, event
, 0, 0, priority
, signal_number
),
678 bytes_to_write_ (bytes_to_write
),
679 message_block_ (message_block
),
681 gather_enabled_ (gather_enabled
)
686 ACE_WIN32_Asynch_Write_Stream_Result::complete (size_t bytes_transferred
,
688 const void *completion_key
,
691 // Copy the data which was returned by <GetQueuedCompletionStatus>.
692 this->bytes_transferred_
= bytes_transferred
;
693 this->success_
= success
;
694 this->completion_key_
= completion_key
;
695 this->error_
= error
;
697 // Appropriately move the pointers in the message block.
698 if (!this->gather_enabled ())
699 this->message_block_
.rd_ptr (bytes_transferred
);
702 for (ACE_Message_Block
* mb
= &this->message_block_
;
703 (mb
!= 0) && (bytes_transferred
> 0);
706 size_t len_part
= mb
->length ();
708 if ( len_part
> bytes_transferred
)
709 len_part
= bytes_transferred
;
711 mb
->rd_ptr (len_part
);
713 bytes_transferred
-= len_part
;
717 // Create the interface result class.
718 ACE_Asynch_Write_Stream::Result
result (this);
720 // Call the application handler.
721 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
723 handler
->handle_write_stream (result
);
726 ACE_WIN32_Asynch_Write_Stream_Result::~ACE_WIN32_Asynch_Write_Stream_Result ()
730 // Base class operations. These operations are here to kill dominance
731 // warnings. These methods call the base class methods.
734 ACE_WIN32_Asynch_Write_Stream_Result::bytes_transferred () const
736 return ACE_WIN32_Asynch_Result::bytes_transferred ();
740 ACE_WIN32_Asynch_Write_Stream_Result::act () const
742 return ACE_WIN32_Asynch_Result::act ();
746 ACE_WIN32_Asynch_Write_Stream_Result::success () const
748 return ACE_WIN32_Asynch_Result::success ();
752 ACE_WIN32_Asynch_Write_Stream_Result::completion_key () const
754 return ACE_WIN32_Asynch_Result::completion_key ();
758 ACE_WIN32_Asynch_Write_Stream_Result::error () const
760 return ACE_WIN32_Asynch_Result::error ();
764 ACE_WIN32_Asynch_Write_Stream_Result::event () const
766 return ACE_WIN32_Asynch_Result::event ();
770 ACE_WIN32_Asynch_Write_Stream_Result::offset () const
772 return ACE_WIN32_Asynch_Result::offset ();
776 ACE_WIN32_Asynch_Write_Stream_Result::offset_high () const
778 return ACE_WIN32_Asynch_Result::offset_high ();
782 ACE_WIN32_Asynch_Write_Stream_Result::priority () const
784 return ACE_WIN32_Asynch_Result::priority ();
788 ACE_WIN32_Asynch_Write_Stream_Result::signal_number () const
790 return ACE_WIN32_Asynch_Result::signal_number ();
794 ACE_WIN32_Asynch_Write_Stream_Result::post_completion (ACE_Proactor_Impl
*proactor
)
796 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
800 ACE_WIN32_Asynch_Write_Stream_Result::gather_enabled () const
802 return this->gather_enabled_
;
805 ACE_WIN32_Asynch_Write_Stream::ACE_WIN32_Asynch_Write_Stream (ACE_WIN32_Proactor
*win32_proactor
)
806 : ACE_Asynch_Operation_Impl (),
807 ACE_Asynch_Write_Stream_Impl (),
808 ACE_WIN32_Asynch_Operation (win32_proactor
)
813 ACE_WIN32_Asynch_Write_Stream::write (ACE_Message_Block
&message_block
,
814 size_t bytes_to_write
,
819 size_t len
= message_block
.length();
821 if (bytes_to_write
> len
)
822 bytes_to_write
= len
;
824 if (bytes_to_write
== 0)
827 ACE_TEXT ("ACE_WIN32_Asynch_Write_Stream::write:")
828 ACE_TEXT ("Attempt to write 0 bytes\n")),
831 if (bytes_to_write
> MAXDWORD
)
837 ACE_WIN32_Asynch_Write_Stream_Result
*result
= 0;
838 ACE_NEW_RETURN (result
,
839 ACE_WIN32_Asynch_Write_Stream_Result (this->handler_proxy_
,
844 this->win32_proactor_
->get_handle (),
849 u_long bytes_written
;
851 result
->set_error (0); // Clear error before starting IO.
853 // Initiate the write; Winsock 2 is required for the higher-performing
854 // WSASend() function. For Winsock 1, fall back to the slower WriteFile().
855 int initiate_result
= 0;
856 #if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
858 iov
.buf
= result
->message_block ().rd_ptr ();
859 iov
.len
= static_cast<DWORD
> (bytes_to_write
);
860 initiate_result
= ::WSASend (reinterpret_cast<SOCKET
> (result
->handle ()),
867 if (initiate_result
== 0)
869 initiate_result
= ::WriteFile (result
->handle (),
870 result
->message_block ().rd_ptr (),
871 static_cast<DWORD
> (bytes_to_write
),
874 if (initiate_result
== 1)
875 #endif /* ACE_HAS_WINSOCK2 */
877 // Immediate success: the OVERLAPPED will still get queued.
881 // If initiate failed, check for a bad error.
882 ACE_OS::set_errno_to_last_error ();
885 case ERROR_IO_PENDING
:
886 // The IO will complete proactively: the OVERLAPPED will still
892 // Something else went wrong: the OVERLAPPED will not get
896 ACELIB_DEBUG ((LM_ERROR
,
898 ACE_TEXT ("Initiating write")));
900 initiate_result
= -1;
903 return initiate_result
;
907 ACE_WIN32_Asynch_Write_Stream::writev (ACE_Message_Block
&message_block
,
908 size_t bytes_to_write
,
913 #if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
914 iovec iov
[ACE_IOV_MAX
];
917 // We should not write more than user requested,
918 // but it is allowed to write less
920 for (const ACE_Message_Block
* msg
= &message_block
;
921 msg
!= 0 && bytes_to_write
> 0 && iovcnt
< ACE_IOV_MAX
;
924 size_t msg_len
= msg
->length ();
926 // Skip 0-length blocks.
929 if (msg_len
> bytes_to_write
)
930 msg_len
= bytes_to_write
;
931 bytes_to_write
-= msg_len
;
933 // Make as many iovec as needed to fit all of msg_len.
934 size_t rd_ptr_offset
= 0;
936 while (msg_len
> 0 && iovcnt
< ACE_IOV_MAX
)
938 u_long this_chunk_length
;
939 if (msg_len
> ULONG_MAX
)
940 this_chunk_length
= ULONG_MAX
;
942 this_chunk_length
= static_cast<u_long
> (msg_len
);
943 // Collect the data in the iovec.
944 iov
[iovcnt
].iov_base
= msg
->rd_ptr () + rd_ptr_offset
;
945 iov
[iovcnt
].iov_len
= this_chunk_length
;
946 msg_len
-= this_chunk_length
;
947 rd_ptr_offset
+= this_chunk_length
;
949 // Increment iovec counter if there's more to do.
953 if (msg_len
> 0) // Ran out of iovecs before msg_space exhausted
961 // Re-calculate number bytes to write
964 for ( int i
=0; i
< iovcnt
; ++i
)
965 bytes_to_write
+= iov
[i
].iov_len
;
967 if ( bytes_to_write
== 0 )
968 ACELIB_ERROR_RETURN ((LM_ERROR
,
969 ACE_TEXT ("ACE_WIN32_Asynch_Write_Stream::writev:")
970 ACE_TEXT ("Attempt to write 0 bytes\n")),
974 ACE_WIN32_Asynch_Write_Stream_Result
*result
= 0;
975 ACE_NEW_RETURN (result
,
976 ACE_WIN32_Asynch_Write_Stream_Result (this->handler_proxy_
,
981 this->win32_proactor_
->get_handle (),
984 1), // gather write enabled
987 // do the gather send
989 u_long bytes_sent
= 0;
991 int initiate_result
= ::WSASend (reinterpret_cast<SOCKET
> (result
->handle ()),
992 reinterpret_cast<WSABUF
*> (iov
),
999 if (0 == initiate_result
)
1000 // Immediate success: the OVERLAPPED will still get queued.
1003 ACE_ASSERT (initiate_result
== SOCKET_ERROR
);
1005 // If initiate failed, check for a bad error.
1006 ACE_OS::set_errno_to_last_error ();
1009 case ERROR_IO_PENDING
:
1010 // The IO will complete proactively: the OVERLAPPED will still
1012 initiate_result
= 0;
1016 // Something else went wrong: the OVERLAPPED will not get
1021 ACELIB_DEBUG ((LM_ERROR
,
1023 ACE_TEXT ("WSASend")));
1027 initiate_result
= -1;
1031 return initiate_result
;
1033 ACE_UNUSED_ARG (message_block
);
1034 ACE_UNUSED_ARG (bytes_to_write
);
1035 ACE_UNUSED_ARG (act
);
1036 ACE_UNUSED_ARG (priority
);
1037 ACE_UNUSED_ARG (signal_number
);
1038 ACE_NOTSUP_RETURN (-1);
1039 #endif /* ACE_HAS_WINSOCK2 && ACE_HAS_WINSOCK2 != 0 */
1042 ACE_WIN32_Asynch_Write_Stream::~ACE_WIN32_Asynch_Write_Stream ()
1046 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
1047 // methods are defined here to avoid VC++ warnings. They route the
1048 // call to the ACE_WIN32_Asynch_Operation base class.
1051 ACE_WIN32_Asynch_Write_Stream::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
1053 const void *completion_key
,
1054 ACE_Proactor
*proactor
)
1056 return ACE_WIN32_Asynch_Operation::open (handler_proxy
,
1063 ACE_WIN32_Asynch_Write_Stream::cancel ()
1065 return ACE_WIN32_Asynch_Operation::cancel ();
1069 ACE_WIN32_Asynch_Write_Stream::proactor () const
1071 return ACE_WIN32_Asynch_Operation::proactor ();
1074 ACE_WIN32_Asynch_Read_File_Result::ACE_WIN32_Asynch_Read_File_Result (
1075 const ACE_Handler::Proxy_Ptr
&handler_proxy
,
1077 ACE_Message_Block
&message_block
,
1078 size_t bytes_to_read
,
1085 int scatter_enabled
)
1086 : ACE_Asynch_Result_Impl (),
1087 ACE_Asynch_Read_Stream_Result_Impl (),
1088 ACE_Asynch_Read_File_Result_Impl (),
1089 ACE_WIN32_Asynch_Read_Stream_Result (handler_proxy
,
1099 this->Offset
= offset
;
1100 this->OffsetHigh
= offset_high
;
1104 ACE_WIN32_Asynch_Read_File_Result::complete (size_t bytes_transferred
,
1106 const void *completion_key
,
1109 // Copy the data which was returned by GetQueuedCompletionStatus.
1110 this->bytes_transferred_
= bytes_transferred
;
1111 this->success_
= success
;
1112 this->completion_key_
= completion_key
;
1113 this->error_
= error
;
1115 // Appropriately move the pointers in the message block.
1116 if (!this->scatter_enabled ())
1117 this->message_block_
.wr_ptr (bytes_transferred
);
1120 static const size_t page_size
= ACE_OS::getpagesize();
1122 for (ACE_Message_Block
* mb
= &this->message_block_
;
1123 (mb
!= 0) && (bytes_transferred
> 0);
1126 // mb->space () is ought to be >= page_size.
1127 // this is verified in the readv method
1128 // ACE_ASSERT (mb->space () >= page_size);
1130 size_t len_part
= page_size
;
1132 if ( len_part
> bytes_transferred
)
1133 len_part
= bytes_transferred
;
1135 mb
->wr_ptr (len_part
);
1137 bytes_transferred
-= len_part
;
1141 // Create the interface result class.
1142 ACE_Asynch_Read_File::Result
result (this);
1144 // Call the application handler.
1145 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
1147 handler
->handle_read_file (result
);
1150 ACE_WIN32_Asynch_Read_File_Result::~ACE_WIN32_Asynch_Read_File_Result ()
1154 // Base class operations. These operations are here to kill dominance
1155 // warnings. These methods call the base class methods.
1158 ACE_WIN32_Asynch_Read_File_Result::bytes_transferred () const
1160 return ACE_WIN32_Asynch_Result::bytes_transferred ();
1164 ACE_WIN32_Asynch_Read_File_Result::act () const
1166 return ACE_WIN32_Asynch_Result::act ();
1170 ACE_WIN32_Asynch_Read_File_Result::success () const
1172 return ACE_WIN32_Asynch_Result::success ();
1176 ACE_WIN32_Asynch_Read_File_Result::completion_key () const
1178 return ACE_WIN32_Asynch_Result::completion_key ();
1182 ACE_WIN32_Asynch_Read_File_Result::error () const
1184 return ACE_WIN32_Asynch_Result::error ();
1188 ACE_WIN32_Asynch_Read_File_Result::event () const
1190 return ACE_WIN32_Asynch_Result::event ();
1194 ACE_WIN32_Asynch_Read_File_Result::offset () const
1196 return ACE_WIN32_Asynch_Result::offset ();
1200 ACE_WIN32_Asynch_Read_File_Result::offset_high () const
1202 return ACE_WIN32_Asynch_Result::offset_high ();
1206 ACE_WIN32_Asynch_Read_File_Result::priority () const
1208 return ACE_WIN32_Asynch_Result::priority ();
1212 ACE_WIN32_Asynch_Read_File_Result::signal_number () const
1214 return ACE_WIN32_Asynch_Result::signal_number ();
1217 // The following methods belong to
1218 // ACE_WIN32_Asynch_Read_Stream_Result. They are here to avoid VC++
1219 // warnings. These methods route their call to the
1220 // ACE_WIN32_Asynch_Read_Stream_Result base class.
1223 ACE_WIN32_Asynch_Read_File_Result::bytes_to_read () const
1225 return ACE_WIN32_Asynch_Read_Stream_Result::bytes_to_read ();
1229 ACE_WIN32_Asynch_Read_File_Result::message_block () const
1231 return ACE_WIN32_Asynch_Read_Stream_Result::message_block ();
1235 ACE_WIN32_Asynch_Read_File_Result::handle () const
1237 return ACE_WIN32_Asynch_Read_Stream_Result::handle ();
1241 ACE_WIN32_Asynch_Read_File_Result::post_completion (ACE_Proactor_Impl
*proactor
)
1243 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
1246 // ************************************************************
1248 ACE_WIN32_Asynch_Read_File::ACE_WIN32_Asynch_Read_File (ACE_WIN32_Proactor
*win32_proactor
)
1249 : ACE_Asynch_Operation_Impl (),
1250 ACE_Asynch_Read_Stream_Impl (),
1251 ACE_Asynch_Read_File_Impl (),
1252 ACE_WIN32_Asynch_Read_Stream (win32_proactor
)
1257 ACE_WIN32_Asynch_Read_File::read (ACE_Message_Block
&message_block
,
1258 size_t bytes_to_read
,
1265 size_t space
= message_block
.space ();
1266 if ( bytes_to_read
> space
)
1267 bytes_to_read
= space
;
1269 if ( bytes_to_read
== 0 )
1272 ACE_TEXT ("ACE_WIN32_Asynch_Read_File::read:")
1273 ACE_TEXT ("Attempt to read 0 bytes or no space in the message block\n")),
1277 ACE_WIN32_Asynch_Read_File_Result
*result
= 0;
1278 ACE_NEW_RETURN (result
,
1279 ACE_WIN32_Asynch_Read_File_Result (this->handler_proxy_
,
1286 this->win32_proactor_
->get_handle (),
1292 int return_val
= this->shared_read (result
);
1295 if (return_val
== -1)
1302 ACE_WIN32_Asynch_Read_File::readv (ACE_Message_Block
&message_block
,
1303 size_t bytes_to_read
,
1310 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO)
1311 static const size_t page_size
= ACE_OS::getpagesize();
1313 FILE_SEGMENT_ELEMENT buffer_pointers
[ACE_IOV_MAX
+ 1];
1314 int buffer_pointers_count
= 0;
1316 // Each buffer must be at least the size of a system memory page
1317 // and must be aligned on a system memory page size boundary
1319 // We should not read more than user requested,
1320 // but it is allowed to read less
1322 size_t total_space
= 0;
1324 for (const ACE_Message_Block
* msg
= &message_block
;
1325 msg
!= 0 && buffer_pointers_count
< ACE_IOV_MAX
&& total_space
< bytes_to_read
;
1326 msg
= msg
->cont(), ++buffer_pointers_count
)
1328 size_t msg_space
= msg
->space ();
1330 if (msg_space
< page_size
)
1331 ACELIB_ERROR_RETURN ((LM_ERROR
,
1332 ACE_TEXT ("ACE_WIN32_Asynch_Read_File::readv:")
1333 ACE_TEXT ("Invalid message block size\n")),
1336 buffer_pointers
[buffer_pointers_count
].Buffer
= msg
->wr_ptr ();
1337 total_space
+= page_size
;
1340 // not read more than buffers space
1341 if (bytes_to_read
> total_space
)
1342 bytes_to_read
= total_space
;
1344 // ReadFileScatter API limits us to DWORD range.
1345 if (bytes_to_read
> MAXDWORD
)
1350 DWORD dword_bytes_to_read
= static_cast<DWORD
> (bytes_to_read
);
1352 // last one should be completely 0
1353 buffer_pointers
[buffer_pointers_count
].Buffer
= 0;
1355 ACE_WIN32_Asynch_Read_File_Result
*result
= 0;
1356 ACE_NEW_RETURN (result
,
1357 ACE_WIN32_Asynch_Read_File_Result (this->handler_proxy_
,
1364 this->win32_proactor_
->get_handle (),
1367 1), // scatter read enabled
1370 // do the scatter read
1371 result
->set_error (0); // Clear error before starting IO.
1373 int initiate_result
= ::ReadFileScatter (result
->handle (),
1375 dword_bytes_to_read
,
1376 0, // reserved, must be NULL
1379 if (0 != initiate_result
)
1380 // Immediate success: the OVERLAPPED will still get queued.
1383 // If initiate failed, check for a bad error.
1384 ACE_OS::set_errno_to_last_error ();
1387 case ERROR_IO_PENDING
:
1388 // The IO will complete proactively: the OVERLAPPED will still
1390 initiate_result
= 0;
1394 // Something else went wrong: the OVERLAPPED will not get
1399 ACELIB_DEBUG ((LM_ERROR
,
1401 ACE_TEXT ("ReadFileScatter")));
1405 initiate_result
= -1;
1409 return initiate_result
;
1411 ACE_NOTSUP_RETURN (-1);
1412 #endif /* ACE_WIN32_OVERLAPPED_IO */
1416 ACE_WIN32_Asynch_Read_File::~ACE_WIN32_Asynch_Read_File ()
1421 ACE_WIN32_Asynch_Read_File::read (ACE_Message_Block
&message_block
,
1422 size_t bytes_to_read
,
1427 return ACE_WIN32_Asynch_Read_Stream::read (message_block
,
1435 ACE_WIN32_Asynch_Read_File::readv (ACE_Message_Block
&message_block
,
1436 size_t bytes_to_read
,
1441 return ACE_WIN32_Asynch_Read_Stream::readv (message_block
,
1448 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
1449 // methods are defined here to avoid VC++ warnings. They route the
1450 // call to the ACE_WIN32_Asynch_Operation base class.
1453 ACE_WIN32_Asynch_Read_File::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
1455 const void *completion_key
,
1456 ACE_Proactor
*proactor
)
1458 return ACE_WIN32_Asynch_Operation::open (handler_proxy
,
1465 ACE_WIN32_Asynch_Read_File::cancel ()
1467 return ACE_WIN32_Asynch_Operation::cancel ();
1471 ACE_WIN32_Asynch_Read_File::proactor () const
1473 return ACE_WIN32_Asynch_Operation::proactor ();
1476 ACE_WIN32_Asynch_Write_File_Result::ACE_WIN32_Asynch_Write_File_Result (
1477 const ACE_Handler::Proxy_Ptr
&handler_proxy
,
1479 ACE_Message_Block
&message_block
,
1480 size_t bytes_to_write
,
1488 : ACE_Asynch_Result_Impl (),
1489 ACE_Asynch_Write_Stream_Result_Impl (),
1490 ACE_Asynch_Write_File_Result_Impl (),
1491 ACE_WIN32_Asynch_Write_Stream_Result (handler_proxy
,
1501 this->Offset
= offset
;
1502 this->OffsetHigh
= offset_high
;
1506 ACE_WIN32_Asynch_Write_File_Result::complete (size_t bytes_transferred
,
1508 const void *completion_key
,
1511 // Copy the data which was returned by GetQueuedCompletionStatus
1512 this->bytes_transferred_
= bytes_transferred
;
1513 this->success_
= success
;
1514 this->completion_key_
= completion_key
;
1515 this->error_
= error
;
1517 // Appropriately move the pointers in the message block.
1518 if (!this->gather_enabled ())
1519 this->message_block_
.rd_ptr (bytes_transferred
);
1522 static const size_t page_size
= ACE_OS::getpagesize();
1524 for (ACE_Message_Block
* mb
= &this->message_block_
;
1525 (mb
!= 0) && (bytes_transferred
> 0);
1528 // mb->length () is ought to be >= page_size.
1529 // this is verified in the writev method
1530 // ACE_ASSERT (mb->length () >= page_size);
1532 size_t len_part
= page_size
;
1534 if ( len_part
> bytes_transferred
)
1535 len_part
= bytes_transferred
;
1537 mb
->rd_ptr (len_part
);
1539 bytes_transferred
-= len_part
;
1544 // Create the interface result class.
1545 ACE_Asynch_Write_File::Result
result (this);
1547 // Call the application handler.
1548 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
1550 handler
->handle_write_file (result
);
1553 ACE_WIN32_Asynch_Write_File_Result::~ACE_WIN32_Asynch_Write_File_Result ()
1557 // Base class operations. These operations are here to kill dominance
1558 // warnings. These methods call the base class methods.
1561 ACE_WIN32_Asynch_Write_File_Result::bytes_transferred () const
1563 return ACE_WIN32_Asynch_Result::bytes_transferred ();
1567 ACE_WIN32_Asynch_Write_File_Result::act () const
1569 return ACE_WIN32_Asynch_Result::act ();
1573 ACE_WIN32_Asynch_Write_File_Result::success () const
1575 return ACE_WIN32_Asynch_Result::success ();
1579 ACE_WIN32_Asynch_Write_File_Result::completion_key () const
1581 return ACE_WIN32_Asynch_Result::completion_key ();
1585 ACE_WIN32_Asynch_Write_File_Result::error () const
1587 return ACE_WIN32_Asynch_Result::error ();
1591 ACE_WIN32_Asynch_Write_File_Result::event () const
1593 return ACE_WIN32_Asynch_Result::event ();
1597 ACE_WIN32_Asynch_Write_File_Result::offset () const
1599 return ACE_WIN32_Asynch_Result::offset ();
1603 ACE_WIN32_Asynch_Write_File_Result::offset_high () const
1605 return ACE_WIN32_Asynch_Result::offset_high ();
1609 ACE_WIN32_Asynch_Write_File_Result::priority () const
1611 return ACE_WIN32_Asynch_Result::priority ();
1615 ACE_WIN32_Asynch_Write_File_Result::signal_number () const
1617 return ACE_WIN32_Asynch_Result::signal_number ();
1620 // The following methods belong to
1621 // ACE_WIN32_Asynch_Write_Stream_Result. They are here to avoid VC++
1622 // warnings. These methods route their call to the
1623 // ACE_WIN32_Asynch_Write_Stream_Result base class.
1626 ACE_WIN32_Asynch_Write_File_Result::bytes_to_write () const
1628 return ACE_WIN32_Asynch_Write_Stream_Result::bytes_to_write ();
1632 ACE_WIN32_Asynch_Write_File_Result::message_block () const
1634 return ACE_WIN32_Asynch_Write_Stream_Result::message_block ();
1638 ACE_WIN32_Asynch_Write_File_Result::handle () const
1640 return ACE_WIN32_Asynch_Write_Stream_Result::handle ();
1644 ACE_WIN32_Asynch_Write_File_Result::post_completion (ACE_Proactor_Impl
*proactor
)
1646 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
1649 ACE_WIN32_Asynch_Write_File::ACE_WIN32_Asynch_Write_File (ACE_WIN32_Proactor
*win32_proactor
)
1650 : ACE_Asynch_Operation_Impl (),
1651 ACE_Asynch_Write_Stream_Impl (),
1652 ACE_Asynch_Write_File_Impl (),
1653 ACE_WIN32_Asynch_Write_Stream (win32_proactor
)
1658 ACE_WIN32_Asynch_Write_File::write (ACE_Message_Block
&message_block
,
1659 size_t bytes_to_write
,
1666 size_t len
= message_block
.length ();
1667 if ( bytes_to_write
> len
)
1668 bytes_to_write
= len
;
1670 if ( bytes_to_write
== 0 )
1673 ACE_TEXT ("ACE_WIN32_Asynch_Write_File::write:")
1674 ACE_TEXT ("Attempt to write 0 bytes\n")),
1677 if (bytes_to_write
> MAXDWORD
)
1683 ACE_WIN32_Asynch_Write_File_Result
*result
= 0;
1684 ACE_NEW_RETURN (result
,
1685 ACE_WIN32_Asynch_Write_File_Result (this->handler_proxy_
,
1692 this->win32_proactor_
->get_handle (),
1697 u_long bytes_written
;
1699 result
->set_error (0); // Clear error before starting IO.
1701 // Initiate the write
1702 int initiate_result
= 0;
1703 initiate_result
= ::WriteFile (result
->handle (),
1704 result
->message_block ().rd_ptr (),
1705 static_cast<DWORD
> (bytes_to_write
),
1708 if (initiate_result
== 1)
1710 // Immediate success: the OVERLAPPED will still get queued.
1714 // If initiate failed, check for a bad error.
1715 ACE_OS::set_errno_to_last_error ();
1718 case ERROR_IO_PENDING
:
1719 // The IO will complete proactively: the OVERLAPPED will still
1721 initiate_result
= 0;
1725 // Something else went wrong: the OVERLAPPED will not get
1729 ACELIB_DEBUG ((LM_ERROR
,
1731 ACE_TEXT ("Initiating write")));
1733 initiate_result
= -1;
1736 return initiate_result
;
1740 ACE_WIN32_Asynch_Write_File::writev (ACE_Message_Block
&message_block
,
1741 size_t bytes_to_write
,
1748 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO)
1749 static const size_t page_size
= ACE_OS::getpagesize();
1751 FILE_SEGMENT_ELEMENT buffer_pointers
[ACE_IOV_MAX
+ 1];
1752 int buffer_pointers_count
= 0;
1754 // Each buffer must be at least the size of a system memory page
1755 // and must be aligned on a system memory page size boundary
1757 // We should not read more than user requested,
1758 // but it is allowed to read less
1760 size_t total_len
= 0;
1762 for (const ACE_Message_Block
* msg
= &message_block
;
1763 msg
!= 0 && buffer_pointers_count
< ACE_IOV_MAX
&& total_len
< bytes_to_write
;
1764 msg
= msg
->cont (), ++buffer_pointers_count
)
1766 size_t msg_len
= msg
->length ();
1768 // Don't allow writing less than page_size, unless
1769 // the size of the message block is big enough (so we don't write from
1770 // memory which does not belong to the message block), and the message
1771 // block is the last in the chain.
1772 if (msg_len
< page_size
&&
1773 (msg
->size () - (msg
->rd_ptr () - msg
->base ()) < page_size
|| // message block too small
1774 bytes_to_write
- total_len
> page_size
))// NOT last chunk
1775 ACELIB_ERROR_RETURN ((LM_ERROR
,
1776 ACE_TEXT ("ACE_WIN32_Asynch_Write_File::writev:")
1777 ACE_TEXT ("Invalid message block length\n")),
1780 buffer_pointers
[buffer_pointers_count
].Buffer
= msg
->rd_ptr ();
1781 total_len
+= page_size
;
1784 // not write more than we have in buffers
1785 if (bytes_to_write
> total_len
)
1786 bytes_to_write
= total_len
;
1787 // WriteFileGather API limits us to DWORD range.
1788 if (bytes_to_write
> MAXDWORD
)
1793 DWORD dword_bytes_to_write
= static_cast<DWORD
> (bytes_to_write
);
1795 // last one should be completely 0
1796 buffer_pointers
[buffer_pointers_count
].Buffer
= 0;
1798 ACE_WIN32_Asynch_Write_File_Result
*result
= 0;
1799 ACE_NEW_RETURN (result
,
1800 ACE_WIN32_Asynch_Write_File_Result (this->handler_proxy_
,
1807 this->win32_proactor_
->get_handle (),
1810 1), // gather write enabled
1813 result
->set_error(0);
1815 // do the gather write
1816 int initiate_result
= ::WriteFileGather (result
->handle (),
1818 dword_bytes_to_write
,
1819 0, // reserved, must be NULL
1822 if (0 != initiate_result
)
1823 // Immediate success: the OVERLAPPED will still get queued.
1826 // If initiate failed, check for a bad error.
1827 ACE_OS::set_errno_to_last_error ();
1830 case ERROR_IO_PENDING
:
1831 // The IO will complete proactively: the OVERLAPPED will still
1833 initiate_result
= 0;
1837 // Something else went wrong: the OVERLAPPED will not get
1842 ACELIB_DEBUG ((LM_ERROR
,
1844 ACE_TEXT ("WriteFileGather")));
1848 initiate_result
= -1;
1852 return initiate_result
;
1855 ACE_NOTSUP_RETURN (-1);
1857 #endif /* ACE_HAS_WIN32_OVERLAPPED_IO */
1861 ACE_WIN32_Asynch_Write_File::~ACE_WIN32_Asynch_Write_File ()
1866 ACE_WIN32_Asynch_Write_File::write (ACE_Message_Block
&message_block
,
1867 size_t bytes_to_write
,
1872 return this->write (message_block
,
1881 ACE_WIN32_Asynch_Write_File::writev (ACE_Message_Block
&message_block
,
1882 size_t bytes_to_write
,
1887 return this->writev (message_block
,
1895 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
1896 // methods are defined here to avoid VC++ warnings. They route the
1897 // call to the ACE_WIN32_Asynch_Operation base class.
1900 ACE_WIN32_Asynch_Write_File::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
1902 const void *completion_key
,
1903 ACE_Proactor
*proactor
)
1905 return ACE_WIN32_Asynch_Operation::open (handler_proxy
,
1912 ACE_WIN32_Asynch_Write_File::cancel ()
1914 return ACE_WIN32_Asynch_Operation::cancel ();
1918 ACE_WIN32_Asynch_Write_File::proactor () const
1920 return ACE_WIN32_Asynch_Operation::proactor ();
1924 ACE_WIN32_Asynch_Accept_Result::bytes_to_read () const
1926 return this->bytes_to_read_
;
1930 ACE_WIN32_Asynch_Accept_Result::message_block () const
1932 return this->message_block_
;
1936 ACE_WIN32_Asynch_Accept_Result::listen_handle () const
1938 return this->listen_handle_
;
1942 ACE_WIN32_Asynch_Accept_Result::accept_handle () const
1944 return this->accept_handle_
;
1947 ACE_WIN32_Asynch_Accept_Result::ACE_WIN32_Asynch_Accept_Result (
1948 const ACE_Handler::Proxy_Ptr
&handler_proxy
,
1949 ACE_HANDLE listen_handle
,
1950 ACE_HANDLE accept_handle
,
1951 ACE_Message_Block
&message_block
,
1952 size_t bytes_to_read
,
1957 : ACE_Asynch_Result_Impl (),
1958 ACE_Asynch_Accept_Result_Impl (),
1959 ACE_WIN32_Asynch_Result (handler_proxy
,
1966 bytes_to_read_ (bytes_to_read
),
1967 message_block_ (message_block
),
1968 listen_handle_ (listen_handle
),
1969 accept_handle_ (accept_handle
)
1974 ACE_WIN32_Asynch_Accept_Result::complete (size_t bytes_transferred
,
1976 const void *completion_key
,
1979 // Copy the data which was returned by GetQueuedCompletionStatus
1980 this->bytes_transferred_
= bytes_transferred
;
1981 this->success_
= success
;
1982 this->completion_key_
= completion_key
;
1983 this->error_
= error
;
1985 // Appropriately move the pointers in the message block.
1986 this->message_block_
.wr_ptr (bytes_transferred
);
1988 if (!success
&& this->accept_handle_
!= ACE_INVALID_HANDLE
)
1990 ACE_OS::closesocket (this->accept_handle_
);
1991 this->accept_handle_
= ACE_INVALID_HANDLE
;
1994 // Create the interface result class.
1995 ACE_Asynch_Accept::Result
result (this);
1997 // Call the application handler.
1998 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
2000 handler
->handle_accept (result
);
2003 ACE_WIN32_Asynch_Accept_Result::~ACE_WIN32_Asynch_Accept_Result ()
2007 // Base class operations. These operations are here to kill dominance
2008 // warnings. These methods call the base class methods.
2011 ACE_WIN32_Asynch_Accept_Result::bytes_transferred () const
2013 return ACE_WIN32_Asynch_Result::bytes_transferred ();
2017 ACE_WIN32_Asynch_Accept_Result::act () const
2019 return ACE_WIN32_Asynch_Result::act ();
2023 ACE_WIN32_Asynch_Accept_Result::success () const
2025 return ACE_WIN32_Asynch_Result::success ();
2029 ACE_WIN32_Asynch_Accept_Result::completion_key () const
2031 return ACE_WIN32_Asynch_Result::completion_key ();
2035 ACE_WIN32_Asynch_Accept_Result::error () const
2037 return ACE_WIN32_Asynch_Result::error ();
2041 ACE_WIN32_Asynch_Accept_Result::event () const
2043 return ACE_WIN32_Asynch_Result::event ();
2047 ACE_WIN32_Asynch_Accept_Result::offset () const
2049 return ACE_WIN32_Asynch_Result::offset ();
2053 ACE_WIN32_Asynch_Accept_Result::offset_high () const
2055 return ACE_WIN32_Asynch_Result::offset_high ();
2059 ACE_WIN32_Asynch_Accept_Result::priority () const
2061 return ACE_WIN32_Asynch_Result::priority ();
2065 ACE_WIN32_Asynch_Accept_Result::signal_number () const
2067 return ACE_WIN32_Asynch_Result::signal_number ();
2071 ACE_WIN32_Asynch_Accept_Result::post_completion (ACE_Proactor_Impl
*proactor
)
2073 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
2076 ACE_WIN32_Asynch_Accept::ACE_WIN32_Asynch_Accept (ACE_WIN32_Proactor
*win32_proactor
)
2077 : ACE_Asynch_Operation_Impl (),
2078 ACE_Asynch_Accept_Impl (),
2079 ACE_WIN32_Asynch_Operation (win32_proactor
)
2084 ACE_WIN32_Asynch_Accept::accept (ACE_Message_Block
&message_block
,
2085 size_t bytes_to_read
,
2086 ACE_HANDLE accept_handle
,
2092 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
2093 // Sanity check: make sure that enough space has been allocated by
2095 size_t address_size
=
2096 #if defined (ACE_HAS_IPV6)
2097 addr_family
== AF_INET
? sizeof (sockaddr_in
) : sizeof (sockaddr_in6
);
2099 sizeof (sockaddr_in
);
2100 #endif /* ACE_HAS_IPV6 */
2101 address_size
+= 16; // AcceptEx requires address size + 16 (minimum)
2102 size_t available_space
= message_block
.space ();
2103 size_t space_needed
= bytes_to_read
+ 2 * address_size
;
2104 if (available_space
< space_needed
)
2105 ACELIB_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("Buffer too small\n")), -1);
2109 // AcceptEx API limits us to DWORD range.
2110 if (bytes_to_read
> MAXDWORD
)
2115 DWORD dword_bytes_to_read
= static_cast<DWORD
> (bytes_to_read
);
2117 int close_accept_handle
= 0;
2118 // If the <accept_handle> is invalid, we will create a new socket.
2119 if (accept_handle
== ACE_INVALID_HANDLE
)
2121 accept_handle
= ACE_OS::socket (addr_family
,
2124 if (accept_handle
== ACE_INVALID_HANDLE
)
2128 ACELIB_DEBUG ((LM_ERROR
,
2130 ACE_TEXT ("ACE_OS::socket")));
2135 // Remember to close the socket down if failures occur.
2136 close_accept_handle
= 1;
2139 // Common code for both WIN and POSIX.
2140 ACE_WIN32_Asynch_Accept_Result
*result
= 0;
2141 ACE_NEW_RETURN (result
,
2142 ACE_WIN32_Asynch_Accept_Result (this->handler_proxy_
,
2148 this->win32_proactor_
->get_handle (),
2155 // Initiate the accept.
2156 int initiate_result
= ::AcceptEx ((SOCKET
) result
->listen_handle (),
2157 (SOCKET
) result
->accept_handle (),
2158 result
->message_block ().wr_ptr (),
2159 dword_bytes_to_read
,
2160 static_cast<DWORD
> (address_size
),
2161 static_cast<DWORD
> (address_size
),
2164 if (initiate_result
== 1)
2165 // Immediate success: the OVERLAPPED will still get queued.
2168 // If initiate failed, check for a bad error.
2169 ACE_OS::set_errno_to_last_error ();
2172 case ERROR_IO_PENDING
:
2173 // The IO will complete proactively: the OVERLAPPED will still
2178 // Something else went wrong: the OVERLAPPED will not get
2181 if (close_accept_handle
== 1)
2182 // Close the newly created socket
2183 ACE_OS::closesocket (accept_handle
);
2185 // Cleanup dynamically allocated Asynch_Result.
2190 ACELIB_DEBUG ((LM_ERROR
,
2192 ACE_TEXT ("AcceptEx")));
2197 ACE_UNUSED_ARG (message_block
);
2198 ACE_UNUSED_ARG (bytes_to_read
);
2199 ACE_UNUSED_ARG (accept_handle
);
2200 ACE_UNUSED_ARG (act
);
2201 ACE_UNUSED_ARG (priority
);
2202 ACE_UNUSED_ARG (signal_number
);
2203 ACE_UNUSED_ARG (addr_family
);
2204 ACE_NOTSUP_RETURN (-1);
2205 #endif /* defined (ACE_HAS_WIN32_OVERLAPPED_IO) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)) */
2208 ACE_WIN32_Asynch_Accept::~ACE_WIN32_Asynch_Accept ()
2212 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
2213 // methods are defined here to avoid VC++ warnings. They route the
2214 // call to the ACE_WIN32_Asynch_Operation base class.
2217 ACE_WIN32_Asynch_Accept::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
2219 const void *completion_key
,
2220 ACE_Proactor
*proactor
)
2222 return ACE_WIN32_Asynch_Operation::open (handler_proxy
,
2229 ACE_WIN32_Asynch_Accept::cancel ()
2231 return ACE_WIN32_Asynch_Operation::cancel ();
2235 ACE_WIN32_Asynch_Accept::proactor () const
2237 return ACE_WIN32_Asynch_Operation::proactor ();
2240 // *********************************************************************
2243 ACE_WIN32_Asynch_Connect_Result::connect_handle () const
2245 return this->connect_handle_
;
2248 void ACE_WIN32_Asynch_Connect_Result::connect_handle ( ACE_HANDLE handle
)
2250 this->connect_handle_
= handle
;
2254 ACE_WIN32_Asynch_Connect_Result::ACE_WIN32_Asynch_Connect_Result
2255 (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
2256 ACE_HANDLE connect_handle
,
2261 : ACE_Asynch_Result_Impl (),
2262 ACE_Asynch_Connect_Result_Impl (),
2263 ACE_WIN32_Asynch_Result
2264 (handler_proxy
, act
, event
, 0, 0, priority
, signal_number
),
2265 connect_handle_ (connect_handle
)
2271 ACE_WIN32_Asynch_Connect_Result::complete (size_t bytes_transferred
,
2273 const void *completion_key
,
2277 this->bytes_transferred_
= bytes_transferred
;
2278 this->success_
= success
;
2279 this->completion_key_
= completion_key
;
2280 this->error_
= error
;
2282 // Create the interface result class.
2283 ACE_Asynch_Connect::Result
result (this);
2285 // Call the application handler.
2286 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
2288 handler
->handle_connect (result
);
2291 ACE_WIN32_Asynch_Connect_Result::~ACE_WIN32_Asynch_Connect_Result ()
2295 // Base class operations. These operations are here to kill dominance
2296 // warnings. These methods call the base class methods.
2299 ACE_WIN32_Asynch_Connect_Result::bytes_transferred () const
2301 return ACE_WIN32_Asynch_Result::bytes_transferred ();
2305 ACE_WIN32_Asynch_Connect_Result::act () const
2307 return ACE_WIN32_Asynch_Result::act ();
2311 ACE_WIN32_Asynch_Connect_Result::success () const
2313 return ACE_WIN32_Asynch_Result::success ();
2317 ACE_WIN32_Asynch_Connect_Result::completion_key () const
2319 return ACE_WIN32_Asynch_Result::completion_key ();
2323 ACE_WIN32_Asynch_Connect_Result::error () const
2325 return ACE_WIN32_Asynch_Result::error ();
2329 ACE_WIN32_Asynch_Connect_Result::event () const
2331 return ACE_WIN32_Asynch_Result::event ();
2335 ACE_WIN32_Asynch_Connect_Result::offset () const
2337 return ACE_WIN32_Asynch_Result::offset ();
2341 ACE_WIN32_Asynch_Connect_Result::offset_high () const
2343 return ACE_WIN32_Asynch_Result::offset_high ();
2347 ACE_WIN32_Asynch_Connect_Result::priority () const
2349 return ACE_WIN32_Asynch_Result::priority ();
2353 ACE_WIN32_Asynch_Connect_Result::signal_number () const
2355 return ACE_WIN32_Asynch_Result::signal_number ();
2359 ACE_WIN32_Asynch_Connect_Result::post_completion (ACE_Proactor_Impl
*proactor
)
2361 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
2364 // *********************************************************************
2366 ACE_WIN32_Asynch_Connect::ACE_WIN32_Asynch_Connect (ACE_WIN32_Proactor
* win32_proactor
)
2367 : ACE_Asynch_Operation_Impl (),
2368 ACE_Asynch_Connect_Impl (),
2369 ACE_WIN32_Asynch_Operation (win32_proactor
),
2374 ACE_WIN32_Asynch_Connect::~ACE_WIN32_Asynch_Connect ()
2377 this->reactor (0); // to avoid purge_pending_notifications
2381 ACE_WIN32_Asynch_Connect::proactor () const
2383 return ACE_WIN32_Asynch_Operation::proactor ();
2387 ACE_WIN32_Asynch_Connect::get_handle () const
2390 return ACE_INVALID_HANDLE
;
2394 ACE_WIN32_Asynch_Connect::set_handle (ACE_HANDLE
)
2400 ACE_WIN32_Asynch_Connect::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
2402 const void *completion_key
,
2403 ACE_Proactor
*proactor
)
2405 ACE_TRACE ("ACE_WIN32_Asynch_Connect::open");
2407 // if we are already opened,
2408 // we could not create a new handler without closing the previous
2409 if (this->flg_open_
)
2410 ACELIB_ERROR_RETURN ((LM_ERROR
,
2411 ACE_TEXT ("%N:%l:ACE_WIN32_Asynch_Connect::open:")
2412 ACE_TEXT ("connector already open\n")),
2416 ACE_WIN32_Asynch_Operation::open (handler_proxy
,
2421 // Ignore result as we pass ACE_INVALID_HANDLE
2425 this->flg_open_
= true;
2431 ACE_WIN32_Asynch_Connect::connect (ACE_HANDLE connect_handle
,
2432 const ACE_Addr
& remote_sap
,
2433 const ACE_Addr
& local_sap
,
2439 ACE_TRACE ("ACE_WIN32_Asynch_Connect::connect");
2441 if (!this->flg_open_
)
2442 ACELIB_ERROR_RETURN ((LM_ERROR
,
2443 ACE_TEXT ("%N:%l:ACE_WIN32_Asynch_Connect::connect")
2444 ACE_TEXT ("connector was not opened before\n")),
2447 // Common code for both WIN and WIN32.
2448 // Create future Asynch_Connect_Result
2449 ACE_WIN32_Asynch_Connect_Result
*result
= 0;
2450 ACE_NEW_RETURN (result
,
2451 ACE_WIN32_Asynch_Connect_Result (this->handler_proxy_
,
2454 this->win32_proactor_
->get_handle (),
2459 int rc
= connect_i (result
,
2465 connect_handle
= result
->connect_handle ();
2468 return post_result (result
, true);
2470 // Enqueue result we will wait for completion
2472 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->lock_
, -1));
2474 if (this->result_map_
.bind (connect_handle
, result
) == -1)
2476 ACELIB_ERROR ((LM_ERROR
,
2477 ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect: %p\n"),
2478 ACE_TEXT ("bind")));
2479 result
->set_error (EFAULT
);
2480 return post_result (result
, true);
2484 ACE_Asynch_Pseudo_Task
& task
=
2485 this->win32_proactor_
->get_asynch_pseudo_task ();
2487 if (-1 == task
.register_io_handler (connect_handle
,
2489 ACE_Event_Handler::CONNECT_MASK
,
2490 0)) // not to suspend after register
2494 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->lock_
, -1));
2495 this->result_map_
.unbind (connect_handle
, result
);
2499 result
->set_error (EFAULT
);
2500 this->post_result (result
, true);
2507 int ACE_WIN32_Asynch_Connect::post_result (ACE_WIN32_Asynch_Connect_Result
* result
,
2510 ACE_HANDLE handle
= result
->connect_handle ();
2511 if (this->flg_open_
&& post_enable
)
2513 // NOTE: result is invalid after post_completion(). It's either deleted
2514 // or will be shortly via the proactor dispatch, regardless of success
2515 // or fail of the call.
2516 if (this->win32_proactor_
->post_completion (result
) == 0)
2519 ACELIB_ERROR ((LM_ERROR
,
2520 ACE_TEXT ("Error:(%P | %t):%p\n"),
2521 ACE_TEXT ("ACE_WIN32_Asynch_Connect::post_result: ")
2522 ACE_TEXT (" <post_completion> failed")));
2526 // There was no call to post_completion() so manually delete result.
2530 if (handle
!= ACE_INVALID_HANDLE
)
2531 ACE_OS::closesocket (handle
);
2538 // -1 errors before attempt to connect
2539 // 0 connect started
2540 // 1 connect finished ( may be unsuccessfully)
2543 ACE_WIN32_Asynch_Connect::connect_i (ACE_WIN32_Asynch_Connect_Result
*result
,
2544 const ACE_Addr
& remote_sap
,
2545 const ACE_Addr
& local_sap
,
2548 result
->set_bytes_transferred (0);
2550 ACE_HANDLE handle
= result
->connect_handle ();
2551 if (handle
== ACE_INVALID_HANDLE
)
2553 int protocol_family
= remote_sap
.get_type ();
2554 handle
= ACE_OS::socket (protocol_family
,
2559 result
->connect_handle (handle
);
2560 if (handle
== ACE_INVALID_HANDLE
)
2562 result
->set_error (errno
);
2565 ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"),
2566 ACE_TEXT ("socket")),
2570 // Reuse the address
2572 if (protocol_family
!= PF_UNIX
&&
2574 ACE_OS::setsockopt (handle
,
2580 result
->set_error (errno
);
2583 ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"),
2584 ACE_TEXT ("setsockopt")),
2589 if (local_sap
!= ACE_Addr::sap_any
)
2591 sockaddr
* laddr
= reinterpret_cast<sockaddr
*> (local_sap
.get_addr ());
2592 int size
= local_sap
.get_size ();
2593 if (ACE_OS::bind (handle
, laddr
, size
) == -1)
2595 result
->set_error (errno
);
2598 ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"),
2604 // set non blocking mode
2605 if (ACE::set_flags (handle
, ACE_NONBLOCK
) != 0)
2607 result
->set_error (errno
);
2610 ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"),
2611 ACE_TEXT ("set_flags")),
2617 int rc
= ACE_OS::connect
2619 reinterpret_cast<sockaddr
*> (remote_sap
.get_addr ()),
2620 remote_sap
.get_size ());
2622 if (rc
< 0) // failure
2624 if (errno
== EWOULDBLOCK
|| errno
== EINPROGRESS
)
2625 return 0; // connect started
2630 result
->set_error (errno
);
2632 return 1 ; // connect finished
2637 // cancel_uncompleted
2638 // It performs cancellation of all pending requests
2640 // Parameter flg_notify can be
2641 // 0 - don't send notifications about canceled accepts
2642 // !0 - notify user about canceled accepts
2643 // according WIN32 standards we should receive notifications
2644 // on canceled AIO requests
2646 // Return value : number of cancelled requests
2650 ACE_WIN32_Asynch_Connect::cancel_uncompleted (bool flg_notify
,
2651 ACE_Handle_Set
&set
)
2653 ACE_TRACE ("ACE_WIN32_Asynch_Connect::cancel_uncompleted");
2657 MAP_MANAGER::ITERATOR
iter (result_map_
);
2658 MAP_MANAGER::ENTRY
* me
= 0;
2662 for (; iter
.next (me
) != 0; retval
++, iter
.advance ())
2664 ACE_HANDLE handle
= me
->ext_id_
;
2665 ACE_WIN32_Asynch_Connect_Result
* result
= me
->int_id_
;
2667 set
.set_bit (handle
);
2669 result
->set_bytes_transferred (0);
2670 result
->set_error (ERROR_OPERATION_ABORTED
);
2671 this->post_result (result
, flg_notify
);
2674 result_map_
.unbind_all ();
2680 ACE_WIN32_Asynch_Connect::cancel ()
2682 ACE_TRACE ("ACE_WIN32_Asynch_Connect::cancel");
2684 int rc
= -1 ; // ERRORS
2687 int num_cancelled
= 0;
2689 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->lock_
, -1));
2691 num_cancelled
= cancel_uncompleted (flg_open_
, set
);
2693 if (num_cancelled
== 0)
2694 rc
= 1; // AIO_ALLDONE
2695 else if (num_cancelled
> 0)
2696 rc
= 0; // AIO_CANCELED
2698 if (!this->flg_open_
)
2701 ACE_Asynch_Pseudo_Task
& task
=
2702 this->win32_proactor_
->get_asynch_pseudo_task ();
2704 task
.remove_io_handler (set
);
2709 ACE_WIN32_Asynch_Connect::close ()
2711 ACE_TRACE ("ACE_WIN32_Asynch_Connect::close");
2714 int num_cancelled
= 0;
2716 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->lock_
, -1));
2718 num_cancelled
= cancel_uncompleted (flg_open_
, set
);
2720 if (num_cancelled
== 0 || this->flg_open_
== 0)
2722 this->flg_open_
= false;
2726 ACE_Asynch_Pseudo_Task
& task
=
2727 this->win32_proactor_
->get_asynch_pseudo_task ();
2729 task
.remove_io_handler (set
);
2734 ACE_WIN32_Asynch_Connect::handle_exception (ACE_HANDLE fd
)
2736 ACE_TRACE ("ACE_WIN32_Asynch_Connect::handle_exception");
2737 return handle_output (fd
);
2741 ACE_WIN32_Asynch_Connect::handle_input (ACE_HANDLE fd
)
2743 ACE_TRACE ("ACE_WIN32_Asynch_Connect::handle_input");
2744 return handle_output (fd
);
2748 ACE_WIN32_Asynch_Connect::handle_output (ACE_HANDLE fd
)
2750 ACE_TRACE ("ACE_WIN32_Asynch_Connect::handle_output");
2752 ACE_WIN32_Asynch_Connect_Result
* result
= 0;
2755 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->lock_
, 0));
2756 if (this->result_map_
.unbind (fd
, result
) != 0) // not found
2761 int lsockerror
= sizeof sockerror
;
2763 ACE_OS::getsockopt (fd
,
2766 (char*) & sockerror
,
2769 // This previously just did a "return -1" and let handle_close() clean
2770 // things up. However, this entire object may be gone as a result of
2771 // the application's completion handler, so don't count on 'this' being
2772 // legitimate on return from post_result().
2773 // remove_io_handler() contains flag DONT_CALL
2774 this->win32_proactor_
->get_asynch_pseudo_task().remove_io_handler (fd
);
2776 result
->set_bytes_transferred (0);
2777 result
->set_error (sockerror
);
2778 this->post_result (result
, this->flg_open_
);
2784 ACE_WIN32_Asynch_Connect::handle_close (ACE_HANDLE fd
, ACE_Reactor_Mask
)
2786 ACE_TRACE ("ACE_WIN32_Asynch_Connect::handle_close");
2788 ACE_Asynch_Pseudo_Task
& task
=
2789 this->win32_proactor_
->get_asynch_pseudo_task ();
2790 task
.remove_io_handler (fd
);
2792 ACE_WIN32_Asynch_Connect_Result
* result
= 0;
2795 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->lock_
, 0));
2796 if (this->result_map_
.unbind (fd
, result
) != 0) // not found
2800 result
->set_bytes_transferred (0);
2801 result
->set_error (ERROR_OPERATION_ABORTED
);
2802 this->post_result (result
, this->flg_open_
);
2807 // *********************************************************************
2810 ACE_WIN32_Asynch_Transmit_File_Result::socket () const
2812 return this->socket_
;
2816 ACE_WIN32_Asynch_Transmit_File_Result::file () const
2821 ACE_Asynch_Transmit_File::Header_And_Trailer
*
2822 ACE_WIN32_Asynch_Transmit_File_Result::header_and_trailer () const
2824 return this->header_and_trailer_
;
2828 ACE_WIN32_Asynch_Transmit_File_Result::bytes_to_write () const
2830 return this->bytes_to_write_
;
2834 ACE_WIN32_Asynch_Transmit_File_Result::bytes_per_send () const
2836 return this->bytes_per_send_
;
2840 ACE_WIN32_Asynch_Transmit_File_Result::flags () const
2842 return this->flags_
;
2845 ACE_WIN32_Asynch_Transmit_File_Result::ACE_WIN32_Asynch_Transmit_File_Result (
2846 const ACE_Handler::Proxy_Ptr
&handler_proxy
,
2849 ACE_Asynch_Transmit_File::Header_And_Trailer
*header_and_trailer
,
2850 size_t bytes_to_write
,
2853 size_t bytes_per_send
,
2859 : ACE_Asynch_Result_Impl (),
2860 ACE_Asynch_Transmit_File_Result_Impl (),
2861 ACE_WIN32_Asynch_Result (handler_proxy
,
2870 header_and_trailer_ (header_and_trailer
),
2871 bytes_to_write_ (bytes_to_write
),
2872 bytes_per_send_ (bytes_per_send
),
2878 ACE_WIN32_Asynch_Transmit_File_Result::complete (size_t bytes_transferred
,
2880 const void *completion_key
,
2883 // Copy the data which was returned by GetQueuedCompletionStatus
2884 this->bytes_transferred_
= bytes_transferred
;
2885 this->success_
= success
;
2886 this->completion_key_
= completion_key
;
2887 this->error_
= error
;
2889 // We will not do this because (a) the header and trailer blocks may
2890 // be the same message_blocks and (b) in cases of failures we have
2891 // no idea how much of what (header, data, trailer) was sent.
2893 if (this->success_ && this->header_and_trailer_ != 0)
2895 ACE_Message_Block *header = this->header_and_trailer_->header ();
2897 header->rd_ptr (this->header_and_trailer_->header_bytes ());
2899 ACE_Message_Block *trailer = this->header_and_trailer_->trailer ();
2901 trailer->rd_ptr (this->header_and_trailer_->trailer_bytes ());
2905 // Create the interface result class.
2906 ACE_Asynch_Transmit_File::Result
result (this);
2908 // Call the application handler.
2909 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
2911 handler
->handle_transmit_file (result
);
2914 ACE_WIN32_Asynch_Transmit_File_Result::~ACE_WIN32_Asynch_Transmit_File_Result ()
2918 // Base class operations. These operations are here to kill dominance
2919 // warnings. These methods call the base class methods.
2922 ACE_WIN32_Asynch_Transmit_File_Result::bytes_transferred () const
2924 return ACE_WIN32_Asynch_Result::bytes_transferred ();
2928 ACE_WIN32_Asynch_Transmit_File_Result::act () const
2930 return ACE_WIN32_Asynch_Result::act ();
2934 ACE_WIN32_Asynch_Transmit_File_Result::success () const
2936 return ACE_WIN32_Asynch_Result::success ();
2940 ACE_WIN32_Asynch_Transmit_File_Result::completion_key () const
2942 return ACE_WIN32_Asynch_Result::completion_key ();
2946 ACE_WIN32_Asynch_Transmit_File_Result::error () const
2948 return ACE_WIN32_Asynch_Result::error ();
2952 ACE_WIN32_Asynch_Transmit_File_Result::event () const
2954 return ACE_WIN32_Asynch_Result::event ();
2958 ACE_WIN32_Asynch_Transmit_File_Result::offset () const
2960 return ACE_WIN32_Asynch_Result::offset ();
2964 ACE_WIN32_Asynch_Transmit_File_Result::offset_high () const
2966 return ACE_WIN32_Asynch_Result::offset_high ();
2970 ACE_WIN32_Asynch_Transmit_File_Result::priority () const
2972 return ACE_WIN32_Asynch_Result::priority ();
2976 ACE_WIN32_Asynch_Transmit_File_Result::signal_number () const
2978 return ACE_WIN32_Asynch_Result::signal_number ();
2982 ACE_WIN32_Asynch_Transmit_File_Result::post_completion (ACE_Proactor_Impl
*proactor
)
2984 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
2987 ACE_WIN32_Asynch_Transmit_File::ACE_WIN32_Asynch_Transmit_File (ACE_WIN32_Proactor
*win32_proactor
)
2988 : ACE_Asynch_Operation_Impl (),
2989 ACE_Asynch_Transmit_File_Impl (),
2990 ACE_WIN32_Asynch_Operation (win32_proactor
)
2995 ACE_WIN32_Asynch_Transmit_File::transmit_file (ACE_HANDLE file
,
2996 ACE_Asynch_Transmit_File::Header_And_Trailer
*header_and_trailer
,
2997 size_t bytes_to_write
,
3000 size_t bytes_per_send
,
3006 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
3008 // TransmitFile API limits us to DWORD range.
3009 if (bytes_to_write
> MAXDWORD
|| bytes_per_send
> MAXDWORD
)
3014 DWORD dword_bytes_to_write
= static_cast<DWORD
> (bytes_to_write
);
3015 DWORD dword_bytes_per_send
= static_cast<DWORD
> (bytes_per_send
);
3017 ACE_WIN32_Asynch_Transmit_File_Result
*result
= 0;
3018 ACE_NEW_RETURN (result
,
3019 ACE_WIN32_Asynch_Transmit_File_Result (this->handler_proxy_
,
3029 this->win32_proactor_
->get_handle (),
3034 ACE_LPTRANSMIT_FILE_BUFFERS transmit_buffers
= 0;
3035 if (result
->header_and_trailer () != 0)
3036 transmit_buffers
= result
->header_and_trailer ()->transmit_buffers ();
3038 // Initiate the transmit file
3039 int initiate_result
= ::TransmitFile ((SOCKET
) result
->socket (),
3041 dword_bytes_to_write
,
3042 dword_bytes_per_send
,
3046 if (initiate_result
== 1)
3047 // Immediate success: the OVERLAPPED will still get queued.
3050 // If initiate failed, check for a bad error.
3051 ACE_OS::set_errno_to_last_error ();
3054 case ERROR_IO_PENDING
:
3055 // The IO will complete proactively: the OVERLAPPED will still
3060 // Something else went wrong: the OVERLAPPED will not get
3063 // Cleanup dynamically allocated Asynch_Result
3068 ACELIB_DEBUG ((LM_ERROR
,
3070 ACE_TEXT ("TransmitFile")));
3075 ACE_UNUSED_ARG (file
);
3076 ACE_UNUSED_ARG (header_and_trailer
);
3077 ACE_UNUSED_ARG (bytes_to_write
);
3078 ACE_UNUSED_ARG (offset
);
3079 ACE_UNUSED_ARG (offset_high
);
3080 ACE_UNUSED_ARG (bytes_per_send
);
3081 ACE_UNUSED_ARG (flags
);
3082 ACE_UNUSED_ARG (act
);
3083 ACE_UNUSED_ARG (priority
);
3084 ACE_UNUSED_ARG (signal_number
);
3085 ACE_NOTSUP_RETURN (-1);
3086 #endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_WINSOCK2 */
3089 ACE_WIN32_Asynch_Transmit_File::~ACE_WIN32_Asynch_Transmit_File ()
3093 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
3094 // methods are defined here to avoid VC++ warnings. They route the
3095 // call to the ACE_WIN32_Asynch_Operation base class.
3098 ACE_WIN32_Asynch_Transmit_File::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
3100 const void *completion_key
,
3101 ACE_Proactor
*proactor
)
3103 return ACE_WIN32_Asynch_Operation::open (handler_proxy
,
3110 ACE_WIN32_Asynch_Transmit_File::cancel ()
3112 return ACE_WIN32_Asynch_Operation::cancel ();
3116 ACE_WIN32_Asynch_Transmit_File::proactor () const
3118 return ACE_WIN32_Asynch_Operation::proactor ();
3122 ACE_WIN32_Asynch_Read_Dgram_Result::bytes_to_read () const
3124 return this->bytes_to_read_
;
3128 ACE_WIN32_Asynch_Read_Dgram_Result::message_block () const
3130 return this->message_block_
;
3135 ACE_WIN32_Asynch_Read_Dgram_Result::remote_address (ACE_Addr
& addr
) const
3137 int retVal
= -1; // failure
3139 // make sure the addresses are of the same type
3140 if (addr
.get_type () == this->remote_address_
->get_type ())
3141 { // copy the remote_address_ into addr
3142 addr
.set_addr (this->remote_address_
->get_addr (),
3143 this->remote_address_
->get_size ());
3144 retVal
= 0; // success
3151 ACE_WIN32_Asynch_Read_Dgram_Result::saddr () const
3153 return (sockaddr
*) this->remote_address_
->get_addr ();
3158 ACE_WIN32_Asynch_Read_Dgram_Result::flags () const
3160 return this->flags_
;
3164 ACE_WIN32_Asynch_Read_Dgram_Result::handle () const
3166 return this->handle_
;
3170 ACE_WIN32_Asynch_Read_Dgram_Result::bytes_transferred () const
3172 return ACE_WIN32_Asynch_Result::bytes_transferred ();
3176 ACE_WIN32_Asynch_Read_Dgram_Result::act () const
3178 return ACE_WIN32_Asynch_Result::act ();
3182 ACE_WIN32_Asynch_Read_Dgram_Result::success () const
3184 return ACE_WIN32_Asynch_Result::success ();
3188 ACE_WIN32_Asynch_Read_Dgram_Result::completion_key () const
3190 return ACE_WIN32_Asynch_Result::completion_key ();
3194 ACE_WIN32_Asynch_Read_Dgram_Result::error () const
3196 return ACE_WIN32_Asynch_Result::error ();
3200 ACE_WIN32_Asynch_Read_Dgram_Result::event () const
3202 return ACE_WIN32_Asynch_Result::event ();
3206 ACE_WIN32_Asynch_Read_Dgram_Result::offset () const
3208 return ACE_WIN32_Asynch_Result::offset ();
3212 ACE_WIN32_Asynch_Read_Dgram_Result::offset_high () const
3214 return ACE_WIN32_Asynch_Result::offset_high ();
3218 ACE_WIN32_Asynch_Read_Dgram_Result::priority () const
3220 return ACE_WIN32_Asynch_Result::priority ();
3224 ACE_WIN32_Asynch_Read_Dgram_Result::signal_number () const
3226 return ACE_WIN32_Asynch_Result::signal_number ();
3230 ACE_WIN32_Asynch_Read_Dgram_Result::post_completion (ACE_Proactor_Impl
*proactor
)
3232 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
3235 ACE_WIN32_Asynch_Read_Dgram_Result::ACE_WIN32_Asynch_Read_Dgram_Result (
3236 const ACE_Handler::Proxy_Ptr
&handler_proxy
,
3238 ACE_Message_Block
*message_block
,
3239 size_t bytes_to_read
,
3241 int protocol_family
,
3246 : ACE_Asynch_Result_Impl (),
3247 ACE_Asynch_Read_Dgram_Result_Impl(),
3248 ACE_WIN32_Asynch_Result (handler_proxy
, act
, event
, 0, 0, priority
, signal_number
),
3249 bytes_to_read_ (bytes_to_read
),
3250 message_block_ (message_block
),
3251 remote_address_ (0),
3256 ACE_ASSERT (protocol_family
== PF_INET
); // only supporting INET addresses
3258 ACE_NEW (remote_address_
, ACE_INET_Addr
);
3259 addr_len_
= remote_address_
->get_size ();
3261 ACE_UNUSED_ARG (protocol_family
);
3265 ACE_WIN32_Asynch_Read_Dgram_Result::complete (size_t bytes_transferred
,
3267 const void *completion_key
,
3270 // Copy the data which was returned by GetQueuedCompletionStatus
3271 this->bytes_transferred_
= bytes_transferred
;
3272 this->success_
= success
;
3273 this->completion_key_
= completion_key
;
3274 this->error_
= error
;
3276 // Appropriately move the pointers in the message block.
3277 for (ACE_Message_Block
* mb
= this->message_block_
;
3278 (mb
!= 0) && (bytes_transferred
> 0);
3281 size_t len_part
= mb
->space ();
3283 if ( len_part
> bytes_transferred
)
3284 len_part
= bytes_transferred
;
3286 mb
->wr_ptr (len_part
);
3288 bytes_transferred
-= len_part
;
3291 // Adjust the address length
3292 this->remote_address_
->set_size (this->addr_len_
);
3294 // Create the interface result class.
3295 ACE_Asynch_Read_Dgram::Result
result (this);
3297 // Call the application handler.
3298 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
3300 handler
->handle_read_dgram (result
);
3303 ACE_WIN32_Asynch_Read_Dgram_Result::~ACE_WIN32_Asynch_Read_Dgram_Result ()
3305 delete this->remote_address_
;
3308 //***************************************************************************
3310 ACE_WIN32_Asynch_Read_Dgram::~ACE_WIN32_Asynch_Read_Dgram ()
3315 ACE_WIN32_Asynch_Read_Dgram::recv (ACE_Message_Block
*message_block
,
3316 size_t & number_of_bytes_recvd
,
3318 int protocol_family
,
3323 number_of_bytes_recvd
= 0;
3325 size_t bytes_to_read
= 0;
3327 iovec iov
[ACE_IOV_MAX
];
3330 for (const ACE_Message_Block
* msg
= message_block
;
3331 msg
!= 0 && iovcnt
< ACE_IOV_MAX
;
3332 msg
= msg
->cont () , ++iovcnt
)
3334 size_t msg_space
= msg
->space ();
3336 // OS should correctly process zero length buffers
3337 // if ( msg_space == 0 )
3338 // ACELIB_ERROR_RETURN ((LM_ERROR,
3339 // ACE_TEXT ("ACE_WIN32_Asynch_Read_Dgram::recv:")
3340 // ACE_TEXT ("No space in the message block\n")),
3343 bytes_to_read
+= msg_space
;
3345 // Make as many iovec as needed to fit all of msg_len.
3346 size_t wr_ptr_offset
= 0;
3348 while (msg_space
> 0 && iovcnt
< ACE_IOV_MAX
)
3350 u_long this_chunk_length
;
3351 if (msg_space
> ULONG_MAX
)
3352 this_chunk_length
= ULONG_MAX
;
3354 this_chunk_length
= static_cast<u_long
> (msg_space
);
3355 // Collect the data in the iovec.
3356 iov
[iovcnt
].iov_base
= msg
->wr_ptr () + wr_ptr_offset
;
3357 iov
[iovcnt
].iov_len
= this_chunk_length
;
3358 msg_space
-= this_chunk_length
;
3359 wr_ptr_offset
+= this_chunk_length
;
3361 // Increment iovec counter if there's more to do.
3365 if (msg_space
> 0) // Ran out of iovecs before msg_space exhausted
3372 if (bytes_to_read
== 0)
3373 ACELIB_ERROR_RETURN ((LM_ERROR
,
3374 ACE_TEXT ("ACE_WIN32_Asynch_Read_Dgram::recv:")
3375 ACE_TEXT ("Attempt to read 0 bytes\n")),
3378 // Create the Asynch_Result.
3379 ACE_WIN32_Asynch_Read_Dgram_Result
*result
= 0;
3380 ACE_NEW_RETURN (result
,
3381 ACE_WIN32_Asynch_Read_Dgram_Result (this->handler_proxy_
,
3388 this->win32_proactor_
->get_handle (),
3393 // do the scatter/gather recv
3394 // NOTE! The flags value is in/out to recvfrom() - it's changed AFTER
3395 // the call to WSARecvFrom returns and if it completes immediately, the
3396 // result object may already be deleted. Since the changed value is not
3397 // used, and not needed by result, pass a copy to avoid the race.
3398 ssize_t initiate_result
= ACE_OS::recvfrom (result
->handle (),
3401 number_of_bytes_recvd
,
3404 &(result
->addr_len_
),
3407 if (initiate_result
== SOCKET_ERROR
)
3409 // If initiate failed, check for a bad error.
3410 ACE_OS::set_errno_to_last_error ();
3413 case ERROR_IO_PENDING
:
3414 // The IO will complete proactively: the OVERLAPPED will still
3416 initiate_result
= 0;
3420 // Something else went wrong: the OVERLAPPED will not get
3425 ACELIB_DEBUG ((LM_ERROR
,
3427 ACE_TEXT ("WSARecvFrom")));
3431 initiate_result
= -1;
3438 // Immediate success: the OVERLAPPED will still get queued.
3439 // number_of_bytes_recvd contains the number of bytes recvd
3440 // addr contains the peer address
3441 // flags was updated
3443 // number_of_bytes_recvd = bytes_recvd;
3444 initiate_result
= 1;
3447 return initiate_result
;
3451 ACE_WIN32_Asynch_Read_Dgram::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
3453 const void *completion_key
,
3454 ACE_Proactor
*proactor
)
3456 return ACE_WIN32_Asynch_Operation::open (handler_proxy
,
3463 ACE_WIN32_Asynch_Read_Dgram::cancel ()
3465 return ACE_WIN32_Asynch_Operation::cancel ();
3469 ACE_WIN32_Asynch_Read_Dgram::proactor () const
3471 return ACE_WIN32_Asynch_Operation::proactor ();
3474 ACE_WIN32_Asynch_Read_Dgram::ACE_WIN32_Asynch_Read_Dgram (ACE_WIN32_Proactor
*win32_proactor
)
3475 : ACE_Asynch_Operation_Impl (),
3476 ACE_Asynch_Read_Dgram_Impl (),
3477 ACE_WIN32_Asynch_Operation (win32_proactor
)
3481 //***********************************************
3484 ACE_WIN32_Asynch_Write_Dgram_Result::bytes_to_write () const
3486 return this->bytes_to_write_
;
3490 ACE_WIN32_Asynch_Write_Dgram_Result::message_block () const
3492 return this->message_block_
;
3496 ACE_WIN32_Asynch_Write_Dgram_Result::flags () const
3498 return this->flags_
;
3502 ACE_WIN32_Asynch_Write_Dgram_Result::handle () const
3504 return this->handle_
;
3508 ACE_WIN32_Asynch_Write_Dgram_Result::bytes_transferred () const
3510 return ACE_WIN32_Asynch_Result::bytes_transferred ();
3514 ACE_WIN32_Asynch_Write_Dgram_Result::act () const
3516 return ACE_WIN32_Asynch_Result::act ();
3520 ACE_WIN32_Asynch_Write_Dgram_Result::success () const
3522 return ACE_WIN32_Asynch_Result::success ();
3526 ACE_WIN32_Asynch_Write_Dgram_Result::completion_key () const
3528 return ACE_WIN32_Asynch_Result::completion_key ();
3532 ACE_WIN32_Asynch_Write_Dgram_Result::error () const
3534 return ACE_WIN32_Asynch_Result::error ();
3538 ACE_WIN32_Asynch_Write_Dgram_Result::event () const
3540 return ACE_WIN32_Asynch_Result::event ();
3544 ACE_WIN32_Asynch_Write_Dgram_Result::offset () const
3546 return ACE_WIN32_Asynch_Result::offset ();
3550 ACE_WIN32_Asynch_Write_Dgram_Result::offset_high () const
3552 return ACE_WIN32_Asynch_Result::offset_high ();
3556 ACE_WIN32_Asynch_Write_Dgram_Result::priority () const
3558 return ACE_WIN32_Asynch_Result::priority ();
3562 ACE_WIN32_Asynch_Write_Dgram_Result::signal_number () const
3564 return ACE_WIN32_Asynch_Result::signal_number ();
3568 ACE_WIN32_Asynch_Write_Dgram_Result::post_completion (ACE_Proactor_Impl
*proactor
)
3570 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
3573 ACE_WIN32_Asynch_Write_Dgram_Result::ACE_WIN32_Asynch_Write_Dgram_Result (
3574 const ACE_Handler::Proxy_Ptr
&handler_proxy
,
3576 ACE_Message_Block
*message_block
,
3577 size_t bytes_to_write
,
3583 : ACE_Asynch_Result_Impl (),
3584 ACE_Asynch_Write_Dgram_Result_Impl(),
3585 ACE_WIN32_Asynch_Result (handler_proxy
,
3592 bytes_to_write_ (bytes_to_write
),
3593 message_block_ (message_block
),
3600 ACE_WIN32_Asynch_Write_Dgram_Result::complete (size_t bytes_transferred
,
3602 const void *completion_key
,
3605 // Copy the data which was returned by GetQueuedCompletionStatus
3606 this->bytes_transferred_
= bytes_transferred
;
3607 this->success_
= success
;
3608 this->completion_key_
= completion_key
;
3609 this->error_
= error
;
3611 // Appropriately move the pointers in the message block.
3612 for (ACE_Message_Block
* mb
= this->message_block_
;
3613 (mb
!= 0) && (bytes_transferred
> 0);
3616 size_t len_part
= mb
->length ();
3618 if ( len_part
> bytes_transferred
)
3619 len_part
= bytes_transferred
;
3621 mb
->rd_ptr (len_part
);
3623 bytes_transferred
-= len_part
;
3626 // Create the interface result class.
3627 ACE_Asynch_Write_Dgram::Result
result (this);
3629 // Call the application handler.
3630 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
3632 handler
->handle_write_dgram (result
);
3635 ACE_WIN32_Asynch_Write_Dgram_Result::~ACE_WIN32_Asynch_Write_Dgram_Result ()
3640 //***********************************************
3642 ACE_WIN32_Asynch_Write_Dgram::~ACE_WIN32_Asynch_Write_Dgram ()
3647 ACE_WIN32_Asynch_Write_Dgram::send (ACE_Message_Block
*message_block
,
3648 size_t &number_of_bytes_sent
,
3650 const ACE_Addr
&addr
,
3655 number_of_bytes_sent
= 0;
3657 size_t bytes_to_write
= 0;
3659 iovec iov
[ACE_IOV_MAX
];
3662 for (const ACE_Message_Block
* msg
= message_block
;
3663 msg
!= 0 && iovcnt
< ACE_IOV_MAX
;
3664 msg
= msg
->cont () , ++iovcnt
)
3666 size_t msg_len
= msg
->length ();
3668 bytes_to_write
+= msg_len
;
3670 // Make as many iovec as needed to fit all of msg_len.
3671 size_t rd_ptr_offset
= 0;
3675 //if (msg_len >= 0 && iovcnt < ACE_IOV_MAX)
3676 // msg_len >= 0 is always true since msg_len is unsigned
3677 if (iovcnt
< ACE_IOV_MAX
)
3679 u_long this_chunk_length
;
3680 if (msg_len
> ULONG_MAX
)
3681 this_chunk_length
= ULONG_MAX
;
3683 this_chunk_length
= static_cast<u_long
> (msg_len
);
3685 // Collect the data in the iovec.
3686 iov
[iovcnt
].iov_base
= msg
->rd_ptr () + rd_ptr_offset
;
3687 iov
[iovcnt
].iov_len
= this_chunk_length
;
3688 msg_len
-= this_chunk_length
;
3689 rd_ptr_offset
+= this_chunk_length
;
3691 // Increment iovec counter if there's more to do.
3696 while (msg_len
> 0 && iovcnt
< ACE_IOV_MAX
);
3698 if (msg_len
> 0) // Ran out of iovecs before msg_space exhausted
3705 // Create the Asynch_Result.
3706 ACE_WIN32_Asynch_Write_Dgram_Result
*result
= 0;
3707 ACE_NEW_RETURN (result
,
3708 ACE_WIN32_Asynch_Write_Dgram_Result (this->handler_proxy_
,
3714 this->win32_proactor_
->get_handle (),
3719 // do the scatter/gather send
3721 ssize_t initiate_result
= ACE_OS::sendto (result
->handle (),
3724 number_of_bytes_sent
,
3726 (sockaddr
*) addr
.get_addr (),
3732 if (initiate_result
== SOCKET_ERROR
)
3734 // If initiate failed, check for a bad error.
3735 ACE_OS::set_errno_to_last_error ();
3738 case ERROR_IO_PENDING
:
3739 // The IO will complete proactively: the OVERLAPPED will still
3741 initiate_result
= 0;
3745 // Something else went wrong: the OVERLAPPED will not get
3750 ACELIB_DEBUG ((LM_ERROR
,
3752 ACE_TEXT ("WSASendTo")));
3756 initiate_result
= -1;
3763 // Immediate success: the OVERLAPPED will still get queued.
3764 // number_of_bytes_recvd contains the number of bytes recvd
3765 // addr contains the peer address
3766 // flags was updated
3768 // number_of_bytes_sent = bytes_sent;
3769 initiate_result
= 1;
3772 return initiate_result
;
3776 ACE_WIN32_Asynch_Write_Dgram::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
3778 const void *completion_key
,
3779 ACE_Proactor
*proactor
)
3781 return ACE_WIN32_Asynch_Operation::open (handler_proxy
,
3788 ACE_WIN32_Asynch_Write_Dgram::cancel ()
3790 return ACE_WIN32_Asynch_Operation::cancel ();
3794 ACE_WIN32_Asynch_Write_Dgram::proactor () const
3796 return ACE_WIN32_Asynch_Operation::proactor ();
3799 ACE_WIN32_Asynch_Write_Dgram::ACE_WIN32_Asynch_Write_Dgram (ACE_WIN32_Proactor
*win32_proactor
)
3800 : ACE_Asynch_Operation_Impl (),
3801 ACE_Asynch_Write_Dgram_Impl (),
3802 ACE_WIN32_Asynch_Operation (win32_proactor
)
3806 ACE_END_VERSIONED_NAMESPACE_DECL
3808 #endif /* ACE_HAS_WIN32_OVERLAPPED_IO && ACE_HAS_WINSOCK2 */