Initial Patch of Auction House bot rev. 135
[auctionmangos.git] / dep / ACE_wrappers / ace / WIN32_Asynch_IO.cpp
blob6f201acccbde36abe6d99e12389981fad2fbe8c1
1 // $Id: WIN32_Asynch_IO.cpp 82444 2008-07-28 13:33:07Z johnnyw $
3 #include "ace/WIN32_Asynch_IO.h"
5 ACE_RCSID (ace,
6 Win32_Asynch_IO,
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
24 size_t
25 ACE_WIN32_Asynch_Result::bytes_transferred (void) const
27 return this->bytes_transferred_;
30 const void *
31 ACE_WIN32_Asynch_Result::act (void) const
33 return this->act_;
36 int
37 ACE_WIN32_Asynch_Result::success (void) const
39 return this->success_;
42 const void *
43 ACE_WIN32_Asynch_Result::completion_key (void) const
45 return this->completion_key_;
48 u_long
49 ACE_WIN32_Asynch_Result::error (void) const
51 return this->error_;
54 ACE_HANDLE
55 ACE_WIN32_Asynch_Result::event (void) const
57 return this->hEvent;
60 u_long
61 ACE_WIN32_Asynch_Result::offset (void) const
63 return this->Offset;
66 u_long
67 ACE_WIN32_Asynch_Result::offset_high (void) const
69 return this->OffsetHigh;
72 int
73 ACE_WIN32_Asynch_Result::priority (void) const
75 ACE_NOTSUP_RETURN (0);
78 int
79 ACE_WIN32_Asynch_Result::signal_number (void) const
81 ACE_NOTSUP_RETURN (0);
84 int
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")),
93 -1);
95 // Post myself.
96 return win32_proactor->post_completion (this);
99 void
100 ACE_WIN32_Asynch_Result::set_bytes_transferred (size_t nbytes)
102 this->bytes_transferred_ = nbytes;
105 void
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,
117 const void* act,
118 ACE_HANDLE event,
119 u_long offset,
120 u_long offset_high,
121 int priority,
122 int signal_number)
123 : ACE_Asynch_Result_Impl (),
124 OVERLAPPED (),
125 handler_proxy_ (handler_proxy),
126 act_ (act),
127 bytes_transferred_ (0),
128 success_ (0),
129 completion_key_ (0),
130 error_ (0)
132 // Set the ACE_OVERLAPPED structure
133 this->Internal = 0;
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,
145 ACE_HANDLE handle,
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 ();
157 if (handler != 0)
158 this->handle_ = handler->handle ();
160 if (this->handle_ == ACE_INVALID_HANDLE)
161 return -1;
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_,
170 completion_key);
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_);
185 if (result == 0)
186 // Couldn't cancel the operations.
187 return 2;
189 // result is non-zero. All the operations are cancelled then.
190 return 0;
192 #else /* !ACE_HAS_WIN32_OVERLAPPED_IO */
193 ACE_NOTSUP_RETURN (-1);
194 #endif /* ACE_HAS_AIO_CALLS */
197 ACE_Proactor *
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),
206 proactor_ (0),
207 handle_ (ACE_INVALID_HANDLE)
211 ACE_WIN32_Asynch_Operation::~ACE_WIN32_Asynch_Operation (void)
215 // ************************************************************
217 size_t
218 ACE_WIN32_Asynch_Read_Stream_Result::bytes_to_read (void) const
220 return this->bytes_to_read_;
223 ACE_Message_Block &
224 ACE_WIN32_Asynch_Read_Stream_Result::message_block (void) const
226 return this->message_block_;
229 ACE_HANDLE
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,
237 ACE_HANDLE handle,
238 ACE_Message_Block &message_block,
239 size_t bytes_to_read,
240 const void* act,
241 ACE_HANDLE event,
242 int priority,
243 int signal_number,
244 int scatter_enabled)
245 : ACE_Asynch_Result_Impl (),
246 ACE_Asynch_Read_Stream_Result_Impl (),
247 ACE_WIN32_Asynch_Result (handler_proxy,
248 act,
249 event,
252 priority,
253 signal_number),
254 bytes_to_read_ (bytes_to_read),
255 message_block_ (message_block),
256 handle_ (handle),
257 scatter_enabled_ (scatter_enabled)
261 void
262 ACE_WIN32_Asynch_Read_Stream_Result::complete (size_t bytes_transferred,
263 int success,
264 const void *completion_key,
265 u_long error)
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);
276 else
278 for (ACE_Message_Block* mb = &this->message_block_;
279 (mb != 0) && (bytes_transferred > 0);
280 mb = mb->cont ())
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 ();
298 if (handler != 0)
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.
309 size_t
310 ACE_WIN32_Asynch_Read_Stream_Result::bytes_transferred (void) const
312 return ACE_WIN32_Asynch_Result::bytes_transferred ();
315 const void *
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 ();
327 const void *
328 ACE_WIN32_Asynch_Read_Stream_Result::completion_key (void) const
330 return ACE_WIN32_Asynch_Result::completion_key ();
333 u_long
334 ACE_WIN32_Asynch_Read_Stream_Result::error (void) const
336 return ACE_WIN32_Asynch_Result::error ();
339 ACE_HANDLE
340 ACE_WIN32_Asynch_Read_Stream_Result::event (void) const
342 return ACE_WIN32_Asynch_Result::event ();
345 u_long
346 ACE_WIN32_Asynch_Read_Stream_Result::offset (void) const
348 return ACE_WIN32_Asynch_Result::offset ();
351 u_long
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,
391 const void *act,
392 int priority,
393 int signal_number)
395 size_t space = message_block.space ();
396 if (bytes_to_read > space)
397 bytes_to_read = space;
399 if (bytes_to_read == 0)
401 errno = ENOSPC;
402 return -1;
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_,
409 this->handle_,
410 message_block,
411 bytes_to_read,
412 act,
413 this->win32_proactor_->get_handle (),
414 priority,
415 signal_number),
416 -1);
418 // Shared read
419 int const return_val = this->shared_read (result);
421 // Upon errors
422 if (return_val == -1)
423 delete result;
425 return return_val;
429 ACE_WIN32_Asynch_Read_Stream::readv (ACE_Message_Block &message_block,
430 size_t bytes_to_read,
431 const void *act,
432 int priority,
433 int signal_number)
435 #if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
436 iovec iov[ACE_IOV_MAX];
437 int iovcnt = 0;
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")),
453 // -1);
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;
467 else
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.
476 if (msg_space > 0)
477 ++iovcnt;
479 if (msg_space > 0) // Ran out of iovecs before msg_space exhausted
481 errno = ERANGE;
482 return -1;
486 // Re-calculate number bytes to read
487 bytes_to_read = 0;
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")),
496 -1);
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_,
502 this->handle_,
503 message_block,
504 bytes_to_read,
505 act,
506 this->win32_proactor_->get_handle (),
507 priority,
508 signal_number,
509 1), // scatter read enabled
510 -1);
512 // do the scatter recv
514 result->set_error (0); // Clear error before starting IO.
516 DWORD bytes_recvd = 0;
517 u_long flags = 0;
519 int initiate_result = ::WSARecv (reinterpret_cast<SOCKET> (result->handle ()),
520 reinterpret_cast<WSABUF *> (iov),
521 iovcnt,
522 &bytes_recvd,
523 &flags,
524 result,
527 if (0 == initiate_result)
528 // Immediate success: the OVERLAPPED will still get queued.
529 return 1;
531 ACE_ASSERT (initiate_result == SOCKET_ERROR);
533 // If initiate failed, check for a bad error.
534 ACE_OS::set_errno_to_last_error ();
535 switch (errno)
537 case ERROR_IO_PENDING:
538 // The IO will complete proactively: the OVERLAPPED will still
539 // get queued.
540 initiate_result = 0;
541 break;
543 default:
544 // Something else went wrong: the OVERLAPPED will not get
545 // queued.
547 if (ACE::debug ())
549 ACE_DEBUG ((LM_ERROR,
550 ACE_TEXT ("%p\n"),
551 ACE_TEXT ("WSARecv")));
554 delete result;
555 initiate_result = -1;
556 break;
559 return initiate_result;
560 #else
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)
580 errno = ERANGE;
581 return -1;
583 DWORD bytes_to_read = static_cast<DWORD> (result->bytes_to_read ());
584 u_long bytes_read;
586 result->set_error (0); // Clear error before starting IO.
588 // Initiate the read
589 int initiate_result = ::ReadFile (result->handle (),
590 result->message_block ().wr_ptr (),
591 bytes_to_read,
592 &bytes_read,
593 result);
594 if (initiate_result == 1)
595 // Immediate success: the OVERLAPPED will still get queued.
596 return 0;
598 // If initiate failed, check for a bad error.
599 ACE_OS::set_errno_to_last_error ();
600 switch (errno)
602 case ERROR_IO_PENDING:
603 /* FALLTHRU */
604 case ERROR_MORE_DATA:
605 // The IO will complete proactively: the OVERLAPPED will still
606 // get queued.
607 return 0;
609 default:
610 // Something else went wrong: the OVERLAPPED will not get
611 // queued.
613 if (ACE::debug ())
615 ACE_DEBUG ((LM_ERROR,
616 ACE_TEXT ("%p\n"),
617 ACE_TEXT ("ReadFile")));
620 return -1;
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,
630 ACE_HANDLE handle,
631 const void *completion_key,
632 ACE_Proactor *proactor)
634 return ACE_WIN32_Asynch_Operation::open (handler_proxy,
635 handle,
636 completion_key,
637 proactor);
641 ACE_WIN32_Asynch_Read_Stream::cancel (void)
643 return ACE_WIN32_Asynch_Operation::cancel ();
646 ACE_Proactor *
647 ACE_WIN32_Asynch_Read_Stream::proactor (void) const
649 return ACE_WIN32_Asynch_Operation::proactor ();
652 size_t
653 ACE_WIN32_Asynch_Write_Stream_Result::bytes_to_write (void) const
655 return this->bytes_to_write_;
658 ACE_Message_Block &
659 ACE_WIN32_Asynch_Write_Stream_Result::message_block (void) const
661 return this->message_block_;
664 ACE_HANDLE
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,
672 ACE_HANDLE handle,
673 ACE_Message_Block &message_block,
674 size_t bytes_to_write,
675 const void* act,
676 ACE_HANDLE event,
677 int priority,
678 int signal_number,
679 int gather_enabled)
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),
686 handle_ (handle),
687 gather_enabled_ (gather_enabled)
691 void
692 ACE_WIN32_Asynch_Write_Stream_Result::complete (size_t bytes_transferred,
693 int success,
694 const void *completion_key,
695 u_long error)
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);
706 else
708 for (ACE_Message_Block* mb = &this->message_block_;
709 (mb != 0) && (bytes_transferred > 0);
710 mb = mb->cont ())
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 ();
728 if (handler != 0)
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.
739 size_t
740 ACE_WIN32_Asynch_Write_Stream_Result::bytes_transferred (void) const
742 return ACE_WIN32_Asynch_Result::bytes_transferred ();
745 const void *
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 ();
757 const void *
758 ACE_WIN32_Asynch_Write_Stream_Result::completion_key (void) const
760 return ACE_WIN32_Asynch_Result::completion_key ();
763 u_long
764 ACE_WIN32_Asynch_Write_Stream_Result::error (void) const
766 return ACE_WIN32_Asynch_Result::error ();
769 ACE_HANDLE
770 ACE_WIN32_Asynch_Write_Stream_Result::event (void) const
772 return ACE_WIN32_Asynch_Result::event ();
775 u_long
776 ACE_WIN32_Asynch_Write_Stream_Result::offset (void) const
778 return ACE_WIN32_Asynch_Result::offset ();
781 u_long
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,
821 const void *act,
822 int priority,
823 int signal_number)
825 size_t len = message_block.length();
827 if (bytes_to_write > len)
828 bytes_to_write = len ;
830 if (bytes_to_write == 0)
831 ACE_ERROR_RETURN
832 ((LM_ERROR,
833 ACE_TEXT ("ACE_WIN32_Asynch_Write_Stream::write:")
834 ACE_TEXT ("Attempt to write 0 bytes\n")),
835 -1);
837 ACE_WIN32_Asynch_Write_Stream_Result *result = 0;
838 ACE_NEW_RETURN (result,
839 ACE_WIN32_Asynch_Write_Stream_Result (this->handler_proxy_,
840 this->handle_,
841 message_block,
842 bytes_to_write,
843 act,
844 this->win32_proactor_->get_handle (),
845 priority,
846 signal_number),
847 -1);
849 // Shared write
850 int return_val = this->shared_write (result);
852 // Upon errors
853 if (return_val == -1)
854 delete result;
856 return return_val;
860 ACE_WIN32_Asynch_Write_Stream::writev (ACE_Message_Block &message_block,
861 size_t bytes_to_write,
862 const void *act,
863 int priority,
864 int signal_number)
866 #if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
867 iovec iov[ACE_IOV_MAX];
868 int iovcnt = 0;
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;
875 msg = msg->cont ())
877 size_t msg_len = msg->length ();
879 // Skip 0-length blocks.
880 if (msg_len == 0)
881 continue;
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;
894 else
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.
903 if (msg_len > 0)
904 iovcnt++;
906 if (msg_len > 0) // Ran out of iovecs before msg_space exhausted
908 errno = ERANGE;
909 return -1;
911 ++iovcnt;
914 // Re-calculate number bytes to write
915 bytes_to_write = 0;
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")),
924 -1);
927 ACE_WIN32_Asynch_Write_Stream_Result *result = 0;
928 ACE_NEW_RETURN (result,
929 ACE_WIN32_Asynch_Write_Stream_Result (this->handler_proxy_,
930 this->handle_,
931 message_block,
932 bytes_to_write,
933 act,
934 this->win32_proactor_->get_handle (),
935 priority,
936 signal_number,
937 1), // gather write enabled
938 -1);
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),
946 iovcnt,
947 &bytes_sent,
948 0, // flags
949 result,
952 if (0 == initiate_result)
953 // Immediate success: the OVERLAPPED will still get queued.
954 return 1;
956 ACE_ASSERT (initiate_result == SOCKET_ERROR);
958 // If initiate failed, check for a bad error.
959 ACE_OS::set_errno_to_last_error ();
960 switch (errno)
962 case ERROR_IO_PENDING:
963 // The IO will complete proactively: the OVERLAPPED will still
964 // get queued.
965 initiate_result = 0;
966 break;
968 default:
969 // Something else went wrong: the OVERLAPPED will not get
970 // queued.
972 if (ACE::debug ())
974 ACE_DEBUG ((LM_ERROR,
975 ACE_TEXT ("%p\n"),
976 ACE_TEXT ("WSASend")));
979 delete result;
980 initiate_result = -1;
981 break;
984 return initiate_result;
985 #else
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)
1005 errno = ERANGE;
1006 return -1;
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))
1016 WSABUF iov;
1017 iov.buf = result->message_block ().rd_ptr ();
1018 iov.len = bytes_to_write;
1019 initiate_result = ::WSASend (reinterpret_cast<SOCKET> (result->handle ()),
1020 &iov,
1022 &bytes_written,
1023 0, // flags
1024 result,
1026 if (initiate_result == 0)
1027 // Immediate success: the OVERLAPPED will still get queued.
1028 return 0;
1029 #else
1030 initiate_result = ::WriteFile (result->handle (),
1031 result->message_block ().rd_ptr (),
1032 bytes_to_write,
1033 &bytes_written,
1034 result);
1035 if (initiate_result == 1)
1036 // Immediate success: the OVERLAPPED will still get queued.
1037 return 0;
1038 #endif /* ACE_HAS_WINSOCK2 */
1040 // If initiate failed, check for a bad error.
1041 ACE_OS::set_errno_to_last_error ();
1042 switch (errno)
1044 case ERROR_IO_PENDING:
1045 // The IO will complete proactively: the OVERLAPPED will still
1046 // get queued.
1047 return 0;
1049 default:
1050 // Something else went wrong: the OVERLAPPED will not get
1051 // queued.
1053 if (ACE::debug ())
1054 ACE_DEBUG ((LM_ERROR,
1055 ACE_TEXT ("%p\n"),
1056 ACE_TEXT ("Initiating write")));
1057 return -1;
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,
1067 ACE_HANDLE handle,
1068 const void *completion_key,
1069 ACE_Proactor *proactor)
1071 return ACE_WIN32_Asynch_Operation::open (handler_proxy,
1072 handle,
1073 completion_key,
1074 proactor);
1078 ACE_WIN32_Asynch_Write_Stream::cancel (void)
1080 return ACE_WIN32_Asynch_Operation::cancel ();
1083 ACE_Proactor *
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,
1091 ACE_HANDLE handle,
1092 ACE_Message_Block &message_block,
1093 size_t bytes_to_read,
1094 const void* act,
1095 u_long offset,
1096 u_long offset_high,
1097 ACE_HANDLE event,
1098 int priority,
1099 int signal_number,
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,
1105 handle,
1106 message_block,
1107 bytes_to_read,
1108 act,
1109 event,
1110 priority,
1111 signal_number,
1112 scatter_enabled)
1114 this->Offset = offset;
1115 this->OffsetHigh = offset_high;
1118 void
1119 ACE_WIN32_Asynch_Read_File_Result::complete (size_t bytes_transferred,
1120 int success,
1121 const void *completion_key,
1122 u_long error)
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);
1133 else
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);
1139 mb = mb->cont ())
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 ();
1161 if (handler != 0)
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.
1172 size_t
1173 ACE_WIN32_Asynch_Read_File_Result::bytes_transferred (void) const
1175 return ACE_WIN32_Asynch_Result::bytes_transferred ();
1178 const void *
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 ();
1190 const void *
1191 ACE_WIN32_Asynch_Read_File_Result::completion_key (void) const
1193 return ACE_WIN32_Asynch_Result::completion_key ();
1196 u_long
1197 ACE_WIN32_Asynch_Read_File_Result::error (void) const
1199 return ACE_WIN32_Asynch_Result::error ();
1202 ACE_HANDLE
1203 ACE_WIN32_Asynch_Read_File_Result::event (void) const
1205 return ACE_WIN32_Asynch_Result::event ();
1208 u_long
1209 ACE_WIN32_Asynch_Read_File_Result::offset (void) const
1211 return ACE_WIN32_Asynch_Result::offset ();
1214 u_long
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.
1237 size_t
1238 ACE_WIN32_Asynch_Read_File_Result::bytes_to_read (void) const
1240 return ACE_WIN32_Asynch_Read_Stream_Result::bytes_to_read ();
1243 ACE_Message_Block &
1244 ACE_WIN32_Asynch_Read_File_Result::message_block (void) const
1246 return ACE_WIN32_Asynch_Read_Stream_Result::message_block ();
1249 ACE_HANDLE
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,
1274 u_long offset,
1275 u_long offset_high,
1276 const void *act,
1277 int priority,
1278 int signal_number)
1280 size_t space = message_block.space ();
1281 if ( bytes_to_read > space )
1282 bytes_to_read = space;
1284 if ( bytes_to_read == 0 )
1285 ACE_ERROR_RETURN
1286 ((LM_ERROR,
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")),
1289 -1);
1292 ACE_WIN32_Asynch_Read_File_Result *result = 0;
1293 ACE_NEW_RETURN (result,
1294 ACE_WIN32_Asynch_Read_File_Result (this->handler_proxy_,
1295 this->handle_,
1296 message_block,
1297 bytes_to_read,
1298 act,
1299 offset,
1300 offset_high,
1301 this->win32_proactor_->get_handle (),
1302 priority,
1303 signal_number),
1304 -1);
1306 // Shared read
1307 int return_val = this->shared_read (result);
1309 // Upon errors
1310 if (return_val == -1)
1311 delete result;
1313 return return_val;
1317 ACE_WIN32_Asynch_Read_File::readv (ACE_Message_Block &message_block,
1318 size_t bytes_to_read,
1319 u_long offset,
1320 u_long offset_high,
1321 const void *act,
1322 int priority,
1323 int signal_number)
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")),
1349 -1);
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)
1362 errno = ERANGE;
1363 return -1;
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_,
1373 this->handle_,
1374 message_block,
1375 bytes_to_read,
1376 act,
1377 offset,
1378 offset_high,
1379 this->win32_proactor_->get_handle (),
1380 priority,
1381 signal_number,
1382 1), // scatter read enabled
1383 -1);
1385 // do the scatter read
1386 result->set_error (0); // Clear error before starting IO.
1388 int initiate_result = ::ReadFileScatter (result->handle (),
1389 buffer_pointers,
1390 dword_bytes_to_read,
1391 0, // reserved, must be NULL
1392 result);
1394 if (0 != initiate_result)
1395 // Immediate success: the OVERLAPPED will still get queued.
1396 return 1;
1398 // If initiate failed, check for a bad error.
1399 ACE_OS::set_errno_to_last_error ();
1400 switch (errno)
1402 case ERROR_IO_PENDING:
1403 // The IO will complete proactively: the OVERLAPPED will still
1404 // get queued.
1405 initiate_result = 0;
1406 break;
1408 default:
1409 // Something else went wrong: the OVERLAPPED will not get
1410 // queued.
1412 if (ACE::debug ())
1414 ACE_DEBUG ((LM_ERROR,
1415 ACE_TEXT ("%p\n"),
1416 ACE_TEXT ("ReadFileScatter")));
1419 delete result;
1420 initiate_result = -1;
1421 break;
1424 return initiate_result;
1425 #else
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,
1438 const void *act,
1439 int priority,
1440 int signal_number)
1442 return ACE_WIN32_Asynch_Read_Stream::read (message_block,
1443 bytes_to_read,
1444 act,
1445 priority,
1446 signal_number);
1450 ACE_WIN32_Asynch_Read_File::readv (ACE_Message_Block &message_block,
1451 size_t bytes_to_read,
1452 const void *act,
1453 int priority,
1454 int signal_number)
1456 return ACE_WIN32_Asynch_Read_Stream::readv (message_block,
1457 bytes_to_read,
1458 act,
1459 priority,
1460 signal_number);
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,
1469 ACE_HANDLE handle,
1470 const void *completion_key,
1471 ACE_Proactor *proactor)
1473 return ACE_WIN32_Asynch_Operation::open (handler_proxy,
1474 handle,
1475 completion_key,
1476 proactor);
1480 ACE_WIN32_Asynch_Read_File::cancel (void)
1482 return ACE_WIN32_Asynch_Operation::cancel ();
1485 ACE_Proactor *
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,
1493 ACE_HANDLE handle,
1494 ACE_Message_Block &message_block,
1495 size_t bytes_to_write,
1496 const void* act,
1497 u_long offset,
1498 u_long offset_high,
1499 ACE_HANDLE event,
1500 int priority,
1501 int signal_number,
1502 int gather_enabled)
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,
1507 handle,
1508 message_block,
1509 bytes_to_write,
1510 act,
1511 event,
1512 priority,
1513 signal_number,
1514 gather_enabled)
1516 this->Offset = offset;
1517 this->OffsetHigh = offset_high;
1520 void
1521 ACE_WIN32_Asynch_Write_File_Result::complete (size_t bytes_transferred,
1522 int success,
1523 const void *completion_key,
1524 u_long error)
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);
1535 else
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);
1541 mb = mb->cont ())
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 ();
1564 if (handler != 0)
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.
1575 size_t
1576 ACE_WIN32_Asynch_Write_File_Result::bytes_transferred (void) const
1578 return ACE_WIN32_Asynch_Result::bytes_transferred ();
1581 const void *
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 ();
1593 const void *
1594 ACE_WIN32_Asynch_Write_File_Result::completion_key (void) const
1596 return ACE_WIN32_Asynch_Result::completion_key ();
1599 u_long
1600 ACE_WIN32_Asynch_Write_File_Result::error (void) const
1602 return ACE_WIN32_Asynch_Result::error ();
1605 ACE_HANDLE
1606 ACE_WIN32_Asynch_Write_File_Result::event (void) const
1608 return ACE_WIN32_Asynch_Result::event ();
1611 u_long
1612 ACE_WIN32_Asynch_Write_File_Result::offset (void) const
1614 return ACE_WIN32_Asynch_Result::offset ();
1617 u_long
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.
1640 size_t
1641 ACE_WIN32_Asynch_Write_File_Result::bytes_to_write (void) const
1643 return ACE_WIN32_Asynch_Write_Stream_Result::bytes_to_write ();
1646 ACE_Message_Block &
1647 ACE_WIN32_Asynch_Write_File_Result::message_block (void) const
1649 return ACE_WIN32_Asynch_Write_Stream_Result::message_block ();
1652 ACE_HANDLE
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,
1675 u_long offset,
1676 u_long offset_high,
1677 const void *act,
1678 int priority,
1679 int signal_number)
1681 size_t len = message_block.length ();
1682 if ( bytes_to_write > len )
1683 bytes_to_write = len;
1685 if ( bytes_to_write == 0 )
1686 ACE_ERROR_RETURN
1687 ((LM_ERROR,
1688 ACE_TEXT ("ACE_WIN32_Asynch_Write_File::write:")
1689 ACE_TEXT ("Attempt to read 0 bytes\n")),
1690 -1);
1692 ACE_WIN32_Asynch_Write_File_Result *result = 0;
1693 ACE_NEW_RETURN (result,
1694 ACE_WIN32_Asynch_Write_File_Result (this->handler_proxy_,
1695 this->handle_,
1696 message_block,
1697 bytes_to_write,
1698 act,
1699 offset,
1700 offset_high,
1701 this->win32_proactor_->get_handle (),
1702 priority,
1703 signal_number),
1704 -1);
1706 // Shared write
1707 int return_val = this->shared_write (result);
1709 // Upon errors
1710 if (return_val == -1)
1711 delete result;
1713 return return_val;
1717 ACE_WIN32_Asynch_Write_File::writev (ACE_Message_Block &message_block,
1718 size_t bytes_to_write,
1719 u_long offset,
1720 u_long offset_high,
1721 const void *act,
1722 int priority,
1723 int signal_number)
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")),
1755 -1);
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)
1767 errno = ERANGE;
1768 return -1;
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_,
1778 this->handle_,
1779 message_block,
1780 bytes_to_write,
1781 act,
1782 offset,
1783 offset_high,
1784 this->win32_proactor_->get_handle (),
1785 priority,
1786 signal_number,
1787 1), // gather write enabled
1788 -1);
1790 result->set_error(0);
1792 // do the gather write
1793 int initiate_result = ::WriteFileGather (result->handle (),
1794 buffer_pointers,
1795 dword_bytes_to_write,
1796 0, // reserved, must be NULL
1797 result);
1799 if (0 != initiate_result)
1800 // Immediate success: the OVERLAPPED will still get queued.
1801 return 1;
1803 // If initiate failed, check for a bad error.
1804 ACE_OS::set_errno_to_last_error ();
1805 switch (errno)
1807 case ERROR_IO_PENDING:
1808 // The IO will complete proactively: the OVERLAPPED will still
1809 // get queued.
1810 initiate_result = 0;
1811 break;
1813 default:
1814 // Something else went wrong: the OVERLAPPED will not get
1815 // queued.
1817 if (ACE::debug ())
1819 ACE_DEBUG ((LM_ERROR,
1820 ACE_TEXT ("%p\n"),
1821 ACE_TEXT ("WriteFileGather")));
1824 delete result;
1825 initiate_result = -1;
1826 break;
1829 return initiate_result;
1830 #else
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,
1845 const void *act,
1846 int priority,
1847 int signal_number)
1849 return ACE_WIN32_Asynch_Write_Stream::write (message_block,
1850 bytes_to_write,
1851 act,
1852 priority,
1853 signal_number);
1857 ACE_WIN32_Asynch_Write_File::writev (ACE_Message_Block &message_block,
1858 size_t bytes_to_write,
1859 const void *act,
1860 int priority,
1861 int signal_number)
1863 return ACE_WIN32_Asynch_Write_Stream::writev (message_block,
1864 bytes_to_write,
1865 act,
1866 priority,
1867 signal_number);
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,
1876 ACE_HANDLE handle,
1877 const void *completion_key,
1878 ACE_Proactor *proactor)
1880 return ACE_WIN32_Asynch_Operation::open (handler_proxy,
1881 handle,
1882 completion_key,
1883 proactor);
1887 ACE_WIN32_Asynch_Write_File::cancel (void)
1889 return ACE_WIN32_Asynch_Operation::cancel ();
1892 ACE_Proactor *
1893 ACE_WIN32_Asynch_Write_File::proactor (void) const
1895 return ACE_WIN32_Asynch_Operation::proactor ();
1898 size_t
1899 ACE_WIN32_Asynch_Accept_Result::bytes_to_read (void) const
1901 return this->bytes_to_read_;
1904 ACE_Message_Block &
1905 ACE_WIN32_Asynch_Accept_Result::message_block (void) const
1907 return this->message_block_;
1910 ACE_HANDLE
1911 ACE_WIN32_Asynch_Accept_Result::listen_handle (void) const
1913 return this->listen_handle_;
1916 ACE_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,
1928 const void* act,
1929 ACE_HANDLE event,
1930 int priority,
1931 int signal_number)
1932 : ACE_Asynch_Result_Impl (),
1933 ACE_Asynch_Accept_Result_Impl (),
1934 ACE_WIN32_Asynch_Result (handler_proxy,
1935 act,
1936 event,
1939 priority,
1940 signal_number),
1941 bytes_to_read_ (bytes_to_read),
1942 message_block_ (message_block),
1943 listen_handle_ (listen_handle),
1944 accept_handle_ (accept_handle)
1948 void
1949 ACE_WIN32_Asynch_Accept_Result::complete (size_t bytes_transferred,
1950 int success,
1951 const void *completion_key,
1952 u_long error)
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 ();
1974 if (handler != 0)
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.
1985 size_t
1986 ACE_WIN32_Asynch_Accept_Result::bytes_transferred (void) const
1988 return ACE_WIN32_Asynch_Result::bytes_transferred ();
1991 const void *
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 ();
2003 const void *
2004 ACE_WIN32_Asynch_Accept_Result::completion_key (void) const
2006 return ACE_WIN32_Asynch_Result::completion_key ();
2009 u_long
2010 ACE_WIN32_Asynch_Accept_Result::error (void) const
2012 return ACE_WIN32_Asynch_Result::error ();
2015 ACE_HANDLE
2016 ACE_WIN32_Asynch_Accept_Result::event (void) const
2018 return ACE_WIN32_Asynch_Result::event ();
2021 u_long
2022 ACE_WIN32_Asynch_Accept_Result::offset (void) const
2024 return ACE_WIN32_Asynch_Result::offset ();
2027 u_long
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,
2062 const void *act,
2063 int priority,
2064 int signal_number,
2065 int addr_family)
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
2069 // the caller.
2070 size_t address_size =
2071 #if defined (ACE_HAS_IPV6)
2072 addr_family == AF_INET ? sizeof (sockaddr_in) : sizeof (sockaddr_in6);
2073 #else
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);
2082 // WIN Specific.
2084 // AcceptEx API limits us to DWORD range.
2085 if (bytes_to_read > MAXDWORD)
2087 errno = ERANGE;
2088 return -1;
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,
2097 SOCK_STREAM,
2099 if (accept_handle == ACE_INVALID_HANDLE)
2101 if (ACE::debug ())
2103 ACE_DEBUG ((LM_ERROR,
2104 ACE_TEXT ("%p\n"),
2105 ACE_TEXT ("ACE_OS::socket")));
2107 return -1;
2109 else
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_,
2118 this->handle_,
2119 accept_handle,
2120 message_block,
2121 bytes_to_read,
2122 act,
2123 this->win32_proactor_->get_handle (),
2124 priority,
2125 signal_number),
2126 -1);
2128 u_long bytes_read;
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),
2137 &bytes_read,
2138 result);
2139 if (initiate_result == 1)
2140 // Immediate success: the OVERLAPPED will still get queued.
2141 return 1;
2143 // If initiate failed, check for a bad error.
2144 ACE_OS::set_errno_to_last_error ();
2145 switch (errno)
2147 case ERROR_IO_PENDING:
2148 // The IO will complete proactively: the OVERLAPPED will still
2149 // get queued.
2150 return 0;
2152 default:
2153 // Something else went wrong: the OVERLAPPED will not get
2154 // queued.
2156 if (close_accept_handle == 1)
2157 // Close the newly created socket
2158 ACE_OS::closesocket (accept_handle);
2160 // Cleanup dynamically allocated Asynch_Result.
2161 delete result;
2163 if (ACE::debug ())
2165 ACE_DEBUG ((LM_ERROR,
2166 ACE_TEXT ("%p\n"),
2167 ACE_TEXT ("AcceptEx")));
2169 return -1;
2171 #else
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,
2193 ACE_HANDLE handle,
2194 const void *completion_key,
2195 ACE_Proactor *proactor)
2197 return ACE_WIN32_Asynch_Operation::open (handler_proxy,
2198 handle,
2199 completion_key,
2200 proactor);
2204 ACE_WIN32_Asynch_Accept::cancel (void)
2206 return ACE_WIN32_Asynch_Operation::cancel ();
2209 ACE_Proactor *
2210 ACE_WIN32_Asynch_Accept::proactor (void) const
2212 return ACE_WIN32_Asynch_Operation::proactor ();
2215 // *********************************************************************
2217 ACE_HANDLE
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,
2232 const void* act,
2233 ACE_HANDLE event,
2234 int priority,
2235 int signal_number)
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)
2245 void
2246 ACE_WIN32_Asynch_Connect_Result::complete (size_t bytes_transferred,
2247 int success,
2248 const void *completion_key,
2249 u_long error)
2251 // Copy the data.
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 ();
2262 if (handler != 0)
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.
2273 size_t
2274 ACE_WIN32_Asynch_Connect_Result::bytes_transferred (void) const
2276 return ACE_WIN32_Asynch_Result::bytes_transferred ();
2279 const void *
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 ();
2291 const void *
2292 ACE_WIN32_Asynch_Connect_Result::completion_key (void) const
2294 return ACE_WIN32_Asynch_Result::completion_key ();
2297 u_long
2298 ACE_WIN32_Asynch_Connect_Result::error (void) const
2300 return ACE_WIN32_Asynch_Result::error ();
2303 ACE_HANDLE
2304 ACE_WIN32_Asynch_Connect_Result::event (void) const
2306 return ACE_WIN32_Asynch_Result::event ();
2309 u_long
2310 ACE_WIN32_Asynch_Connect_Result::offset (void) const
2312 return ACE_WIN32_Asynch_Result::offset ();
2315 u_long
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),
2345 flg_open_ (false)
2349 ACE_WIN32_Asynch_Connect::~ACE_WIN32_Asynch_Connect (void)
2351 this->close ();
2352 this->reactor (0); // to avoid purge_pending_notifications
2355 ACE_Proactor *
2356 ACE_WIN32_Asynch_Connect::proactor (void) const
2358 return ACE_WIN32_Asynch_Operation::proactor ();
2361 ACE_HANDLE
2362 ACE_WIN32_Asynch_Connect::get_handle (void) const
2365 ACE_ASSERT (0);
2366 return ACE_INVALID_HANDLE;
2369 void
2370 ACE_WIN32_Asynch_Connect::set_handle (ACE_HANDLE)
2372 ACE_ASSERT (0) ;
2376 ACE_WIN32_Asynch_Connect::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
2377 ACE_HANDLE,
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")),
2389 -1);
2391 //int result =
2392 ACE_WIN32_Asynch_Operation::open (handler_proxy,
2393 ACE_INVALID_HANDLE,
2394 completion_key,
2395 proactor);
2397 // Ignore result as we pass ACE_INVALID_HANDLE
2398 //if (result == -1)
2399 // return result;
2401 this->flg_open_ = true;
2403 return 0;
2407 ACE_WIN32_Asynch_Connect::connect (ACE_HANDLE connect_handle,
2408 const ACE_Addr & remote_sap,
2409 const ACE_Addr & local_sap,
2410 int reuse_addr,
2411 const void *act,
2412 int priority,
2413 int signal_number)
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")),
2421 -1);
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_,
2428 connect_handle,
2429 act,
2430 this->win32_proactor_->get_handle (),
2431 priority,
2432 signal_number),
2433 -1);
2435 int rc = connect_i (result,
2436 remote_sap,
2437 local_sap,
2438 reuse_addr);
2440 // update handle
2441 connect_handle = result->connect_handle ();
2443 if (rc != 0)
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,
2464 this,
2465 ACE_Event_Handler::CONNECT_MASK,
2466 0)) // not to suspend after register
2468 result = 0;
2470 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
2471 this->result_map_.unbind (connect_handle, result);
2473 if (result != 0)
2475 result->set_error (EFAULT);
2476 this->post_result (result, true);
2480 return 0;
2483 int ACE_WIN32_Asynch_Connect::post_result (ACE_WIN32_Asynch_Connect_Result * result,
2484 bool post_enable)
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)
2493 return 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")));
2500 else
2502 // There was no call to post_completion() so manually delete result.
2503 delete result;
2506 if (handle != ACE_INVALID_HANDLE)
2507 ACE_OS::closesocket (handle);
2509 return -1;
2512 // connect_i
2513 // return code :
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,
2522 int reuse_addr)
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,
2531 SOCK_STREAM,
2534 // save it
2535 result->connect_handle (handle);
2536 if (handle == ACE_INVALID_HANDLE)
2538 result->set_error (errno);
2539 ACE_ERROR_RETURN
2540 ((LM_ERROR,
2541 ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"),
2542 ACE_TEXT ("socket")),
2543 -1);
2546 // Reuse the address
2547 int one = 1;
2548 if (protocol_family != PF_UNIX &&
2549 reuse_addr != 0 &&
2550 ACE_OS::setsockopt (handle,
2551 SOL_SOCKET,
2552 SO_REUSEADDR,
2553 (const char*) &one,
2554 sizeof one) == -1)
2556 result->set_error (errno);
2557 ACE_ERROR_RETURN
2558 ((LM_ERROR,
2559 ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"),
2560 ACE_TEXT ("setsockopt")),
2561 -1);
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);
2572 ACE_ERROR_RETURN
2573 ((LM_ERROR,
2574 ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"),
2575 ACE_TEXT ("bind")),
2576 -1);
2580 // set non blocking mode
2581 if (ACE::set_flags (handle, ACE_NONBLOCK) != 0)
2583 result->set_error (errno);
2584 ACE_ERROR_RETURN
2585 ((LM_ERROR,
2586 ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"),
2587 ACE_TEXT ("set_flags")),
2588 -1);
2591 for (;;)
2593 int rc = ACE_OS::connect
2594 (handle,
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
2603 if (errno == EINTR)
2604 continue;
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");
2631 int retval = 0;
2633 MAP_MANAGER::ITERATOR iter (result_map_);
2634 MAP_MANAGER::ENTRY * me = 0;
2636 set.reset ();
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 ();
2652 return retval;
2656 ACE_WIN32_Asynch_Connect::cancel (void)
2658 ACE_TRACE ("ACE_WIN32_Asynch_Connect::cancel");
2660 int rc = -1 ; // ERRORS
2662 ACE_Handle_Set set;
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_)
2675 return rc;
2677 ACE_Asynch_Pseudo_Task & task =
2678 this->win32_proactor_->get_asynch_pseudo_task ();
2680 task.remove_io_handler (set);
2681 return rc;
2685 ACE_WIN32_Asynch_Connect::close (void)
2687 ACE_TRACE ("ACE_WIN32_Asynch_Connect::close");
2689 ACE_Handle_Set set;
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;
2699 return 0;
2702 ACE_Asynch_Pseudo_Task & task =
2703 this->win32_proactor_->get_asynch_pseudo_task ();
2705 task.remove_io_handler (set);
2706 return 0;
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
2733 return -1;
2736 int sockerror = 0 ;
2737 int lsockerror = sizeof sockerror;
2739 ACE_OS::getsockopt (fd,
2740 SOL_SOCKET,
2741 SO_ERROR,
2742 (char*) & sockerror,
2743 & lsockerror);
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_);
2755 return 0;
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
2773 return -1;
2776 result->set_bytes_transferred (0);
2777 result->set_error (ERROR_OPERATION_ABORTED);
2778 this->post_result (result, this->flg_open_);
2780 return 0;
2783 // *********************************************************************
2785 ACE_HANDLE
2786 ACE_WIN32_Asynch_Transmit_File_Result::socket (void) const
2788 return this->socket_;
2791 ACE_HANDLE
2792 ACE_WIN32_Asynch_Transmit_File_Result::file (void) const
2794 return this->file_;
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_;
2803 size_t
2804 ACE_WIN32_Asynch_Transmit_File_Result::bytes_to_write (void) const
2806 return this->bytes_to_write_;
2809 size_t
2810 ACE_WIN32_Asynch_Transmit_File_Result::bytes_per_send (void) const
2812 return this->bytes_per_send_;
2815 u_long
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,
2823 ACE_HANDLE socket,
2824 ACE_HANDLE file,
2825 ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer,
2826 size_t bytes_to_write,
2827 u_long offset,
2828 u_long offset_high,
2829 size_t bytes_per_send,
2830 u_long flags,
2831 const void *act,
2832 ACE_HANDLE event,
2833 int priority,
2834 int signal_number)
2835 : ACE_Asynch_Result_Impl (),
2836 ACE_Asynch_Transmit_File_Result_Impl (),
2837 ACE_WIN32_Asynch_Result (handler_proxy,
2838 act,
2839 event,
2840 offset,
2841 offset_high,
2842 priority,
2843 signal_number),
2844 socket_ (socket),
2845 file_ (file),
2846 header_and_trailer_ (header_and_trailer),
2847 bytes_to_write_ (bytes_to_write),
2848 bytes_per_send_ (bytes_per_send),
2849 flags_ (flags)
2853 void
2854 ACE_WIN32_Asynch_Transmit_File_Result::complete (size_t bytes_transferred,
2855 int success,
2856 const void *completion_key,
2857 u_long error)
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 ();
2872 if (header != 0)
2873 header->rd_ptr (this->header_and_trailer_->header_bytes ());
2875 ACE_Message_Block *trailer = this->header_and_trailer_->trailer ();
2876 if (trailer != 0)
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 ();
2886 if (handler != 0)
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.
2897 size_t
2898 ACE_WIN32_Asynch_Transmit_File_Result::bytes_transferred (void) const
2900 return ACE_WIN32_Asynch_Result::bytes_transferred ();
2903 const void *
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 ();
2915 const void *
2916 ACE_WIN32_Asynch_Transmit_File_Result::completion_key (void) const
2918 return ACE_WIN32_Asynch_Result::completion_key ();
2921 u_long
2922 ACE_WIN32_Asynch_Transmit_File_Result::error (void) const
2924 return ACE_WIN32_Asynch_Result::error ();
2927 ACE_HANDLE
2928 ACE_WIN32_Asynch_Transmit_File_Result::event (void) const
2930 return ACE_WIN32_Asynch_Result::event ();
2933 u_long
2934 ACE_WIN32_Asynch_Transmit_File_Result::offset (void) const
2936 return ACE_WIN32_Asynch_Result::offset ();
2939 u_long
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,
2974 u_long offset,
2975 u_long offset_high,
2976 size_t bytes_per_send,
2977 u_long flags,
2978 const void *act,
2979 int priority,
2980 int signal_number)
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)
2987 errno = ERANGE;
2988 return -1;
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_,
2996 this->handle_,
2997 file,
2998 header_and_trailer,
2999 bytes_to_write,
3000 offset,
3001 offset_high,
3002 bytes_per_send,
3003 flags,
3004 act,
3005 this->win32_proactor_->get_handle (),
3006 priority,
3007 signal_number),
3008 -1);
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 (),
3016 result->file (),
3017 dword_bytes_to_write,
3018 dword_bytes_per_send,
3019 result,
3020 transmit_buffers,
3021 result->flags ());
3022 if (initiate_result == 1)
3023 // Immediate success: the OVERLAPPED will still get queued.
3024 return 1;
3026 // If initiate failed, check for a bad error.
3027 ACE_OS::set_errno_to_last_error ();
3028 switch (errno)
3030 case ERROR_IO_PENDING:
3031 // The IO will complete proactively: the OVERLAPPED will still
3032 // get queued.
3033 return 0;
3035 default:
3036 // Something else went wrong: the OVERLAPPED will not get
3037 // queued.
3039 // Cleanup dynamically allocated Asynch_Result
3040 delete result;
3042 if (ACE::debug ())
3044 ACE_DEBUG ((LM_ERROR,
3045 ACE_TEXT ("%p\n"),
3046 ACE_TEXT ("TransmitFile")));
3048 return -1;
3050 #else
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,
3075 ACE_HANDLE handle,
3076 const void *completion_key,
3077 ACE_Proactor *proactor)
3079 return ACE_WIN32_Asynch_Operation::open (handler_proxy,
3080 handle,
3081 completion_key,
3082 proactor);
3086 ACE_WIN32_Asynch_Transmit_File::cancel (void)
3088 return ACE_WIN32_Asynch_Operation::cancel ();
3091 ACE_Proactor *
3092 ACE_WIN32_Asynch_Transmit_File::proactor (void) const
3094 return ACE_WIN32_Asynch_Operation::proactor ();
3097 size_t
3098 ACE_WIN32_Asynch_Read_Dgram_Result::bytes_to_read (void) const
3100 return this->bytes_to_read_;
3103 ACE_Message_Block*
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
3123 return retVal;
3126 sockaddr *
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_;
3139 ACE_HANDLE
3140 ACE_WIN32_Asynch_Read_Dgram_Result::handle (void) const
3142 return this->handle_;
3145 size_t
3146 ACE_WIN32_Asynch_Read_Dgram_Result::bytes_transferred (void) const
3148 return ACE_WIN32_Asynch_Result::bytes_transferred ();
3151 const void *
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 ();
3163 const void *
3164 ACE_WIN32_Asynch_Read_Dgram_Result::completion_key (void) const
3166 return ACE_WIN32_Asynch_Result::completion_key ();
3169 u_long
3170 ACE_WIN32_Asynch_Read_Dgram_Result::error (void) const
3172 return ACE_WIN32_Asynch_Result::error ();
3175 ACE_HANDLE
3176 ACE_WIN32_Asynch_Read_Dgram_Result::event (void) const
3178 return ACE_WIN32_Asynch_Result::event ();
3181 u_long
3182 ACE_WIN32_Asynch_Read_Dgram_Result::offset (void) const
3184 return ACE_WIN32_Asynch_Result::offset ();
3187 u_long
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,
3213 ACE_HANDLE handle,
3214 ACE_Message_Block *message_block,
3215 size_t bytes_to_read,
3216 int flags,
3217 int protocol_family,
3218 const void* act,
3219 ACE_HANDLE event,
3220 int priority,
3221 int signal_number)
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),
3228 addr_len_ (0),
3229 flags_ (flags),
3230 handle_ (handle)
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);
3240 void
3241 ACE_WIN32_Asynch_Read_Dgram_Result::complete (size_t bytes_transferred,
3242 int success,
3243 const void *completion_key,
3244 u_long error)
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);
3255 mb = mb->cont ())
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 ();
3275 if (handler != 0)
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)
3290 ssize_t
3291 ACE_WIN32_Asynch_Read_Dgram::recv (ACE_Message_Block *message_block,
3292 size_t & number_of_bytes_recvd,
3293 int flags,
3294 int protocol_family,
3295 const void *act,
3296 int priority,
3297 int signal_number)
3299 number_of_bytes_recvd = 0;
3301 size_t bytes_to_read = 0;
3303 iovec iov[ACE_IOV_MAX];
3304 int iovcnt = 0;
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")),
3317 // -1);
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;
3329 else
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.
3338 if (msg_space > 0)
3339 iovcnt++;
3341 if (msg_space > 0) // Ran out of iovecs before msg_space exhausted
3343 errno = ERANGE;
3344 return -1;
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")),
3352 -1);
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_,
3358 this->handle_,
3359 message_block,
3360 bytes_to_read,
3361 flags,
3362 protocol_family,
3363 act,
3364 this->win32_proactor_->get_handle (),
3365 priority,
3366 signal_number),
3367 -1);
3369 // do the scatter/gather recv
3370 ssize_t initiate_result = ACE_OS::recvfrom (result->handle (),
3371 iov,
3372 iovcnt,
3373 number_of_bytes_recvd,
3374 result->flags_,
3375 result->saddr (),
3376 &(result->addr_len_),
3377 result,
3379 if (initiate_result == SOCKET_ERROR)
3381 // If initiate failed, check for a bad error.
3382 ACE_OS::set_errno_to_last_error ();
3383 switch (errno)
3385 case ERROR_IO_PENDING:
3386 // The IO will complete proactively: the OVERLAPPED will still
3387 // get queued.
3388 initiate_result = 0;
3389 break;
3391 default:
3392 // Something else went wrong: the OVERLAPPED will not get
3393 // queued.
3395 if (ACE::debug ())
3397 ACE_DEBUG ((LM_ERROR,
3398 ACE_TEXT ("%p\n"),
3399 ACE_TEXT ("WSARecvFrom")));
3402 delete result;
3403 initiate_result = -1;
3404 break;
3408 else
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,
3424 ACE_HANDLE handle,
3425 const void *completion_key,
3426 ACE_Proactor *proactor)
3428 return ACE_WIN32_Asynch_Operation::open (handler_proxy,
3429 handle,
3430 completion_key,
3431 proactor);
3435 ACE_WIN32_Asynch_Read_Dgram::cancel (void)
3437 return ACE_WIN32_Asynch_Operation::cancel ();
3440 ACE_Proactor *
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 //***********************************************
3455 size_t
3456 ACE_WIN32_Asynch_Write_Dgram_Result::bytes_to_write (void) const
3458 return this->bytes_to_write_;
3461 ACE_Message_Block*
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_;
3473 ACE_HANDLE
3474 ACE_WIN32_Asynch_Write_Dgram_Result::handle (void) const
3476 return this->handle_;
3479 size_t
3480 ACE_WIN32_Asynch_Write_Dgram_Result::bytes_transferred (void) const
3482 return ACE_WIN32_Asynch_Result::bytes_transferred ();
3485 const void *
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 ();
3497 const void *
3498 ACE_WIN32_Asynch_Write_Dgram_Result::completion_key (void) const
3500 return ACE_WIN32_Asynch_Result::completion_key ();
3503 u_long
3504 ACE_WIN32_Asynch_Write_Dgram_Result::error (void) const
3506 return ACE_WIN32_Asynch_Result::error ();
3509 ACE_HANDLE
3510 ACE_WIN32_Asynch_Write_Dgram_Result::event (void) const
3512 return ACE_WIN32_Asynch_Result::event ();
3515 u_long
3516 ACE_WIN32_Asynch_Write_Dgram_Result::offset (void) const
3518 return ACE_WIN32_Asynch_Result::offset ();
3521 u_long
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,
3547 ACE_HANDLE handle,
3548 ACE_Message_Block *message_block,
3549 size_t bytes_to_write,
3550 int flags,
3551 const void* act,
3552 ACE_HANDLE event,
3553 int priority,
3554 int signal_number)
3555 : ACE_Asynch_Result_Impl (),
3556 ACE_Asynch_Write_Dgram_Result_Impl(),
3557 ACE_WIN32_Asynch_Result (handler_proxy,
3558 act,
3559 event,
3562 priority,
3563 signal_number),
3564 bytes_to_write_ (bytes_to_write),
3565 message_block_ (message_block),
3566 flags_ (flags),
3567 handle_ (handle)
3571 void
3572 ACE_WIN32_Asynch_Write_Dgram_Result::complete (size_t bytes_transferred,
3573 int success,
3574 const void *completion_key,
3575 u_long error)
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);
3586 mb = mb->cont ())
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 ();
3603 if (handler != 0)
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)
3618 ssize_t
3619 ACE_WIN32_Asynch_Write_Dgram::send (ACE_Message_Block *message_block,
3620 size_t &number_of_bytes_sent,
3621 int flags,
3622 const ACE_Addr &addr,
3623 const void *act,
3624 int priority,
3625 int signal_number)
3627 number_of_bytes_sent = 0;
3629 size_t bytes_to_write = 0;
3631 iovec iov[ACE_IOV_MAX];
3632 int iovcnt = 0;
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;
3652 else
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.
3662 if (msg_len > 0)
3663 iovcnt++;
3666 while (msg_len > 0 && iovcnt < ACE_IOV_MAX);
3668 if (msg_len > 0) // Ran out of iovecs before msg_space exhausted
3670 errno = ERANGE;
3671 return -1;
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_,
3679 this->handle_,
3680 message_block,
3681 bytes_to_write,
3682 flags,
3683 act,
3684 this->win32_proactor_->get_handle (),
3685 priority,
3686 signal_number),
3687 -1);
3689 // do the scatter/gather send
3691 ssize_t initiate_result = ACE_OS::sendto (result->handle (),
3692 iov,
3693 iovcnt,
3694 number_of_bytes_sent,
3695 result->flags_,
3696 (sockaddr *) addr.get_addr (),
3697 addr.get_size(),
3698 result,
3702 if (initiate_result == SOCKET_ERROR)
3704 // If initiate failed, check for a bad error.
3705 ACE_OS::set_errno_to_last_error ();
3706 switch (errno)
3708 case ERROR_IO_PENDING:
3709 // The IO will complete proactively: the OVERLAPPED will still
3710 // get queued.
3711 initiate_result = 0;
3712 break;
3714 default:
3715 // Something else went wrong: the OVERLAPPED will not get
3716 // queued.
3718 if (ACE::debug ())
3720 ACE_DEBUG ((LM_ERROR,
3721 ACE_TEXT ("%p\n"),
3722 ACE_TEXT ("WSASendTo")));
3725 delete result;
3726 initiate_result = -1;
3727 break;
3731 else
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,
3747 ACE_HANDLE handle,
3748 const void *completion_key,
3749 ACE_Proactor *proactor)
3751 return ACE_WIN32_Asynch_Operation::open (handler_proxy,
3752 handle,
3753 completion_key,
3754 proactor);
3758 ACE_WIN32_Asynch_Write_Dgram::cancel (void)
3760 return ACE_WIN32_Asynch_Operation::cancel ();
3763 ACE_Proactor *
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 */