1 // $Id: WIN32_Asynch_IO.cpp 82444 2008-07-28 13:33:07Z johnnyw $
3 #include "ace/WIN32_Asynch_IO.h"
7 "$Id: WIN32_Asynch_IO.cpp 82444 2008-07-28 13:33:07Z johnnyw $")
9 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) && \
10 (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 == 1))
12 #include "ace/WIN32_Proactor.h"
13 #include "ace/Proactor.h"
14 #include "ace/Message_Block.h"
15 #include "ace/Service_Config.h"
16 #include "ace/INET_Addr.h"
17 #include "ace/Task_T.h"
18 #include "ace/OS_NS_errno.h"
19 #include "ace/OS_NS_unistd.h"
20 #include "ace/OS_NS_sys_socket.h"
22 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
25 ACE_WIN32_Asynch_Result::bytes_transferred (void) const
27 return this->bytes_transferred_
;
31 ACE_WIN32_Asynch_Result::act (void) const
37 ACE_WIN32_Asynch_Result::success (void) const
39 return this->success_
;
43 ACE_WIN32_Asynch_Result::completion_key (void) const
45 return this->completion_key_
;
49 ACE_WIN32_Asynch_Result::error (void) const
55 ACE_WIN32_Asynch_Result::event (void) const
61 ACE_WIN32_Asynch_Result::offset (void) const
67 ACE_WIN32_Asynch_Result::offset_high (void) const
69 return this->OffsetHigh
;
73 ACE_WIN32_Asynch_Result::priority (void) const
75 ACE_NOTSUP_RETURN (0);
79 ACE_WIN32_Asynch_Result::signal_number (void) const
81 ACE_NOTSUP_RETURN (0);
85 ACE_WIN32_Asynch_Result::post_completion (ACE_Proactor_Impl
*proactor
)
87 // Get to the platform specific implementation.
88 ACE_WIN32_Proactor
*win32_proactor
= dynamic_cast<ACE_WIN32_Proactor
*> (proactor
);
90 if (win32_proactor
== 0)
91 ACE_ERROR_RETURN ((LM_ERROR
,
92 ACE_TEXT ("Dynamic cast to WIN32 Proactor failed\n")),
96 return win32_proactor
->post_completion (this);
100 ACE_WIN32_Asynch_Result::set_bytes_transferred (size_t nbytes
)
102 this->bytes_transferred_
= nbytes
;
106 ACE_WIN32_Asynch_Result::set_error (u_long errcode
)
108 this->error_
= errcode
;
111 ACE_WIN32_Asynch_Result::~ACE_WIN32_Asynch_Result (void)
115 ACE_WIN32_Asynch_Result::ACE_WIN32_Asynch_Result
116 (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
123 : ACE_Asynch_Result_Impl (),
125 handler_proxy_ (handler_proxy
),
127 bytes_transferred_ (0),
132 // Set the ACE_OVERLAPPED structure
134 this->InternalHigh
= 0;
135 this->Offset
= offset
;
136 this->OffsetHigh
= offset_high
;
137 this->hEvent
= event
;
139 ACE_UNUSED_ARG (priority
);
140 ACE_UNUSED_ARG (signal_number
);
144 ACE_WIN32_Asynch_Operation::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
146 const void *completion_key
,
147 ACE_Proactor
*proactor
)
149 this->proactor_
= proactor
;
150 this->handler_proxy_
= handler_proxy
;
151 this->handle_
= handle
;
153 // Grab the handle from the <handler> if <handle> is invalid
154 if (this->handle_
== ACE_INVALID_HANDLE
)
156 ACE_Handler
*handler
= handler_proxy
.get ()->handler ();
158 this->handle_
= handler
->handle ();
160 if (this->handle_
== ACE_INVALID_HANDLE
)
163 if (this->proactor_
!= 0)
164 // update implementation.
165 this->win32_proactor_
=
166 dynamic_cast <ACE_WIN32_Proactor
*>(this->proactor_
->implementation ());
168 // Register with the <proactor>.
169 return this->win32_proactor_
->register_handle (this->handle_
,
174 ACE_WIN32_Asynch_Operation::cancel (void)
176 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO)
177 // All I/O operations that are canceled will complete with the error
178 // ERROR_OPERATION_ABORTED. All completion notifications for the I/O
179 // operations will occur normally.
181 // @@ This API returns 0 on failure. So, I am returning -1 in that
182 // case. Is that right? (Alex).
183 int const result
= (int) ::CancelIo (this->handle_
);
186 // Couldn't cancel the operations.
189 // result is non-zero. All the operations are cancelled then.
192 #else /* !ACE_HAS_WIN32_OVERLAPPED_IO */
193 ACE_NOTSUP_RETURN (-1);
194 #endif /* ACE_HAS_AIO_CALLS */
198 ACE_WIN32_Asynch_Operation::proactor (void) const
200 return this->proactor_
;
203 ACE_WIN32_Asynch_Operation::ACE_WIN32_Asynch_Operation (ACE_WIN32_Proactor
*win32_proactor
)
204 : ACE_Asynch_Operation_Impl (),
205 win32_proactor_ (win32_proactor
),
207 handle_ (ACE_INVALID_HANDLE
)
211 ACE_WIN32_Asynch_Operation::~ACE_WIN32_Asynch_Operation (void)
215 // ************************************************************
218 ACE_WIN32_Asynch_Read_Stream_Result::bytes_to_read (void) const
220 return this->bytes_to_read_
;
224 ACE_WIN32_Asynch_Read_Stream_Result::message_block (void) const
226 return this->message_block_
;
230 ACE_WIN32_Asynch_Read_Stream_Result::handle (void) const
232 return this->handle_
;
235 ACE_WIN32_Asynch_Read_Stream_Result::ACE_WIN32_Asynch_Read_Stream_Result (
236 const ACE_Handler::Proxy_Ptr
&handler_proxy
,
238 ACE_Message_Block
&message_block
,
239 size_t bytes_to_read
,
245 : ACE_Asynch_Result_Impl (),
246 ACE_Asynch_Read_Stream_Result_Impl (),
247 ACE_WIN32_Asynch_Result (handler_proxy
,
254 bytes_to_read_ (bytes_to_read
),
255 message_block_ (message_block
),
257 scatter_enabled_ (scatter_enabled
)
262 ACE_WIN32_Asynch_Read_Stream_Result::complete (size_t bytes_transferred
,
264 const void *completion_key
,
267 // Copy the data which was returned by GetQueuedCompletionStatus
268 this->bytes_transferred_
= bytes_transferred
;
269 this->success_
= success
;
270 this->completion_key_
= completion_key
;
271 this->error_
= error
;
273 // Appropriately move the pointers in the message block.
274 if (!this->scatter_enabled ())
275 this->message_block_
.wr_ptr (bytes_transferred
);
278 for (ACE_Message_Block
* mb
= &this->message_block_
;
279 (mb
!= 0) && (bytes_transferred
> 0);
282 size_t len_part
= mb
->space ();
284 if (len_part
> bytes_transferred
)
285 len_part
= bytes_transferred
;
287 mb
->wr_ptr (len_part
);
289 bytes_transferred
-= len_part
;
293 // Create the interface result class.
294 ACE_Asynch_Read_Stream::Result
result (this);
296 // Call the application handler.
297 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
299 handler
->handle_read_stream (result
);
302 ACE_WIN32_Asynch_Read_Stream_Result::~ACE_WIN32_Asynch_Read_Stream_Result (void)
306 // Base class operations. These operations are here to kill dominance
307 // warnings. These methods call the base class methods.
310 ACE_WIN32_Asynch_Read_Stream_Result::bytes_transferred (void) const
312 return ACE_WIN32_Asynch_Result::bytes_transferred ();
316 ACE_WIN32_Asynch_Read_Stream_Result::act (void) const
318 return ACE_WIN32_Asynch_Result::act ();
322 ACE_WIN32_Asynch_Read_Stream_Result::success (void) const
324 return ACE_WIN32_Asynch_Result::success ();
328 ACE_WIN32_Asynch_Read_Stream_Result::completion_key (void) const
330 return ACE_WIN32_Asynch_Result::completion_key ();
334 ACE_WIN32_Asynch_Read_Stream_Result::error (void) const
336 return ACE_WIN32_Asynch_Result::error ();
340 ACE_WIN32_Asynch_Read_Stream_Result::event (void) const
342 return ACE_WIN32_Asynch_Result::event ();
346 ACE_WIN32_Asynch_Read_Stream_Result::offset (void) const
348 return ACE_WIN32_Asynch_Result::offset ();
352 ACE_WIN32_Asynch_Read_Stream_Result::offset_high (void) const
354 return ACE_WIN32_Asynch_Result::offset_high ();
358 ACE_WIN32_Asynch_Read_Stream_Result::priority (void) const
360 return ACE_WIN32_Asynch_Result::priority ();
364 ACE_WIN32_Asynch_Read_Stream_Result::signal_number (void) const
366 return ACE_WIN32_Asynch_Result::signal_number ();
370 ACE_WIN32_Asynch_Read_Stream_Result::post_completion (ACE_Proactor_Impl
*proactor
)
372 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
376 ACE_WIN32_Asynch_Read_Stream_Result::scatter_enabled (void) const
378 return this->scatter_enabled_
;
381 ACE_WIN32_Asynch_Read_Stream::ACE_WIN32_Asynch_Read_Stream (ACE_WIN32_Proactor
*win32_proactor
)
382 : ACE_Asynch_Operation_Impl (),
383 ACE_Asynch_Read_Stream_Impl (),
384 ACE_WIN32_Asynch_Operation (win32_proactor
)
389 ACE_WIN32_Asynch_Read_Stream::read (ACE_Message_Block
&message_block
,
390 size_t bytes_to_read
,
395 size_t space
= message_block
.space ();
396 if (bytes_to_read
> space
)
397 bytes_to_read
= space
;
399 if (bytes_to_read
== 0)
405 // Create the Asynch_Result.
406 ACE_WIN32_Asynch_Read_Stream_Result
*result
= 0;
407 ACE_NEW_RETURN (result
,
408 ACE_WIN32_Asynch_Read_Stream_Result (this->handler_proxy_
,
413 this->win32_proactor_
->get_handle (),
419 int const return_val
= this->shared_read (result
);
422 if (return_val
== -1)
429 ACE_WIN32_Asynch_Read_Stream::readv (ACE_Message_Block
&message_block
,
430 size_t bytes_to_read
,
435 #if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
436 iovec iov
[ACE_IOV_MAX
];
439 // We should not read more than user requested,
440 // but it is allowed to read less
442 for (const ACE_Message_Block
* msg
= &message_block
;
443 msg
!= 0 && bytes_to_read
> 0 && iovcnt
< ACE_IOV_MAX
;
444 msg
= msg
->cont () , ++iovcnt
)
446 size_t msg_space
= msg
->space ();
448 // OS should correctly process zero length buffers
449 // if ( msg_space == 0 )
450 // ACE_ERROR_RETURN ((LM_ERROR,
451 // ACE_TEXT ("ACE_WIN32_Asynch_Read_Stream::readv:")
452 // ACE_TEXT ("No space in the message block\n")),
455 if (msg_space
> bytes_to_read
)
456 msg_space
= bytes_to_read
;
457 bytes_to_read
-= msg_space
;
459 // Make as many iovec as needed to fit all of msg_space.
460 size_t wr_ptr_offset
= 0;
462 while (msg_space
> 0 && iovcnt
< ACE_IOV_MAX
)
464 u_long this_chunk_length
;
465 if (msg_space
> ULONG_MAX
)
466 this_chunk_length
= ULONG_MAX
;
468 this_chunk_length
= static_cast<u_long
> (msg_space
);
469 // Collect the data in the iovec.
470 iov
[iovcnt
].iov_base
= msg
->wr_ptr () + wr_ptr_offset
;
471 iov
[iovcnt
].iov_len
= this_chunk_length
;
472 msg_space
-= this_chunk_length
;
473 wr_ptr_offset
+= this_chunk_length
;
475 // Increment iovec counter if there's more to do.
479 if (msg_space
> 0) // Ran out of iovecs before msg_space exhausted
486 // Re-calculate number bytes to read
489 for (int i
= 0; i
< iovcnt
; ++i
)
490 bytes_to_read
+= iov
[i
].iov_len
;
492 if (bytes_to_read
== 0)
493 ACE_ERROR_RETURN ((LM_ERROR
,
494 ACE_TEXT ("ACE_WIN32_Asynch_Read_Stream::readv:")
495 ACE_TEXT ("Attempt to read 0 bytes\n")),
498 // Create the Asynch_Result.
499 ACE_WIN32_Asynch_Read_Stream_Result
*result
= 0;
500 ACE_NEW_RETURN (result
,
501 ACE_WIN32_Asynch_Read_Stream_Result (this->handler_proxy_
,
506 this->win32_proactor_
->get_handle (),
509 1), // scatter read enabled
512 // do the scatter recv
514 result
->set_error (0); // Clear error before starting IO.
516 DWORD bytes_recvd
= 0;
519 int initiate_result
= ::WSARecv (reinterpret_cast<SOCKET
> (result
->handle ()),
520 reinterpret_cast<WSABUF
*> (iov
),
527 if (0 == initiate_result
)
528 // Immediate success: the OVERLAPPED will still get queued.
531 ACE_ASSERT (initiate_result
== SOCKET_ERROR
);
533 // If initiate failed, check for a bad error.
534 ACE_OS::set_errno_to_last_error ();
537 case ERROR_IO_PENDING
:
538 // The IO will complete proactively: the OVERLAPPED will still
544 // Something else went wrong: the OVERLAPPED will not get
549 ACE_DEBUG ((LM_ERROR
,
551 ACE_TEXT ("WSARecv")));
555 initiate_result
= -1;
559 return initiate_result
;
561 ACE_UNUSED_ARG (message_block
);
562 ACE_UNUSED_ARG (bytes_to_read
);
563 ACE_UNUSED_ARG (act
);
564 ACE_UNUSED_ARG (priority
);
565 ACE_UNUSED_ARG (signal_number
);
566 ACE_NOTSUP_RETURN (-1);
567 #endif /* ACE_HAS_WINSOCK2 && ACE_HAS_WINSOCK2 != 0 */
570 ACE_WIN32_Asynch_Read_Stream::~ACE_WIN32_Asynch_Read_Stream (void)
575 ACE_WIN32_Asynch_Read_Stream::shared_read (ACE_WIN32_Asynch_Read_Stream_Result
*result
)
577 // ReadFile API limits us to DWORD range.
578 if (result
->bytes_to_read () > MAXDWORD
)
583 DWORD bytes_to_read
= static_cast<DWORD
> (result
->bytes_to_read ());
586 result
->set_error (0); // Clear error before starting IO.
589 int initiate_result
= ::ReadFile (result
->handle (),
590 result
->message_block ().wr_ptr (),
594 if (initiate_result
== 1)
595 // Immediate success: the OVERLAPPED will still get queued.
598 // If initiate failed, check for a bad error.
599 ACE_OS::set_errno_to_last_error ();
602 case ERROR_IO_PENDING
:
604 case ERROR_MORE_DATA
:
605 // The IO will complete proactively: the OVERLAPPED will still
610 // Something else went wrong: the OVERLAPPED will not get
615 ACE_DEBUG ((LM_ERROR
,
617 ACE_TEXT ("ReadFile")));
624 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
625 // methods are defined here to avoid VC++ warnings. They route the
626 // call to the ACE_WIN32_Asynch_Operation base class.
629 ACE_WIN32_Asynch_Read_Stream::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
631 const void *completion_key
,
632 ACE_Proactor
*proactor
)
634 return ACE_WIN32_Asynch_Operation::open (handler_proxy
,
641 ACE_WIN32_Asynch_Read_Stream::cancel (void)
643 return ACE_WIN32_Asynch_Operation::cancel ();
647 ACE_WIN32_Asynch_Read_Stream::proactor (void) const
649 return ACE_WIN32_Asynch_Operation::proactor ();
653 ACE_WIN32_Asynch_Write_Stream_Result::bytes_to_write (void) const
655 return this->bytes_to_write_
;
659 ACE_WIN32_Asynch_Write_Stream_Result::message_block (void) const
661 return this->message_block_
;
665 ACE_WIN32_Asynch_Write_Stream_Result::handle (void) const
667 return this->handle_
;
670 ACE_WIN32_Asynch_Write_Stream_Result::ACE_WIN32_Asynch_Write_Stream_Result (
671 const ACE_Handler::Proxy_Ptr
&handler_proxy
,
673 ACE_Message_Block
&message_block
,
674 size_t bytes_to_write
,
680 : ACE_Asynch_Result_Impl (),
681 ACE_Asynch_Write_Stream_Result_Impl (),
682 ACE_WIN32_Asynch_Result
683 (handler_proxy
, act
, event
, 0, 0, priority
, signal_number
),
684 bytes_to_write_ (bytes_to_write
),
685 message_block_ (message_block
),
687 gather_enabled_ (gather_enabled
)
692 ACE_WIN32_Asynch_Write_Stream_Result::complete (size_t bytes_transferred
,
694 const void *completion_key
,
697 // Copy the data which was returned by <GetQueuedCompletionStatus>.
698 this->bytes_transferred_
= bytes_transferred
;
699 this->success_
= success
;
700 this->completion_key_
= completion_key
;
701 this->error_
= error
;
703 // Appropriately move the pointers in the message block.
704 if (!this->gather_enabled ())
705 this->message_block_
.rd_ptr (bytes_transferred
);
708 for (ACE_Message_Block
* mb
= &this->message_block_
;
709 (mb
!= 0) && (bytes_transferred
> 0);
712 size_t len_part
= mb
->length ();
714 if ( len_part
> bytes_transferred
)
715 len_part
= bytes_transferred
;
717 mb
->rd_ptr (len_part
);
719 bytes_transferred
-= len_part
;
723 // Create the interface result class.
724 ACE_Asynch_Write_Stream::Result
result (this);
726 // Call the application handler.
727 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
729 handler
->handle_write_stream (result
);
732 ACE_WIN32_Asynch_Write_Stream_Result::~ACE_WIN32_Asynch_Write_Stream_Result (void)
736 // Base class operations. These operations are here to kill dominance
737 // warnings. These methods call the base class methods.
740 ACE_WIN32_Asynch_Write_Stream_Result::bytes_transferred (void) const
742 return ACE_WIN32_Asynch_Result::bytes_transferred ();
746 ACE_WIN32_Asynch_Write_Stream_Result::act (void) const
748 return ACE_WIN32_Asynch_Result::act ();
752 ACE_WIN32_Asynch_Write_Stream_Result::success (void) const
754 return ACE_WIN32_Asynch_Result::success ();
758 ACE_WIN32_Asynch_Write_Stream_Result::completion_key (void) const
760 return ACE_WIN32_Asynch_Result::completion_key ();
764 ACE_WIN32_Asynch_Write_Stream_Result::error (void) const
766 return ACE_WIN32_Asynch_Result::error ();
770 ACE_WIN32_Asynch_Write_Stream_Result::event (void) const
772 return ACE_WIN32_Asynch_Result::event ();
776 ACE_WIN32_Asynch_Write_Stream_Result::offset (void) const
778 return ACE_WIN32_Asynch_Result::offset ();
782 ACE_WIN32_Asynch_Write_Stream_Result::offset_high (void) const
784 return ACE_WIN32_Asynch_Result::offset_high ();
788 ACE_WIN32_Asynch_Write_Stream_Result::priority (void) const
790 return ACE_WIN32_Asynch_Result::priority ();
794 ACE_WIN32_Asynch_Write_Stream_Result::signal_number (void) const
796 return ACE_WIN32_Asynch_Result::signal_number ();
800 ACE_WIN32_Asynch_Write_Stream_Result::post_completion (ACE_Proactor_Impl
*proactor
)
802 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
806 ACE_WIN32_Asynch_Write_Stream_Result::gather_enabled (void) const
808 return this->gather_enabled_
;
811 ACE_WIN32_Asynch_Write_Stream::ACE_WIN32_Asynch_Write_Stream (ACE_WIN32_Proactor
*win32_proactor
)
812 : ACE_Asynch_Operation_Impl (),
813 ACE_Asynch_Write_Stream_Impl (),
814 ACE_WIN32_Asynch_Operation (win32_proactor
)
819 ACE_WIN32_Asynch_Write_Stream::write (ACE_Message_Block
&message_block
,
820 size_t bytes_to_write
,
825 size_t len
= message_block
.length();
827 if (bytes_to_write
> len
)
828 bytes_to_write
= len
;
830 if (bytes_to_write
== 0)
833 ACE_TEXT ("ACE_WIN32_Asynch_Write_Stream::write:")
834 ACE_TEXT ("Attempt to write 0 bytes\n")),
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 (),
850 int return_val
= this->shared_write (result
);
853 if (return_val
== -1)
860 ACE_WIN32_Asynch_Write_Stream::writev (ACE_Message_Block
&message_block
,
861 size_t bytes_to_write
,
866 #if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
867 iovec iov
[ACE_IOV_MAX
];
870 // We should not write more than user requested,
871 // but it is allowed to write less
873 for (const ACE_Message_Block
* msg
= &message_block
;
874 msg
!= 0 && bytes_to_write
> 0 && iovcnt
< ACE_IOV_MAX
;
877 size_t msg_len
= msg
->length ();
879 // Skip 0-length blocks.
882 if (msg_len
> bytes_to_write
)
883 msg_len
= bytes_to_write
;
884 bytes_to_write
-= msg_len
;
886 // Make as many iovec as needed to fit all of msg_len.
887 size_t rd_ptr_offset
= 0;
889 while (msg_len
> 0 && iovcnt
< ACE_IOV_MAX
)
891 u_long this_chunk_length
;
892 if (msg_len
> ULONG_MAX
)
893 this_chunk_length
= ULONG_MAX
;
895 this_chunk_length
= static_cast<u_long
> (msg_len
);
896 // Collect the data in the iovec.
897 iov
[iovcnt
].iov_base
= msg
->rd_ptr () + rd_ptr_offset
;
898 iov
[iovcnt
].iov_len
= this_chunk_length
;
899 msg_len
-= this_chunk_length
;
900 rd_ptr_offset
+= this_chunk_length
;
902 // Increment iovec counter if there's more to do.
906 if (msg_len
> 0) // Ran out of iovecs before msg_space exhausted
914 // Re-calculate number bytes to write
917 for ( int i
=0; i
< iovcnt
; ++i
)
918 bytes_to_write
+= iov
[i
].iov_len
;
920 if ( bytes_to_write
== 0 )
921 ACE_ERROR_RETURN ((LM_ERROR
,
922 ACE_TEXT ("ACE_WIN32_Asynch_Write_Stream::writev:")
923 ACE_TEXT ("Attempt to write 0 bytes\n")),
927 ACE_WIN32_Asynch_Write_Stream_Result
*result
= 0;
928 ACE_NEW_RETURN (result
,
929 ACE_WIN32_Asynch_Write_Stream_Result (this->handler_proxy_
,
934 this->win32_proactor_
->get_handle (),
937 1), // gather write enabled
940 // do the gather send
942 u_long bytes_sent
= 0;
944 int initiate_result
= ::WSASend (reinterpret_cast<SOCKET
> (result
->handle ()),
945 reinterpret_cast<WSABUF
*> (iov
),
952 if (0 == initiate_result
)
953 // Immediate success: the OVERLAPPED will still get queued.
956 ACE_ASSERT (initiate_result
== SOCKET_ERROR
);
958 // If initiate failed, check for a bad error.
959 ACE_OS::set_errno_to_last_error ();
962 case ERROR_IO_PENDING
:
963 // The IO will complete proactively: the OVERLAPPED will still
969 // Something else went wrong: the OVERLAPPED will not get
974 ACE_DEBUG ((LM_ERROR
,
976 ACE_TEXT ("WSASend")));
980 initiate_result
= -1;
984 return initiate_result
;
986 ACE_UNUSED_ARG (message_block
);
987 ACE_UNUSED_ARG (bytes_to_write
);
988 ACE_UNUSED_ARG (act
);
989 ACE_UNUSED_ARG (priority
);
990 ACE_UNUSED_ARG (signal_number
);
991 ACE_NOTSUP_RETURN (-1);
992 #endif /* ACE_HAS_WINSOCK2 && ACE_HAS_WINSOCK2 != 0 */
995 ACE_WIN32_Asynch_Write_Stream::~ACE_WIN32_Asynch_Write_Stream (void)
1000 ACE_WIN32_Asynch_Write_Stream::shared_write (ACE_WIN32_Asynch_Write_Stream_Result
*result
)
1002 u_long bytes_written
;
1003 if (result
->bytes_to_write () > MAXDWORD
)
1008 DWORD bytes_to_write
= static_cast<DWORD
> (result
->bytes_to_write ());
1010 result
->set_error (0); // Clear error before starting IO.
1012 // Initiate the write; Winsock 2 is required for the higher-performing
1013 // WSASend() function. For Winsock 1, fall back to the slower WriteFile().
1014 int initiate_result
= 0;
1015 #if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
1017 iov
.buf
= result
->message_block ().rd_ptr ();
1018 iov
.len
= bytes_to_write
;
1019 initiate_result
= ::WSASend (reinterpret_cast<SOCKET
> (result
->handle ()),
1026 if (initiate_result
== 0)
1027 // Immediate success: the OVERLAPPED will still get queued.
1030 initiate_result
= ::WriteFile (result
->handle (),
1031 result
->message_block ().rd_ptr (),
1035 if (initiate_result
== 1)
1036 // Immediate success: the OVERLAPPED will still get queued.
1038 #endif /* ACE_HAS_WINSOCK2 */
1040 // If initiate failed, check for a bad error.
1041 ACE_OS::set_errno_to_last_error ();
1044 case ERROR_IO_PENDING
:
1045 // The IO will complete proactively: the OVERLAPPED will still
1050 // Something else went wrong: the OVERLAPPED will not get
1054 ACE_DEBUG ((LM_ERROR
,
1056 ACE_TEXT ("Initiating write")));
1061 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
1062 // methods are defined here to avoid VC++ warnings. They route the
1063 // call to the ACE_WIN32_Asynch_Operation base class.
1066 ACE_WIN32_Asynch_Write_Stream::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
1068 const void *completion_key
,
1069 ACE_Proactor
*proactor
)
1071 return ACE_WIN32_Asynch_Operation::open (handler_proxy
,
1078 ACE_WIN32_Asynch_Write_Stream::cancel (void)
1080 return ACE_WIN32_Asynch_Operation::cancel ();
1084 ACE_WIN32_Asynch_Write_Stream::proactor (void) const
1086 return ACE_WIN32_Asynch_Operation::proactor ();
1089 ACE_WIN32_Asynch_Read_File_Result::ACE_WIN32_Asynch_Read_File_Result (
1090 const ACE_Handler::Proxy_Ptr
&handler_proxy
,
1092 ACE_Message_Block
&message_block
,
1093 size_t bytes_to_read
,
1100 int scatter_enabled
)
1101 : ACE_Asynch_Result_Impl (),
1102 ACE_Asynch_Read_Stream_Result_Impl (),
1103 ACE_Asynch_Read_File_Result_Impl (),
1104 ACE_WIN32_Asynch_Read_Stream_Result (handler_proxy
,
1114 this->Offset
= offset
;
1115 this->OffsetHigh
= offset_high
;
1119 ACE_WIN32_Asynch_Read_File_Result::complete (size_t bytes_transferred
,
1121 const void *completion_key
,
1124 // Copy the data which was returned by GetQueuedCompletionStatus.
1125 this->bytes_transferred_
= bytes_transferred
;
1126 this->success_
= success
;
1127 this->completion_key_
= completion_key
;
1128 this->error_
= error
;
1130 // Appropriately move the pointers in the message block.
1131 if (!this->scatter_enabled ())
1132 this->message_block_
.wr_ptr (bytes_transferred
);
1135 static const size_t page_size
= ACE_OS::getpagesize();
1137 for (ACE_Message_Block
* mb
= &this->message_block_
;
1138 (mb
!= 0) && (bytes_transferred
> 0);
1141 // mb->space () is ought to be >= page_size.
1142 // this is verified in the readv method
1143 // ACE_ASSERT (mb->space () >= page_size);
1145 size_t len_part
= page_size
;
1147 if ( len_part
> bytes_transferred
)
1148 len_part
= bytes_transferred
;
1150 mb
->wr_ptr (len_part
);
1152 bytes_transferred
-= len_part
;
1156 // Create the interface result class.
1157 ACE_Asynch_Read_File::Result
result (this);
1159 // Call the application handler.
1160 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
1162 handler
->handle_read_file (result
);
1165 ACE_WIN32_Asynch_Read_File_Result::~ACE_WIN32_Asynch_Read_File_Result (void)
1169 // Base class operations. These operations are here to kill dominance
1170 // warnings. These methods call the base class methods.
1173 ACE_WIN32_Asynch_Read_File_Result::bytes_transferred (void) const
1175 return ACE_WIN32_Asynch_Result::bytes_transferred ();
1179 ACE_WIN32_Asynch_Read_File_Result::act (void) const
1181 return ACE_WIN32_Asynch_Result::act ();
1185 ACE_WIN32_Asynch_Read_File_Result::success (void) const
1187 return ACE_WIN32_Asynch_Result::success ();
1191 ACE_WIN32_Asynch_Read_File_Result::completion_key (void) const
1193 return ACE_WIN32_Asynch_Result::completion_key ();
1197 ACE_WIN32_Asynch_Read_File_Result::error (void) const
1199 return ACE_WIN32_Asynch_Result::error ();
1203 ACE_WIN32_Asynch_Read_File_Result::event (void) const
1205 return ACE_WIN32_Asynch_Result::event ();
1209 ACE_WIN32_Asynch_Read_File_Result::offset (void) const
1211 return ACE_WIN32_Asynch_Result::offset ();
1215 ACE_WIN32_Asynch_Read_File_Result::offset_high (void) const
1217 return ACE_WIN32_Asynch_Result::offset_high ();
1221 ACE_WIN32_Asynch_Read_File_Result::priority (void) const
1223 return ACE_WIN32_Asynch_Result::priority ();
1227 ACE_WIN32_Asynch_Read_File_Result::signal_number (void) const
1229 return ACE_WIN32_Asynch_Result::signal_number ();
1232 // The following methods belong to
1233 // ACE_WIN32_Asynch_Read_Stream_Result. They are here to avoid VC++
1234 // warnings. These methods route their call to the
1235 // ACE_WIN32_Asynch_Read_Stream_Result base class.
1238 ACE_WIN32_Asynch_Read_File_Result::bytes_to_read (void) const
1240 return ACE_WIN32_Asynch_Read_Stream_Result::bytes_to_read ();
1244 ACE_WIN32_Asynch_Read_File_Result::message_block (void) const
1246 return ACE_WIN32_Asynch_Read_Stream_Result::message_block ();
1250 ACE_WIN32_Asynch_Read_File_Result::handle (void) const
1252 return ACE_WIN32_Asynch_Read_Stream_Result::handle ();
1256 ACE_WIN32_Asynch_Read_File_Result::post_completion (ACE_Proactor_Impl
*proactor
)
1258 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
1261 // ************************************************************
1263 ACE_WIN32_Asynch_Read_File::ACE_WIN32_Asynch_Read_File (ACE_WIN32_Proactor
*win32_proactor
)
1264 : ACE_Asynch_Operation_Impl (),
1265 ACE_Asynch_Read_Stream_Impl (),
1266 ACE_Asynch_Read_File_Impl (),
1267 ACE_WIN32_Asynch_Read_Stream (win32_proactor
)
1272 ACE_WIN32_Asynch_Read_File::read (ACE_Message_Block
&message_block
,
1273 size_t bytes_to_read
,
1280 size_t space
= message_block
.space ();
1281 if ( bytes_to_read
> space
)
1282 bytes_to_read
= space
;
1284 if ( bytes_to_read
== 0 )
1287 ACE_TEXT ("ACE_WIN32_Asynch_Read_File::read:")
1288 ACE_TEXT ("Attempt to read 0 bytes or no space in the message block\n")),
1292 ACE_WIN32_Asynch_Read_File_Result
*result
= 0;
1293 ACE_NEW_RETURN (result
,
1294 ACE_WIN32_Asynch_Read_File_Result (this->handler_proxy_
,
1301 this->win32_proactor_
->get_handle (),
1307 int return_val
= this->shared_read (result
);
1310 if (return_val
== -1)
1317 ACE_WIN32_Asynch_Read_File::readv (ACE_Message_Block
&message_block
,
1318 size_t bytes_to_read
,
1325 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO)
1326 static const size_t page_size
= ACE_OS::getpagesize();
1328 FILE_SEGMENT_ELEMENT buffer_pointers
[ACE_IOV_MAX
+ 1];
1329 int buffer_pointers_count
= 0;
1331 // Each buffer must be at least the size of a system memory page
1332 // and must be aligned on a system memory page size boundary
1334 // We should not read more than user requested,
1335 // but it is allowed to read less
1337 size_t total_space
= 0;
1339 for (const ACE_Message_Block
* msg
= &message_block
;
1340 msg
!= 0 && buffer_pointers_count
< ACE_IOV_MAX
&& total_space
< bytes_to_read
;
1341 msg
= msg
->cont(), ++buffer_pointers_count
)
1343 size_t msg_space
= msg
->space ();
1345 if (msg_space
< page_size
)
1346 ACE_ERROR_RETURN ((LM_ERROR
,
1347 ACE_TEXT ("ACE_WIN32_Asynch_Read_File::readv:")
1348 ACE_TEXT ("Invalid message block size\n")),
1351 buffer_pointers
[buffer_pointers_count
].Buffer
= msg
->wr_ptr ();
1352 total_space
+= page_size
;
1355 // not read more than buffers space
1356 if (bytes_to_read
> total_space
)
1357 bytes_to_read
= total_space
;
1359 // ReadFileScatter API limits us to DWORD range.
1360 if (bytes_to_read
> MAXDWORD
)
1365 DWORD dword_bytes_to_read
= static_cast<DWORD
> (bytes_to_read
);
1367 // last one should be completely 0
1368 buffer_pointers
[buffer_pointers_count
].Buffer
= 0;
1370 ACE_WIN32_Asynch_Read_File_Result
*result
= 0;
1371 ACE_NEW_RETURN (result
,
1372 ACE_WIN32_Asynch_Read_File_Result (this->handler_proxy_
,
1379 this->win32_proactor_
->get_handle (),
1382 1), // scatter read enabled
1385 // do the scatter read
1386 result
->set_error (0); // Clear error before starting IO.
1388 int initiate_result
= ::ReadFileScatter (result
->handle (),
1390 dword_bytes_to_read
,
1391 0, // reserved, must be NULL
1394 if (0 != initiate_result
)
1395 // Immediate success: the OVERLAPPED will still get queued.
1398 // If initiate failed, check for a bad error.
1399 ACE_OS::set_errno_to_last_error ();
1402 case ERROR_IO_PENDING
:
1403 // The IO will complete proactively: the OVERLAPPED will still
1405 initiate_result
= 0;
1409 // Something else went wrong: the OVERLAPPED will not get
1414 ACE_DEBUG ((LM_ERROR
,
1416 ACE_TEXT ("ReadFileScatter")));
1420 initiate_result
= -1;
1424 return initiate_result
;
1426 ACE_NOTSUP_RETURN (-1);
1427 #endif /* ACE_WIN32_OVERLAPPED_IO */
1431 ACE_WIN32_Asynch_Read_File::~ACE_WIN32_Asynch_Read_File (void)
1436 ACE_WIN32_Asynch_Read_File::read (ACE_Message_Block
&message_block
,
1437 size_t bytes_to_read
,
1442 return ACE_WIN32_Asynch_Read_Stream::read (message_block
,
1450 ACE_WIN32_Asynch_Read_File::readv (ACE_Message_Block
&message_block
,
1451 size_t bytes_to_read
,
1456 return ACE_WIN32_Asynch_Read_Stream::readv (message_block
,
1463 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
1464 // methods are defined here to avoid VC++ warnings. They route the
1465 // call to the ACE_WIN32_Asynch_Operation base class.
1468 ACE_WIN32_Asynch_Read_File::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
1470 const void *completion_key
,
1471 ACE_Proactor
*proactor
)
1473 return ACE_WIN32_Asynch_Operation::open (handler_proxy
,
1480 ACE_WIN32_Asynch_Read_File::cancel (void)
1482 return ACE_WIN32_Asynch_Operation::cancel ();
1486 ACE_WIN32_Asynch_Read_File::proactor (void) const
1488 return ACE_WIN32_Asynch_Operation::proactor ();
1491 ACE_WIN32_Asynch_Write_File_Result::ACE_WIN32_Asynch_Write_File_Result (
1492 const ACE_Handler::Proxy_Ptr
&handler_proxy
,
1494 ACE_Message_Block
&message_block
,
1495 size_t bytes_to_write
,
1503 : ACE_Asynch_Result_Impl (),
1504 ACE_Asynch_Write_Stream_Result_Impl (),
1505 ACE_Asynch_Write_File_Result_Impl (),
1506 ACE_WIN32_Asynch_Write_Stream_Result (handler_proxy
,
1516 this->Offset
= offset
;
1517 this->OffsetHigh
= offset_high
;
1521 ACE_WIN32_Asynch_Write_File_Result::complete (size_t bytes_transferred
,
1523 const void *completion_key
,
1526 // Copy the data which was returned by GetQueuedCompletionStatus
1527 this->bytes_transferred_
= bytes_transferred
;
1528 this->success_
= success
;
1529 this->completion_key_
= completion_key
;
1530 this->error_
= error
;
1532 // Appropriately move the pointers in the message block.
1533 if (!this->gather_enabled ())
1534 this->message_block_
.rd_ptr (bytes_transferred
);
1537 static const size_t page_size
= ACE_OS::getpagesize();
1539 for (ACE_Message_Block
* mb
= &this->message_block_
;
1540 (mb
!= 0) && (bytes_transferred
> 0);
1543 // mb->length () is ought to be >= page_size.
1544 // this is verified in the writev method
1545 // ACE_ASSERT (mb->length () >= page_size);
1547 size_t len_part
= page_size
;
1549 if ( len_part
> bytes_transferred
)
1550 len_part
= bytes_transferred
;
1552 mb
->rd_ptr (len_part
);
1554 bytes_transferred
-= len_part
;
1559 // Create the interface result class.
1560 ACE_Asynch_Write_File::Result
result (this);
1562 // Call the application handler.
1563 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
1565 handler
->handle_write_file (result
);
1568 ACE_WIN32_Asynch_Write_File_Result::~ACE_WIN32_Asynch_Write_File_Result (void)
1572 // Base class operations. These operations are here to kill dominance
1573 // warnings. These methods call the base class methods.
1576 ACE_WIN32_Asynch_Write_File_Result::bytes_transferred (void) const
1578 return ACE_WIN32_Asynch_Result::bytes_transferred ();
1582 ACE_WIN32_Asynch_Write_File_Result::act (void) const
1584 return ACE_WIN32_Asynch_Result::act ();
1588 ACE_WIN32_Asynch_Write_File_Result::success (void) const
1590 return ACE_WIN32_Asynch_Result::success ();
1594 ACE_WIN32_Asynch_Write_File_Result::completion_key (void) const
1596 return ACE_WIN32_Asynch_Result::completion_key ();
1600 ACE_WIN32_Asynch_Write_File_Result::error (void) const
1602 return ACE_WIN32_Asynch_Result::error ();
1606 ACE_WIN32_Asynch_Write_File_Result::event (void) const
1608 return ACE_WIN32_Asynch_Result::event ();
1612 ACE_WIN32_Asynch_Write_File_Result::offset (void) const
1614 return ACE_WIN32_Asynch_Result::offset ();
1618 ACE_WIN32_Asynch_Write_File_Result::offset_high (void) const
1620 return ACE_WIN32_Asynch_Result::offset_high ();
1624 ACE_WIN32_Asynch_Write_File_Result::priority (void) const
1626 return ACE_WIN32_Asynch_Result::priority ();
1630 ACE_WIN32_Asynch_Write_File_Result::signal_number (void) const
1632 return ACE_WIN32_Asynch_Result::signal_number ();
1635 // The following methods belong to
1636 // ACE_WIN32_Asynch_Write_Stream_Result. They are here to avoid VC++
1637 // warnings. These methods route their call to the
1638 // ACE_WIN32_Asynch_Write_Stream_Result base class.
1641 ACE_WIN32_Asynch_Write_File_Result::bytes_to_write (void) const
1643 return ACE_WIN32_Asynch_Write_Stream_Result::bytes_to_write ();
1647 ACE_WIN32_Asynch_Write_File_Result::message_block (void) const
1649 return ACE_WIN32_Asynch_Write_Stream_Result::message_block ();
1653 ACE_WIN32_Asynch_Write_File_Result::handle (void) const
1655 return ACE_WIN32_Asynch_Write_Stream_Result::handle ();
1659 ACE_WIN32_Asynch_Write_File_Result::post_completion (ACE_Proactor_Impl
*proactor
)
1661 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
1664 ACE_WIN32_Asynch_Write_File::ACE_WIN32_Asynch_Write_File (ACE_WIN32_Proactor
*win32_proactor
)
1665 : ACE_Asynch_Operation_Impl (),
1666 ACE_Asynch_Write_Stream_Impl (),
1667 ACE_Asynch_Write_File_Impl (),
1668 ACE_WIN32_Asynch_Write_Stream (win32_proactor
)
1673 ACE_WIN32_Asynch_Write_File::write (ACE_Message_Block
&message_block
,
1674 size_t bytes_to_write
,
1681 size_t len
= message_block
.length ();
1682 if ( bytes_to_write
> len
)
1683 bytes_to_write
= len
;
1685 if ( bytes_to_write
== 0 )
1688 ACE_TEXT ("ACE_WIN32_Asynch_Write_File::write:")
1689 ACE_TEXT ("Attempt to read 0 bytes\n")),
1692 ACE_WIN32_Asynch_Write_File_Result
*result
= 0;
1693 ACE_NEW_RETURN (result
,
1694 ACE_WIN32_Asynch_Write_File_Result (this->handler_proxy_
,
1701 this->win32_proactor_
->get_handle (),
1707 int return_val
= this->shared_write (result
);
1710 if (return_val
== -1)
1717 ACE_WIN32_Asynch_Write_File::writev (ACE_Message_Block
&message_block
,
1718 size_t bytes_to_write
,
1725 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO)
1726 static const size_t page_size
= ACE_OS::getpagesize();
1728 FILE_SEGMENT_ELEMENT buffer_pointers
[ACE_IOV_MAX
+ 1];
1729 int buffer_pointers_count
= 0;
1731 // Each buffer must be at least the size of a system memory page
1732 // and must be aligned on a system memory page size boundary
1734 // We should not read more than user requested,
1735 // but it is allowed to read less
1737 size_t total_len
= 0;
1739 for (const ACE_Message_Block
* msg
= &message_block
;
1740 msg
!= 0 && buffer_pointers_count
< ACE_IOV_MAX
&& total_len
< bytes_to_write
;
1741 msg
= msg
->cont (), ++buffer_pointers_count
)
1743 size_t msg_len
= msg
->length ();
1745 // Don't allow writing less than page_size, unless
1746 // the size of the message block is big enough (so we don't write from
1747 // memory which does not belong to the message block), and the message
1748 // block is the last in the chain.
1749 if (msg_len
< page_size
&&
1750 (msg
->size () - (msg
->rd_ptr () - msg
->base ()) < page_size
|| // message block too small
1751 bytes_to_write
- total_len
> page_size
))// NOT last chunk
1752 ACE_ERROR_RETURN ((LM_ERROR
,
1753 ACE_TEXT ("ACE_WIN32_Asynch_Write_File::writev:")
1754 ACE_TEXT ("Invalid message block length\n")),
1757 buffer_pointers
[buffer_pointers_count
].Buffer
= msg
->rd_ptr ();
1758 total_len
+= page_size
;
1761 // not write more than we have in buffers
1762 if (bytes_to_write
> total_len
)
1763 bytes_to_write
= total_len
;
1764 // WriteFileGather API limits us to DWORD range.
1765 if (bytes_to_write
> MAXDWORD
)
1770 DWORD dword_bytes_to_write
= static_cast<DWORD
> (bytes_to_write
);
1772 // last one should be completely 0
1773 buffer_pointers
[buffer_pointers_count
].Buffer
= 0;
1775 ACE_WIN32_Asynch_Write_File_Result
*result
= 0;
1776 ACE_NEW_RETURN (result
,
1777 ACE_WIN32_Asynch_Write_File_Result (this->handler_proxy_
,
1784 this->win32_proactor_
->get_handle (),
1787 1), // gather write enabled
1790 result
->set_error(0);
1792 // do the gather write
1793 int initiate_result
= ::WriteFileGather (result
->handle (),
1795 dword_bytes_to_write
,
1796 0, // reserved, must be NULL
1799 if (0 != initiate_result
)
1800 // Immediate success: the OVERLAPPED will still get queued.
1803 // If initiate failed, check for a bad error.
1804 ACE_OS::set_errno_to_last_error ();
1807 case ERROR_IO_PENDING
:
1808 // The IO will complete proactively: the OVERLAPPED will still
1810 initiate_result
= 0;
1814 // Something else went wrong: the OVERLAPPED will not get
1819 ACE_DEBUG ((LM_ERROR
,
1821 ACE_TEXT ("WriteFileGather")));
1825 initiate_result
= -1;
1829 return initiate_result
;
1832 ACE_NOTSUP_RETURN (-1);
1834 #endif /* ACE_HAS_WIN32_OVERLAPPED_IO */
1838 ACE_WIN32_Asynch_Write_File::~ACE_WIN32_Asynch_Write_File (void)
1843 ACE_WIN32_Asynch_Write_File::write (ACE_Message_Block
&message_block
,
1844 size_t bytes_to_write
,
1849 return ACE_WIN32_Asynch_Write_Stream::write (message_block
,
1857 ACE_WIN32_Asynch_Write_File::writev (ACE_Message_Block
&message_block
,
1858 size_t bytes_to_write
,
1863 return ACE_WIN32_Asynch_Write_Stream::writev (message_block
,
1870 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
1871 // methods are defined here to avoid VC++ warnings. They route the
1872 // call to the ACE_WIN32_Asynch_Operation base class.
1875 ACE_WIN32_Asynch_Write_File::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
1877 const void *completion_key
,
1878 ACE_Proactor
*proactor
)
1880 return ACE_WIN32_Asynch_Operation::open (handler_proxy
,
1887 ACE_WIN32_Asynch_Write_File::cancel (void)
1889 return ACE_WIN32_Asynch_Operation::cancel ();
1893 ACE_WIN32_Asynch_Write_File::proactor (void) const
1895 return ACE_WIN32_Asynch_Operation::proactor ();
1899 ACE_WIN32_Asynch_Accept_Result::bytes_to_read (void) const
1901 return this->bytes_to_read_
;
1905 ACE_WIN32_Asynch_Accept_Result::message_block (void) const
1907 return this->message_block_
;
1911 ACE_WIN32_Asynch_Accept_Result::listen_handle (void) const
1913 return this->listen_handle_
;
1917 ACE_WIN32_Asynch_Accept_Result::accept_handle (void) const
1919 return this->accept_handle_
;
1922 ACE_WIN32_Asynch_Accept_Result::ACE_WIN32_Asynch_Accept_Result (
1923 const ACE_Handler::Proxy_Ptr
&handler_proxy
,
1924 ACE_HANDLE listen_handle
,
1925 ACE_HANDLE accept_handle
,
1926 ACE_Message_Block
&message_block
,
1927 size_t bytes_to_read
,
1932 : ACE_Asynch_Result_Impl (),
1933 ACE_Asynch_Accept_Result_Impl (),
1934 ACE_WIN32_Asynch_Result (handler_proxy
,
1941 bytes_to_read_ (bytes_to_read
),
1942 message_block_ (message_block
),
1943 listen_handle_ (listen_handle
),
1944 accept_handle_ (accept_handle
)
1949 ACE_WIN32_Asynch_Accept_Result::complete (size_t bytes_transferred
,
1951 const void *completion_key
,
1954 // Copy the data which was returned by GetQueuedCompletionStatus
1955 this->bytes_transferred_
= bytes_transferred
;
1956 this->success_
= success
;
1957 this->completion_key_
= completion_key
;
1958 this->error_
= error
;
1960 // Appropriately move the pointers in the message block.
1961 this->message_block_
.wr_ptr (bytes_transferred
);
1963 if (!success
&& this->accept_handle_
!= ACE_INVALID_HANDLE
)
1965 ACE_OS::closesocket (this->accept_handle_
);
1966 this->accept_handle_
= ACE_INVALID_HANDLE
;
1969 // Create the interface result class.
1970 ACE_Asynch_Accept::Result
result (this);
1972 // Call the application handler.
1973 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
1975 handler
->handle_accept (result
);
1978 ACE_WIN32_Asynch_Accept_Result::~ACE_WIN32_Asynch_Accept_Result (void)
1982 // Base class operations. These operations are here to kill dominance
1983 // warnings. These methods call the base class methods.
1986 ACE_WIN32_Asynch_Accept_Result::bytes_transferred (void) const
1988 return ACE_WIN32_Asynch_Result::bytes_transferred ();
1992 ACE_WIN32_Asynch_Accept_Result::act (void) const
1994 return ACE_WIN32_Asynch_Result::act ();
1998 ACE_WIN32_Asynch_Accept_Result::success (void) const
2000 return ACE_WIN32_Asynch_Result::success ();
2004 ACE_WIN32_Asynch_Accept_Result::completion_key (void) const
2006 return ACE_WIN32_Asynch_Result::completion_key ();
2010 ACE_WIN32_Asynch_Accept_Result::error (void) const
2012 return ACE_WIN32_Asynch_Result::error ();
2016 ACE_WIN32_Asynch_Accept_Result::event (void) const
2018 return ACE_WIN32_Asynch_Result::event ();
2022 ACE_WIN32_Asynch_Accept_Result::offset (void) const
2024 return ACE_WIN32_Asynch_Result::offset ();
2028 ACE_WIN32_Asynch_Accept_Result::offset_high (void) const
2030 return ACE_WIN32_Asynch_Result::offset_high ();
2034 ACE_WIN32_Asynch_Accept_Result::priority (void) const
2036 return ACE_WIN32_Asynch_Result::priority ();
2040 ACE_WIN32_Asynch_Accept_Result::signal_number (void) const
2042 return ACE_WIN32_Asynch_Result::signal_number ();
2046 ACE_WIN32_Asynch_Accept_Result::post_completion (ACE_Proactor_Impl
*proactor
)
2048 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
2051 ACE_WIN32_Asynch_Accept::ACE_WIN32_Asynch_Accept (ACE_WIN32_Proactor
*win32_proactor
)
2052 : ACE_Asynch_Operation_Impl (),
2053 ACE_Asynch_Accept_Impl (),
2054 ACE_WIN32_Asynch_Operation (win32_proactor
)
2059 ACE_WIN32_Asynch_Accept::accept (ACE_Message_Block
&message_block
,
2060 size_t bytes_to_read
,
2061 ACE_HANDLE accept_handle
,
2067 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
2068 // Sanity check: make sure that enough space has been allocated by
2070 size_t address_size
=
2071 #if defined (ACE_HAS_IPV6)
2072 addr_family
== AF_INET
? sizeof (sockaddr_in
) : sizeof (sockaddr_in6
);
2074 sizeof (sockaddr_in
);
2075 #endif /* ACE_HAS_IPV6 */
2076 address_size
+= 16; // AcceptEx requires address size + 16 (minimum)
2077 size_t available_space
= message_block
.space ();
2078 size_t space_needed
= bytes_to_read
+ 2 * address_size
;
2079 if (available_space
< space_needed
)
2080 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("Buffer too small\n")), -1);
2084 // AcceptEx API limits us to DWORD range.
2085 if (bytes_to_read
> MAXDWORD
)
2090 DWORD dword_bytes_to_read
= static_cast<DWORD
> (bytes_to_read
);
2092 int close_accept_handle
= 0;
2093 // If the <accept_handle> is invalid, we will create a new socket.
2094 if (accept_handle
== ACE_INVALID_HANDLE
)
2096 accept_handle
= ACE_OS::socket (addr_family
,
2099 if (accept_handle
== ACE_INVALID_HANDLE
)
2103 ACE_DEBUG ((LM_ERROR
,
2105 ACE_TEXT ("ACE_OS::socket")));
2110 // Remember to close the socket down if failures occur.
2111 close_accept_handle
= 1;
2114 // Common code for both WIN and POSIX.
2115 ACE_WIN32_Asynch_Accept_Result
*result
= 0;
2116 ACE_NEW_RETURN (result
,
2117 ACE_WIN32_Asynch_Accept_Result (this->handler_proxy_
,
2123 this->win32_proactor_
->get_handle (),
2130 // Initiate the accept.
2131 int initiate_result
= ::AcceptEx ((SOCKET
) result
->listen_handle (),
2132 (SOCKET
) result
->accept_handle (),
2133 result
->message_block ().wr_ptr (),
2134 dword_bytes_to_read
,
2135 static_cast<DWORD
> (address_size
),
2136 static_cast<DWORD
> (address_size
),
2139 if (initiate_result
== 1)
2140 // Immediate success: the OVERLAPPED will still get queued.
2143 // If initiate failed, check for a bad error.
2144 ACE_OS::set_errno_to_last_error ();
2147 case ERROR_IO_PENDING
:
2148 // The IO will complete proactively: the OVERLAPPED will still
2153 // Something else went wrong: the OVERLAPPED will not get
2156 if (close_accept_handle
== 1)
2157 // Close the newly created socket
2158 ACE_OS::closesocket (accept_handle
);
2160 // Cleanup dynamically allocated Asynch_Result.
2165 ACE_DEBUG ((LM_ERROR
,
2167 ACE_TEXT ("AcceptEx")));
2172 ACE_UNUSED_ARG (message_block
);
2173 ACE_UNUSED_ARG (bytes_to_read
);
2174 ACE_UNUSED_ARG (accept_handle
);
2175 ACE_UNUSED_ARG (act
);
2176 ACE_UNUSED_ARG (priority
);
2177 ACE_UNUSED_ARG (signal_number
);
2178 ACE_UNUSED_ARG (addr_family
);
2179 ACE_NOTSUP_RETURN (-1);
2180 #endif /* defined (ACE_HAS_WIN32_OVERLAPPED_IO) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)) */
2183 ACE_WIN32_Asynch_Accept::~ACE_WIN32_Asynch_Accept (void)
2187 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
2188 // methods are defined here to avoid VC++ warnings. They route the
2189 // call to the ACE_WIN32_Asynch_Operation base class.
2192 ACE_WIN32_Asynch_Accept::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
2194 const void *completion_key
,
2195 ACE_Proactor
*proactor
)
2197 return ACE_WIN32_Asynch_Operation::open (handler_proxy
,
2204 ACE_WIN32_Asynch_Accept::cancel (void)
2206 return ACE_WIN32_Asynch_Operation::cancel ();
2210 ACE_WIN32_Asynch_Accept::proactor (void) const
2212 return ACE_WIN32_Asynch_Operation::proactor ();
2215 // *********************************************************************
2218 ACE_WIN32_Asynch_Connect_Result::connect_handle (void) const
2220 return this->connect_handle_
;
2223 void ACE_WIN32_Asynch_Connect_Result::connect_handle ( ACE_HANDLE handle
)
2225 this->connect_handle_
= handle
;
2229 ACE_WIN32_Asynch_Connect_Result::ACE_WIN32_Asynch_Connect_Result
2230 (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
2231 ACE_HANDLE connect_handle
,
2236 : ACE_Asynch_Result_Impl (),
2237 ACE_Asynch_Connect_Result_Impl (),
2238 ACE_WIN32_Asynch_Result
2239 (handler_proxy
, act
, event
, 0, 0, priority
, signal_number
),
2240 connect_handle_ (connect_handle
)
2246 ACE_WIN32_Asynch_Connect_Result::complete (size_t bytes_transferred
,
2248 const void *completion_key
,
2252 this->bytes_transferred_
= bytes_transferred
;
2253 this->success_
= success
;
2254 this->completion_key_
= completion_key
;
2255 this->error_
= error
;
2257 // Create the interface result class.
2258 ACE_Asynch_Connect::Result
result (this);
2260 // Call the application handler.
2261 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
2263 handler
->handle_connect (result
);
2266 ACE_WIN32_Asynch_Connect_Result::~ACE_WIN32_Asynch_Connect_Result (void)
2270 // Base class operations. These operations are here to kill dominance
2271 // warnings. These methods call the base class methods.
2274 ACE_WIN32_Asynch_Connect_Result::bytes_transferred (void) const
2276 return ACE_WIN32_Asynch_Result::bytes_transferred ();
2280 ACE_WIN32_Asynch_Connect_Result::act (void) const
2282 return ACE_WIN32_Asynch_Result::act ();
2286 ACE_WIN32_Asynch_Connect_Result::success (void) const
2288 return ACE_WIN32_Asynch_Result::success ();
2292 ACE_WIN32_Asynch_Connect_Result::completion_key (void) const
2294 return ACE_WIN32_Asynch_Result::completion_key ();
2298 ACE_WIN32_Asynch_Connect_Result::error (void) const
2300 return ACE_WIN32_Asynch_Result::error ();
2304 ACE_WIN32_Asynch_Connect_Result::event (void) const
2306 return ACE_WIN32_Asynch_Result::event ();
2310 ACE_WIN32_Asynch_Connect_Result::offset (void) const
2312 return ACE_WIN32_Asynch_Result::offset ();
2316 ACE_WIN32_Asynch_Connect_Result::offset_high (void) const
2318 return ACE_WIN32_Asynch_Result::offset_high ();
2322 ACE_WIN32_Asynch_Connect_Result::priority (void) const
2324 return ACE_WIN32_Asynch_Result::priority ();
2328 ACE_WIN32_Asynch_Connect_Result::signal_number (void) const
2330 return ACE_WIN32_Asynch_Result::signal_number ();
2334 ACE_WIN32_Asynch_Connect_Result::post_completion (ACE_Proactor_Impl
*proactor
)
2336 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
2339 // *********************************************************************
2341 ACE_WIN32_Asynch_Connect::ACE_WIN32_Asynch_Connect (ACE_WIN32_Proactor
* win32_proactor
)
2342 : ACE_Asynch_Operation_Impl (),
2343 ACE_Asynch_Connect_Impl (),
2344 ACE_WIN32_Asynch_Operation (win32_proactor
),
2349 ACE_WIN32_Asynch_Connect::~ACE_WIN32_Asynch_Connect (void)
2352 this->reactor (0); // to avoid purge_pending_notifications
2356 ACE_WIN32_Asynch_Connect::proactor (void) const
2358 return ACE_WIN32_Asynch_Operation::proactor ();
2362 ACE_WIN32_Asynch_Connect::get_handle (void) const
2366 return ACE_INVALID_HANDLE
;
2370 ACE_WIN32_Asynch_Connect::set_handle (ACE_HANDLE
)
2376 ACE_WIN32_Asynch_Connect::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
2378 const void *completion_key
,
2379 ACE_Proactor
*proactor
)
2381 ACE_TRACE ("ACE_WIN32_Asynch_Connect::open");
2383 // if we are already opened,
2384 // we could not create a new handler without closing the previous
2385 if (this->flg_open_
)
2386 ACE_ERROR_RETURN ((LM_ERROR
,
2387 ACE_TEXT ("%N:%l:ACE_WIN32_Asynch_Connect::open:")
2388 ACE_TEXT ("connector already open \n")),
2392 ACE_WIN32_Asynch_Operation::open (handler_proxy
,
2397 // Ignore result as we pass ACE_INVALID_HANDLE
2401 this->flg_open_
= true;
2407 ACE_WIN32_Asynch_Connect::connect (ACE_HANDLE connect_handle
,
2408 const ACE_Addr
& remote_sap
,
2409 const ACE_Addr
& local_sap
,
2415 ACE_TRACE ("ACE_WIN32_Asynch_Connect::connect");
2417 if (!this->flg_open_
)
2418 ACE_ERROR_RETURN ((LM_ERROR
,
2419 ACE_TEXT ("%N:%l:ACE_WIN32_Asynch_Connect::connect")
2420 ACE_TEXT ("connector was not opened before\n")),
2423 // Common code for both WIN and WIN32.
2424 // Create future Asynch_Connect_Result
2425 ACE_WIN32_Asynch_Connect_Result
*result
= 0;
2426 ACE_NEW_RETURN (result
,
2427 ACE_WIN32_Asynch_Connect_Result (this->handler_proxy_
,
2430 this->win32_proactor_
->get_handle (),
2435 int rc
= connect_i (result
,
2441 connect_handle
= result
->connect_handle ();
2444 return post_result (result
, true);
2446 // Enqueue result we will wait for completion
2448 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->lock_
, -1));
2450 if (this->result_map_
.bind (connect_handle
, result
) == -1)
2452 ACE_ERROR ((LM_ERROR
,
2453 ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect: %p\n"),
2454 ACE_TEXT ("bind")));
2455 result
->set_error (EFAULT
);
2456 return post_result (result
, true);
2460 ACE_Asynch_Pseudo_Task
& task
=
2461 this->win32_proactor_
->get_asynch_pseudo_task ();
2463 if (-1 == task
.register_io_handler (connect_handle
,
2465 ACE_Event_Handler::CONNECT_MASK
,
2466 0)) // not to suspend after register
2470 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->lock_
, -1));
2471 this->result_map_
.unbind (connect_handle
, result
);
2475 result
->set_error (EFAULT
);
2476 this->post_result (result
, true);
2483 int ACE_WIN32_Asynch_Connect::post_result (ACE_WIN32_Asynch_Connect_Result
* result
,
2486 ACE_HANDLE handle
= result
->connect_handle ();
2487 if (this->flg_open_
&& post_enable
)
2489 // NOTE: result is invalid after post_completion(). It's either deleted
2490 // or will be shortly via the proactor dispatch, regardless of success
2491 // or fail of the call.
2492 if (this->win32_proactor_
->post_completion (result
) == 0)
2495 ACE_ERROR ((LM_ERROR
,
2496 ACE_TEXT ("Error:(%P | %t):%p\n"),
2497 ACE_TEXT ("ACE_WIN32_Asynch_Connect::post_result: ")
2498 ACE_TEXT (" <post_completion> failed")));
2502 // There was no call to post_completion() so manually delete result.
2506 if (handle
!= ACE_INVALID_HANDLE
)
2507 ACE_OS::closesocket (handle
);
2514 // -1 errors before attempt to connect
2515 // 0 connect started
2516 // 1 connect finished ( may be unsuccessfully)
2519 ACE_WIN32_Asynch_Connect::connect_i (ACE_WIN32_Asynch_Connect_Result
*result
,
2520 const ACE_Addr
& remote_sap
,
2521 const ACE_Addr
& local_sap
,
2524 result
->set_bytes_transferred (0);
2526 ACE_HANDLE handle
= result
->connect_handle ();
2527 if (handle
== ACE_INVALID_HANDLE
)
2529 int protocol_family
= remote_sap
.get_type ();
2530 handle
= ACE_OS::socket (protocol_family
,
2535 result
->connect_handle (handle
);
2536 if (handle
== ACE_INVALID_HANDLE
)
2538 result
->set_error (errno
);
2541 ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"),
2542 ACE_TEXT ("socket")),
2546 // Reuse the address
2548 if (protocol_family
!= PF_UNIX
&&
2550 ACE_OS::setsockopt (handle
,
2556 result
->set_error (errno
);
2559 ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"),
2560 ACE_TEXT ("setsockopt")),
2565 if (local_sap
!= ACE_Addr::sap_any
)
2567 sockaddr
* laddr
= reinterpret_cast<sockaddr
*> (local_sap
.get_addr ());
2568 int size
= local_sap
.get_size ();
2569 if (ACE_OS::bind (handle
, laddr
, size
) == -1)
2571 result
->set_error (errno
);
2574 ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"),
2580 // set non blocking mode
2581 if (ACE::set_flags (handle
, ACE_NONBLOCK
) != 0)
2583 result
->set_error (errno
);
2586 ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"),
2587 ACE_TEXT ("set_flags")),
2593 int rc
= ACE_OS::connect
2595 reinterpret_cast<sockaddr
*> (remote_sap
.get_addr ()),
2596 remote_sap
.get_size ());
2598 if (rc
< 0) // failure
2600 if (errno
== EWOULDBLOCK
|| errno
== EINPROGRESS
)
2601 return 0; // connect started
2606 result
->set_error (errno
);
2608 return 1 ; // connect finished
2613 // cancel_uncompleted
2614 // It performs cancellation of all pending requests
2616 // Parameter flg_notify can be
2617 // 0 - don't send notifications about canceled accepts
2618 // !0 - notify user about canceled accepts
2619 // according WIN32 standards we should receive notifications
2620 // on canceled AIO requests
2622 // Return value : number of cancelled requests
2626 ACE_WIN32_Asynch_Connect::cancel_uncompleted (bool flg_notify
,
2627 ACE_Handle_Set
&set
)
2629 ACE_TRACE ("ACE_WIN32_Asynch_Connect::cancel_uncompleted");
2633 MAP_MANAGER::ITERATOR
iter (result_map_
);
2634 MAP_MANAGER::ENTRY
* me
= 0;
2638 for (; iter
.next (me
) != 0; retval
++, iter
.advance ())
2640 ACE_HANDLE handle
= me
->ext_id_
;
2641 ACE_WIN32_Asynch_Connect_Result
* result
= me
->int_id_
;
2643 set
.set_bit (handle
);
2645 result
->set_bytes_transferred (0);
2646 result
->set_error (ERROR_OPERATION_ABORTED
);
2647 this->post_result (result
, flg_notify
);
2650 result_map_
.unbind_all ();
2656 ACE_WIN32_Asynch_Connect::cancel (void)
2658 ACE_TRACE ("ACE_WIN32_Asynch_Connect::cancel");
2660 int rc
= -1 ; // ERRORS
2663 int num_cancelled
= 0;
2665 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->lock_
, -1));
2667 num_cancelled
= cancel_uncompleted (flg_open_
, set
);
2669 if (num_cancelled
== 0)
2670 rc
= 1; // AIO_ALLDONE
2671 else if (num_cancelled
> 0)
2672 rc
= 0; // AIO_CANCELED
2674 if (!this->flg_open_
)
2677 ACE_Asynch_Pseudo_Task
& task
=
2678 this->win32_proactor_
->get_asynch_pseudo_task ();
2680 task
.remove_io_handler (set
);
2685 ACE_WIN32_Asynch_Connect::close (void)
2687 ACE_TRACE ("ACE_WIN32_Asynch_Connect::close");
2690 int num_cancelled
= 0;
2692 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->lock_
, -1));
2694 num_cancelled
= cancel_uncompleted (flg_open_
, set
);
2696 if (num_cancelled
== 0 || this->flg_open_
== 0)
2698 this->flg_open_
= false;
2702 ACE_Asynch_Pseudo_Task
& task
=
2703 this->win32_proactor_
->get_asynch_pseudo_task ();
2705 task
.remove_io_handler (set
);
2710 ACE_WIN32_Asynch_Connect::handle_exception (ACE_HANDLE fd
)
2712 ACE_TRACE ("ACE_WIN32_Asynch_Connect::handle_exception");
2713 return handle_output (fd
);
2717 ACE_WIN32_Asynch_Connect::handle_input (ACE_HANDLE fd
)
2719 ACE_TRACE ("ACE_WIN32_Asynch_Connect::handle_input");
2720 return handle_output (fd
);
2724 ACE_WIN32_Asynch_Connect::handle_output (ACE_HANDLE fd
)
2726 ACE_TRACE ("ACE_WIN32_Asynch_Connect::handle_output");
2728 ACE_WIN32_Asynch_Connect_Result
* result
= 0;
2731 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->lock_
, 0));
2732 if (this->result_map_
.unbind (fd
, result
) != 0) // not found
2737 int lsockerror
= sizeof sockerror
;
2739 ACE_OS::getsockopt (fd
,
2742 (char*) & sockerror
,
2745 // This previously just did a "return -1" and let handle_close() clean
2746 // things up. However, this entire object may be gone as a result of
2747 // the application's completion handler, so don't count on 'this' being
2748 // legitimate on return from post_result().
2749 // remove_io_handler() contains flag DONT_CALL
2750 this->win32_proactor_
->get_asynch_pseudo_task().remove_io_handler (fd
);
2752 result
->set_bytes_transferred (0);
2753 result
->set_error (sockerror
);
2754 this->post_result (result
, this->flg_open_
);
2760 ACE_WIN32_Asynch_Connect::handle_close (ACE_HANDLE fd
, ACE_Reactor_Mask
)
2762 ACE_TRACE ("ACE_WIN32_Asynch_Connect::handle_close");
2764 ACE_Asynch_Pseudo_Task
& task
=
2765 this->win32_proactor_
->get_asynch_pseudo_task ();
2766 task
.remove_io_handler (fd
);
2768 ACE_WIN32_Asynch_Connect_Result
* result
= 0;
2771 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->lock_
, 0));
2772 if (this->result_map_
.unbind (fd
, result
) != 0) // not found
2776 result
->set_bytes_transferred (0);
2777 result
->set_error (ERROR_OPERATION_ABORTED
);
2778 this->post_result (result
, this->flg_open_
);
2783 // *********************************************************************
2786 ACE_WIN32_Asynch_Transmit_File_Result::socket (void) const
2788 return this->socket_
;
2792 ACE_WIN32_Asynch_Transmit_File_Result::file (void) const
2797 ACE_Asynch_Transmit_File::Header_And_Trailer
*
2798 ACE_WIN32_Asynch_Transmit_File_Result::header_and_trailer (void) const
2800 return this->header_and_trailer_
;
2804 ACE_WIN32_Asynch_Transmit_File_Result::bytes_to_write (void) const
2806 return this->bytes_to_write_
;
2810 ACE_WIN32_Asynch_Transmit_File_Result::bytes_per_send (void) const
2812 return this->bytes_per_send_
;
2816 ACE_WIN32_Asynch_Transmit_File_Result::flags (void) const
2818 return this->flags_
;
2821 ACE_WIN32_Asynch_Transmit_File_Result::ACE_WIN32_Asynch_Transmit_File_Result (
2822 const ACE_Handler::Proxy_Ptr
&handler_proxy
,
2825 ACE_Asynch_Transmit_File::Header_And_Trailer
*header_and_trailer
,
2826 size_t bytes_to_write
,
2829 size_t bytes_per_send
,
2835 : ACE_Asynch_Result_Impl (),
2836 ACE_Asynch_Transmit_File_Result_Impl (),
2837 ACE_WIN32_Asynch_Result (handler_proxy
,
2846 header_and_trailer_ (header_and_trailer
),
2847 bytes_to_write_ (bytes_to_write
),
2848 bytes_per_send_ (bytes_per_send
),
2854 ACE_WIN32_Asynch_Transmit_File_Result::complete (size_t bytes_transferred
,
2856 const void *completion_key
,
2859 // Copy the data which was returned by GetQueuedCompletionStatus
2860 this->bytes_transferred_
= bytes_transferred
;
2861 this->success_
= success
;
2862 this->completion_key_
= completion_key
;
2863 this->error_
= error
;
2865 // We will not do this because (a) the header and trailer blocks may
2866 // be the same message_blocks and (b) in cases of failures we have
2867 // no idea how much of what (header, data, trailer) was sent.
2869 if (this->success_ && this->header_and_trailer_ != 0)
2871 ACE_Message_Block *header = this->header_and_trailer_->header ();
2873 header->rd_ptr (this->header_and_trailer_->header_bytes ());
2875 ACE_Message_Block *trailer = this->header_and_trailer_->trailer ();
2877 trailer->rd_ptr (this->header_and_trailer_->trailer_bytes ());
2881 // Create the interface result class.
2882 ACE_Asynch_Transmit_File::Result
result (this);
2884 // Call the application handler.
2885 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
2887 handler
->handle_transmit_file (result
);
2890 ACE_WIN32_Asynch_Transmit_File_Result::~ACE_WIN32_Asynch_Transmit_File_Result (void)
2894 // Base class operations. These operations are here to kill dominance
2895 // warnings. These methods call the base class methods.
2898 ACE_WIN32_Asynch_Transmit_File_Result::bytes_transferred (void) const
2900 return ACE_WIN32_Asynch_Result::bytes_transferred ();
2904 ACE_WIN32_Asynch_Transmit_File_Result::act (void) const
2906 return ACE_WIN32_Asynch_Result::act ();
2910 ACE_WIN32_Asynch_Transmit_File_Result::success (void) const
2912 return ACE_WIN32_Asynch_Result::success ();
2916 ACE_WIN32_Asynch_Transmit_File_Result::completion_key (void) const
2918 return ACE_WIN32_Asynch_Result::completion_key ();
2922 ACE_WIN32_Asynch_Transmit_File_Result::error (void) const
2924 return ACE_WIN32_Asynch_Result::error ();
2928 ACE_WIN32_Asynch_Transmit_File_Result::event (void) const
2930 return ACE_WIN32_Asynch_Result::event ();
2934 ACE_WIN32_Asynch_Transmit_File_Result::offset (void) const
2936 return ACE_WIN32_Asynch_Result::offset ();
2940 ACE_WIN32_Asynch_Transmit_File_Result::offset_high (void) const
2942 return ACE_WIN32_Asynch_Result::offset_high ();
2946 ACE_WIN32_Asynch_Transmit_File_Result::priority (void) const
2948 return ACE_WIN32_Asynch_Result::priority ();
2952 ACE_WIN32_Asynch_Transmit_File_Result::signal_number (void) const
2954 return ACE_WIN32_Asynch_Result::signal_number ();
2958 ACE_WIN32_Asynch_Transmit_File_Result::post_completion (ACE_Proactor_Impl
*proactor
)
2960 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
2963 ACE_WIN32_Asynch_Transmit_File::ACE_WIN32_Asynch_Transmit_File (ACE_WIN32_Proactor
*win32_proactor
)
2964 : ACE_Asynch_Operation_Impl (),
2965 ACE_Asynch_Transmit_File_Impl (),
2966 ACE_WIN32_Asynch_Operation (win32_proactor
)
2971 ACE_WIN32_Asynch_Transmit_File::transmit_file (ACE_HANDLE file
,
2972 ACE_Asynch_Transmit_File::Header_And_Trailer
*header_and_trailer
,
2973 size_t bytes_to_write
,
2976 size_t bytes_per_send
,
2982 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
2984 // TransmitFile API limits us to DWORD range.
2985 if (bytes_to_write
> MAXDWORD
|| bytes_per_send
> MAXDWORD
)
2990 DWORD dword_bytes_to_write
= static_cast<DWORD
> (bytes_to_write
);
2991 DWORD dword_bytes_per_send
= static_cast<DWORD
> (bytes_per_send
);
2993 ACE_WIN32_Asynch_Transmit_File_Result
*result
= 0;
2994 ACE_NEW_RETURN (result
,
2995 ACE_WIN32_Asynch_Transmit_File_Result (this->handler_proxy_
,
3005 this->win32_proactor_
->get_handle (),
3010 ACE_LPTRANSMIT_FILE_BUFFERS transmit_buffers
= 0;
3011 if (result
->header_and_trailer () != 0)
3012 transmit_buffers
= result
->header_and_trailer ()->transmit_buffers ();
3014 // Initiate the transmit file
3015 int initiate_result
= ::TransmitFile ((SOCKET
) result
->socket (),
3017 dword_bytes_to_write
,
3018 dword_bytes_per_send
,
3022 if (initiate_result
== 1)
3023 // Immediate success: the OVERLAPPED will still get queued.
3026 // If initiate failed, check for a bad error.
3027 ACE_OS::set_errno_to_last_error ();
3030 case ERROR_IO_PENDING
:
3031 // The IO will complete proactively: the OVERLAPPED will still
3036 // Something else went wrong: the OVERLAPPED will not get
3039 // Cleanup dynamically allocated Asynch_Result
3044 ACE_DEBUG ((LM_ERROR
,
3046 ACE_TEXT ("TransmitFile")));
3051 ACE_UNUSED_ARG (file
);
3052 ACE_UNUSED_ARG (header_and_trailer
);
3053 ACE_UNUSED_ARG (bytes_to_write
);
3054 ACE_UNUSED_ARG (offset
);
3055 ACE_UNUSED_ARG (offset_high
);
3056 ACE_UNUSED_ARG (bytes_per_send
);
3057 ACE_UNUSED_ARG (flags
);
3058 ACE_UNUSED_ARG (act
);
3059 ACE_UNUSED_ARG (priority
);
3060 ACE_UNUSED_ARG (signal_number
);
3061 ACE_NOTSUP_RETURN (-1);
3062 #endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_WINSOCK2 */
3065 ACE_WIN32_Asynch_Transmit_File::~ACE_WIN32_Asynch_Transmit_File (void)
3069 // Methods belong to ACE_WIN32_Asynch_Operation base class. These
3070 // methods are defined here to avoid VC++ warnings. They route the
3071 // call to the ACE_WIN32_Asynch_Operation base class.
3074 ACE_WIN32_Asynch_Transmit_File::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
3076 const void *completion_key
,
3077 ACE_Proactor
*proactor
)
3079 return ACE_WIN32_Asynch_Operation::open (handler_proxy
,
3086 ACE_WIN32_Asynch_Transmit_File::cancel (void)
3088 return ACE_WIN32_Asynch_Operation::cancel ();
3092 ACE_WIN32_Asynch_Transmit_File::proactor (void) const
3094 return ACE_WIN32_Asynch_Operation::proactor ();
3098 ACE_WIN32_Asynch_Read_Dgram_Result::bytes_to_read (void) const
3100 return this->bytes_to_read_
;
3104 ACE_WIN32_Asynch_Read_Dgram_Result::message_block (void) const
3106 return this->message_block_
;
3111 ACE_WIN32_Asynch_Read_Dgram_Result::remote_address (ACE_Addr
& addr
) const
3113 int retVal
= -1; // failure
3115 // make sure the addresses are of the same type
3116 if (addr
.get_type () == this->remote_address_
->get_type ())
3117 { // copy the remote_address_ into addr
3118 addr
.set_addr (this->remote_address_
->get_addr (),
3119 this->remote_address_
->get_size ());
3120 retVal
= 0; // success
3127 ACE_WIN32_Asynch_Read_Dgram_Result::saddr () const
3129 return (sockaddr
*) this->remote_address_
->get_addr ();
3134 ACE_WIN32_Asynch_Read_Dgram_Result::flags (void) const
3136 return this->flags_
;
3140 ACE_WIN32_Asynch_Read_Dgram_Result::handle (void) const
3142 return this->handle_
;
3146 ACE_WIN32_Asynch_Read_Dgram_Result::bytes_transferred (void) const
3148 return ACE_WIN32_Asynch_Result::bytes_transferred ();
3152 ACE_WIN32_Asynch_Read_Dgram_Result::act (void) const
3154 return ACE_WIN32_Asynch_Result::act ();
3158 ACE_WIN32_Asynch_Read_Dgram_Result::success (void) const
3160 return ACE_WIN32_Asynch_Result::success ();
3164 ACE_WIN32_Asynch_Read_Dgram_Result::completion_key (void) const
3166 return ACE_WIN32_Asynch_Result::completion_key ();
3170 ACE_WIN32_Asynch_Read_Dgram_Result::error (void) const
3172 return ACE_WIN32_Asynch_Result::error ();
3176 ACE_WIN32_Asynch_Read_Dgram_Result::event (void) const
3178 return ACE_WIN32_Asynch_Result::event ();
3182 ACE_WIN32_Asynch_Read_Dgram_Result::offset (void) const
3184 return ACE_WIN32_Asynch_Result::offset ();
3188 ACE_WIN32_Asynch_Read_Dgram_Result::offset_high (void) const
3190 return ACE_WIN32_Asynch_Result::offset_high ();
3194 ACE_WIN32_Asynch_Read_Dgram_Result::priority (void) const
3196 return ACE_WIN32_Asynch_Result::priority ();
3200 ACE_WIN32_Asynch_Read_Dgram_Result::signal_number (void) const
3202 return ACE_WIN32_Asynch_Result::signal_number ();
3206 ACE_WIN32_Asynch_Read_Dgram_Result::post_completion (ACE_Proactor_Impl
*proactor
)
3208 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
3211 ACE_WIN32_Asynch_Read_Dgram_Result::ACE_WIN32_Asynch_Read_Dgram_Result (
3212 const ACE_Handler::Proxy_Ptr
&handler_proxy
,
3214 ACE_Message_Block
*message_block
,
3215 size_t bytes_to_read
,
3217 int protocol_family
,
3222 : ACE_Asynch_Result_Impl (),
3223 ACE_Asynch_Read_Dgram_Result_Impl(),
3224 ACE_WIN32_Asynch_Result (handler_proxy
, act
, event
, 0, 0, priority
, signal_number
),
3225 bytes_to_read_ (bytes_to_read
),
3226 message_block_ (message_block
),
3227 remote_address_ (0),
3232 ACE_ASSERT (protocol_family
== PF_INET
); // only supporting INET addresses
3234 ACE_NEW (remote_address_
, ACE_INET_Addr
);
3235 addr_len_
= remote_address_
->get_size ();
3237 ACE_UNUSED_ARG (protocol_family
);
3241 ACE_WIN32_Asynch_Read_Dgram_Result::complete (size_t bytes_transferred
,
3243 const void *completion_key
,
3246 // Copy the data which was returned by GetQueuedCompletionStatus
3247 this->bytes_transferred_
= bytes_transferred
;
3248 this->success_
= success
;
3249 this->completion_key_
= completion_key
;
3250 this->error_
= error
;
3252 // Appropriately move the pointers in the message block.
3253 for (ACE_Message_Block
* mb
= this->message_block_
;
3254 (mb
!= 0) && (bytes_transferred
> 0);
3257 size_t len_part
= mb
->space ();
3259 if ( len_part
> bytes_transferred
)
3260 len_part
= bytes_transferred
;
3262 mb
->wr_ptr (len_part
);
3264 bytes_transferred
-= len_part
;
3267 // Adjust the address length
3268 this->remote_address_
->set_size (this->addr_len_
);
3270 // Create the interface result class.
3271 ACE_Asynch_Read_Dgram::Result
result (this);
3273 // Call the application handler.
3274 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
3276 handler
->handle_read_dgram (result
);
3279 ACE_WIN32_Asynch_Read_Dgram_Result::~ACE_WIN32_Asynch_Read_Dgram_Result (void)
3281 delete this->remote_address_
;
3284 //***************************************************************************
3286 ACE_WIN32_Asynch_Read_Dgram::~ACE_WIN32_Asynch_Read_Dgram (void)
3291 ACE_WIN32_Asynch_Read_Dgram::recv (ACE_Message_Block
*message_block
,
3292 size_t & number_of_bytes_recvd
,
3294 int protocol_family
,
3299 number_of_bytes_recvd
= 0;
3301 size_t bytes_to_read
= 0;
3303 iovec iov
[ACE_IOV_MAX
];
3306 for (const ACE_Message_Block
* msg
= message_block
;
3307 msg
!= 0 && iovcnt
< ACE_IOV_MAX
;
3308 msg
= msg
->cont () , ++iovcnt
)
3310 size_t msg_space
= msg
->space ();
3312 // OS should correctly process zero length buffers
3313 // if ( msg_space == 0 )
3314 // ACE_ERROR_RETURN ((LM_ERROR,
3315 // ACE_TEXT ("ACE_WIN32_Asynch_Read_Dgram::recv:")
3316 // ACE_TEXT ("No space in the message block\n")),
3319 bytes_to_read
+= msg_space
;
3321 // Make as many iovec as needed to fit all of msg_len.
3322 size_t wr_ptr_offset
= 0;
3324 while (msg_space
> 0 && iovcnt
< ACE_IOV_MAX
)
3326 u_long this_chunk_length
;
3327 if (msg_space
> ULONG_MAX
)
3328 this_chunk_length
= ULONG_MAX
;
3330 this_chunk_length
= static_cast<u_long
> (msg_space
);
3331 // Collect the data in the iovec.
3332 iov
[iovcnt
].iov_base
= msg
->wr_ptr () + wr_ptr_offset
;
3333 iov
[iovcnt
].iov_len
= this_chunk_length
;
3334 msg_space
-= this_chunk_length
;
3335 wr_ptr_offset
+= this_chunk_length
;
3337 // Increment iovec counter if there's more to do.
3341 if (msg_space
> 0) // Ran out of iovecs before msg_space exhausted
3348 if (bytes_to_read
== 0)
3349 ACE_ERROR_RETURN ((LM_ERROR
,
3350 ACE_TEXT ("ACE_WIN32_Asynch_Read_Dgram::recv:")
3351 ACE_TEXT ("Attempt to read 0 bytes\n")),
3354 // Create the Asynch_Result.
3355 ACE_WIN32_Asynch_Read_Dgram_Result
*result
= 0;
3356 ACE_NEW_RETURN (result
,
3357 ACE_WIN32_Asynch_Read_Dgram_Result (this->handler_proxy_
,
3364 this->win32_proactor_
->get_handle (),
3369 // do the scatter/gather recv
3370 ssize_t initiate_result
= ACE_OS::recvfrom (result
->handle (),
3373 number_of_bytes_recvd
,
3376 &(result
->addr_len_
),
3379 if (initiate_result
== SOCKET_ERROR
)
3381 // If initiate failed, check for a bad error.
3382 ACE_OS::set_errno_to_last_error ();
3385 case ERROR_IO_PENDING
:
3386 // The IO will complete proactively: the OVERLAPPED will still
3388 initiate_result
= 0;
3392 // Something else went wrong: the OVERLAPPED will not get
3397 ACE_DEBUG ((LM_ERROR
,
3399 ACE_TEXT ("WSARecvFrom")));
3403 initiate_result
= -1;
3410 // Immediate success: the OVERLAPPED will still get queued.
3411 // number_of_bytes_recvd contains the number of bytes recvd
3412 // addr contains the peer address
3413 // flags was updated
3415 // number_of_bytes_recvd = bytes_recvd;
3416 initiate_result
= 1;
3419 return initiate_result
;
3423 ACE_WIN32_Asynch_Read_Dgram::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
3425 const void *completion_key
,
3426 ACE_Proactor
*proactor
)
3428 return ACE_WIN32_Asynch_Operation::open (handler_proxy
,
3435 ACE_WIN32_Asynch_Read_Dgram::cancel (void)
3437 return ACE_WIN32_Asynch_Operation::cancel ();
3441 ACE_WIN32_Asynch_Read_Dgram::proactor (void) const
3443 return ACE_WIN32_Asynch_Operation::proactor ();
3446 ACE_WIN32_Asynch_Read_Dgram::ACE_WIN32_Asynch_Read_Dgram (ACE_WIN32_Proactor
*win32_proactor
)
3447 : ACE_Asynch_Operation_Impl (),
3448 ACE_Asynch_Read_Dgram_Impl (),
3449 ACE_WIN32_Asynch_Operation (win32_proactor
)
3453 //***********************************************
3456 ACE_WIN32_Asynch_Write_Dgram_Result::bytes_to_write (void) const
3458 return this->bytes_to_write_
;
3462 ACE_WIN32_Asynch_Write_Dgram_Result::message_block () const
3464 return this->message_block_
;
3468 ACE_WIN32_Asynch_Write_Dgram_Result::flags (void) const
3470 return this->flags_
;
3474 ACE_WIN32_Asynch_Write_Dgram_Result::handle (void) const
3476 return this->handle_
;
3480 ACE_WIN32_Asynch_Write_Dgram_Result::bytes_transferred (void) const
3482 return ACE_WIN32_Asynch_Result::bytes_transferred ();
3486 ACE_WIN32_Asynch_Write_Dgram_Result::act (void) const
3488 return ACE_WIN32_Asynch_Result::act ();
3492 ACE_WIN32_Asynch_Write_Dgram_Result::success (void) const
3494 return ACE_WIN32_Asynch_Result::success ();
3498 ACE_WIN32_Asynch_Write_Dgram_Result::completion_key (void) const
3500 return ACE_WIN32_Asynch_Result::completion_key ();
3504 ACE_WIN32_Asynch_Write_Dgram_Result::error (void) const
3506 return ACE_WIN32_Asynch_Result::error ();
3510 ACE_WIN32_Asynch_Write_Dgram_Result::event (void) const
3512 return ACE_WIN32_Asynch_Result::event ();
3516 ACE_WIN32_Asynch_Write_Dgram_Result::offset (void) const
3518 return ACE_WIN32_Asynch_Result::offset ();
3522 ACE_WIN32_Asynch_Write_Dgram_Result::offset_high (void) const
3524 return ACE_WIN32_Asynch_Result::offset_high ();
3528 ACE_WIN32_Asynch_Write_Dgram_Result::priority (void) const
3530 return ACE_WIN32_Asynch_Result::priority ();
3534 ACE_WIN32_Asynch_Write_Dgram_Result::signal_number (void) const
3536 return ACE_WIN32_Asynch_Result::signal_number ();
3540 ACE_WIN32_Asynch_Write_Dgram_Result::post_completion (ACE_Proactor_Impl
*proactor
)
3542 return ACE_WIN32_Asynch_Result::post_completion (proactor
);
3545 ACE_WIN32_Asynch_Write_Dgram_Result::ACE_WIN32_Asynch_Write_Dgram_Result (
3546 const ACE_Handler::Proxy_Ptr
&handler_proxy
,
3548 ACE_Message_Block
*message_block
,
3549 size_t bytes_to_write
,
3555 : ACE_Asynch_Result_Impl (),
3556 ACE_Asynch_Write_Dgram_Result_Impl(),
3557 ACE_WIN32_Asynch_Result (handler_proxy
,
3564 bytes_to_write_ (bytes_to_write
),
3565 message_block_ (message_block
),
3572 ACE_WIN32_Asynch_Write_Dgram_Result::complete (size_t bytes_transferred
,
3574 const void *completion_key
,
3577 // Copy the data which was returned by GetQueuedCompletionStatus
3578 this->bytes_transferred_
= bytes_transferred
;
3579 this->success_
= success
;
3580 this->completion_key_
= completion_key
;
3581 this->error_
= error
;
3583 // Appropriately move the pointers in the message block.
3584 for (ACE_Message_Block
* mb
= this->message_block_
;
3585 (mb
!= 0) && (bytes_transferred
> 0);
3588 size_t len_part
= mb
->length ();
3590 if ( len_part
> bytes_transferred
)
3591 len_part
= bytes_transferred
;
3593 mb
->rd_ptr (len_part
);
3595 bytes_transferred
-= len_part
;
3598 // Create the interface result class.
3599 ACE_Asynch_Write_Dgram::Result
result (this);
3601 // Call the application handler.
3602 ACE_Handler
*handler
= this->handler_proxy_
.get ()->handler ();
3604 handler
->handle_write_dgram (result
);
3607 ACE_WIN32_Asynch_Write_Dgram_Result::~ACE_WIN32_Asynch_Write_Dgram_Result (void)
3612 //***********************************************
3614 ACE_WIN32_Asynch_Write_Dgram::~ACE_WIN32_Asynch_Write_Dgram (void)
3619 ACE_WIN32_Asynch_Write_Dgram::send (ACE_Message_Block
*message_block
,
3620 size_t &number_of_bytes_sent
,
3622 const ACE_Addr
&addr
,
3627 number_of_bytes_sent
= 0;
3629 size_t bytes_to_write
= 0;
3631 iovec iov
[ACE_IOV_MAX
];
3634 for (const ACE_Message_Block
* msg
= message_block
;
3635 msg
!= 0 && iovcnt
< ACE_IOV_MAX
;
3636 msg
= msg
->cont () , ++iovcnt
)
3638 size_t msg_len
= msg
->length ();
3640 bytes_to_write
+= msg_len
;
3642 // Make as many iovec as needed to fit all of msg_len.
3643 size_t rd_ptr_offset
= 0;
3647 if (msg_len
>= 0 && iovcnt
< ACE_IOV_MAX
)
3649 u_long this_chunk_length
;
3650 if (msg_len
> ULONG_MAX
)
3651 this_chunk_length
= ULONG_MAX
;
3653 this_chunk_length
= static_cast<u_long
> (msg_len
);
3655 // Collect the data in the iovec.
3656 iov
[iovcnt
].iov_base
= msg
->rd_ptr () + rd_ptr_offset
;
3657 iov
[iovcnt
].iov_len
= this_chunk_length
;
3658 msg_len
-= this_chunk_length
;
3659 rd_ptr_offset
+= this_chunk_length
;
3661 // Increment iovec counter if there's more to do.
3666 while (msg_len
> 0 && iovcnt
< ACE_IOV_MAX
);
3668 if (msg_len
> 0) // Ran out of iovecs before msg_space exhausted
3675 // Create the Asynch_Result.
3676 ACE_WIN32_Asynch_Write_Dgram_Result
*result
= 0;
3677 ACE_NEW_RETURN (result
,
3678 ACE_WIN32_Asynch_Write_Dgram_Result (this->handler_proxy_
,
3684 this->win32_proactor_
->get_handle (),
3689 // do the scatter/gather send
3691 ssize_t initiate_result
= ACE_OS::sendto (result
->handle (),
3694 number_of_bytes_sent
,
3696 (sockaddr
*) addr
.get_addr (),
3702 if (initiate_result
== SOCKET_ERROR
)
3704 // If initiate failed, check for a bad error.
3705 ACE_OS::set_errno_to_last_error ();
3708 case ERROR_IO_PENDING
:
3709 // The IO will complete proactively: the OVERLAPPED will still
3711 initiate_result
= 0;
3715 // Something else went wrong: the OVERLAPPED will not get
3720 ACE_DEBUG ((LM_ERROR
,
3722 ACE_TEXT ("WSASendTo")));
3726 initiate_result
= -1;
3733 // Immediate success: the OVERLAPPED will still get queued.
3734 // number_of_bytes_recvd contains the number of bytes recvd
3735 // addr contains the peer address
3736 // flags was updated
3738 // number_of_bytes_sent = bytes_sent;
3739 initiate_result
= 1;
3742 return initiate_result
;
3746 ACE_WIN32_Asynch_Write_Dgram::open (const ACE_Handler::Proxy_Ptr
&handler_proxy
,
3748 const void *completion_key
,
3749 ACE_Proactor
*proactor
)
3751 return ACE_WIN32_Asynch_Operation::open (handler_proxy
,
3758 ACE_WIN32_Asynch_Write_Dgram::cancel (void)
3760 return ACE_WIN32_Asynch_Operation::cancel ();
3764 ACE_WIN32_Asynch_Write_Dgram::proactor (void) const
3766 return ACE_WIN32_Asynch_Operation::proactor ();
3769 ACE_WIN32_Asynch_Write_Dgram::ACE_WIN32_Asynch_Write_Dgram (ACE_WIN32_Proactor
*win32_proactor
)
3770 : ACE_Asynch_Operation_Impl (),
3771 ACE_Asynch_Write_Dgram_Impl (),
3772 ACE_WIN32_Asynch_Operation (win32_proactor
)
3776 ACE_END_VERSIONED_NAMESPACE_DECL
3778 #endif /* ACE_HAS_WIN32_OVERLAPPED_IO && ACE_HAS_WINSOCK2 */