Removed ACE_HAS_BSTRING, not used
[ACE_TAO.git] / ACE / ace / POSIX_Asynch_IO.cpp
blob2b29515b934fac14b2ec3c468e317fd2f2ba7b95
1 #include "ace/POSIX_Asynch_IO.h"
3 #if defined (ACE_HAS_AIO_CALLS)
5 #include "ace/Flag_Manip.h"
6 #include "ace/Proactor.h"
7 #include "ace/Message_Block.h"
8 #include "ace/INET_Addr.h"
9 #include "ace/Asynch_Pseudo_Task.h"
10 #include "ace/POSIX_Proactor.h"
11 #include "ace/OS_NS_errno.h"
12 #include "ace/OS_NS_sys_socket.h"
13 #include "ace/OS_NS_sys_stat.h"
15 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
17 size_t
18 ACE_POSIX_Asynch_Result::bytes_transferred (void) const
20 return this->bytes_transferred_;
23 void
24 ACE_POSIX_Asynch_Result::set_bytes_transferred (size_t nbytes)
26 this->bytes_transferred_= nbytes;
29 const void *
30 ACE_POSIX_Asynch_Result::act (void) const
32 return this->act_;
35 int
36 ACE_POSIX_Asynch_Result::success (void) const
38 return this->success_;
41 const void *
42 ACE_POSIX_Asynch_Result::completion_key (void) const
44 return this->completion_key_;
47 u_long
48 ACE_POSIX_Asynch_Result::error (void) const
50 return this->error_;
53 void
54 ACE_POSIX_Asynch_Result::set_error (u_long errcode)
56 this->error_=errcode;
58 ACE_HANDLE
59 ACE_POSIX_Asynch_Result::event (void) const
61 return ACE_INVALID_HANDLE;
64 u_long
65 ACE_POSIX_Asynch_Result::offset (void) const
67 return this->aio_offset;
70 u_long
71 ACE_POSIX_Asynch_Result::offset_high (void) const
74 // @@ Support aiocb64??
76 ACE_NOTSUP_RETURN (0);
79 int
80 ACE_POSIX_Asynch_Result::priority (void) const
82 return this->aio_reqprio;
85 int
86 ACE_POSIX_Asynch_Result::signal_number (void) const
88 return this->aio_sigevent.sigev_signo;
91 int
92 ACE_POSIX_Asynch_Result::post_completion (ACE_Proactor_Impl *proactor_impl)
94 // Get to the platform specific implementation.
95 ACE_POSIX_Proactor *posix_proactor = dynamic_cast<ACE_POSIX_Proactor *> (proactor_impl);
97 if (posix_proactor == 0)
98 ACELIB_ERROR_RETURN ((LM_ERROR, "Dynamic cast to POSIX Proactor failed\n"), -1);
100 // Post myself.
101 return posix_proactor->post_completion (this);
104 ACE_POSIX_Asynch_Result::~ACE_POSIX_Asynch_Result (void)
108 ACE_POSIX_Asynch_Result::ACE_POSIX_Asynch_Result
109 (const ACE_Handler::Proxy_Ptr &handler_proxy,
110 const void* act,
111 ACE_HANDLE /* event */, // Event is not used on POSIX.
112 u_long offset,
113 u_long offset_high,
114 int priority,
115 int signal_number)
116 : handler_proxy_ (handler_proxy),
117 act_ (act),
118 bytes_transferred_ (0),
119 success_ (0),
120 completion_key_ (0),
121 error_ (0)
123 aio_offset = offset;
124 aio_reqprio = priority;
125 aio_sigevent.sigev_signo = signal_number;
128 // @@ Support offset_high with aiocb64.
130 ACE_UNUSED_ARG (offset_high);
132 // Other fields in the <aiocb> will be initialized by the
133 // subclasses.
136 // ****************************************************************
139 ACE_POSIX_Asynch_Operation::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
140 ACE_HANDLE handle,
141 const void * /* completion_key */,
142 ACE_Proactor *proactor)
144 this->proactor_ = proactor;
145 this->handler_proxy_ = handler_proxy;
146 this->handle_ = handle;
148 // Grab the handle from the <handler> if <handle> is invalid
149 if (this->handle_ == ACE_INVALID_HANDLE)
151 ACE_Handler *handler = handler_proxy.get ()->handler ();
152 if (handler != 0)
153 this->handle_ = handler->handle ();
155 if (this->handle_ == ACE_INVALID_HANDLE)
156 return -1;
158 #if 0
159 // @@ If <proactor> is 0, let us not bother about getting this
160 // Proactor, we have already got the specific implementation
161 // Proactor.
163 // If no proactor was passed
164 if (this->proactor_ == 0)
166 // Grab the proactor from the <Service_Config> if
167 // <handler->proactor> is zero
168 this->proactor_ = this->handler_->proactor ();
169 if (this->proactor_ == 0)
170 this->proactor_ = ACE_Proactor::instance();
172 #endif /* 0 */
174 return 0;
178 ACE_POSIX_Asynch_Operation::cancel (void)
180 if (!posix_proactor_)
181 return -1;
182 return posix_proactor_->cancel_aio (this->handle_);
185 ACE_Proactor *
186 ACE_POSIX_Asynch_Operation::proactor (void) const
188 return this->proactor_;
191 ACE_POSIX_Proactor *
192 ACE_POSIX_Asynch_Operation::posix_proactor (void) const
194 return this->posix_proactor_;
197 ACE_POSIX_Asynch_Operation::~ACE_POSIX_Asynch_Operation (void)
201 ACE_POSIX_Asynch_Operation::ACE_POSIX_Asynch_Operation (ACE_POSIX_Proactor *posix_proactor)
202 : posix_proactor_ (posix_proactor),
203 handle_ (ACE_INVALID_HANDLE)
207 // *********************************************************************
209 size_t
210 ACE_POSIX_Asynch_Read_Stream_Result::bytes_to_read (void) const
212 return this->aio_nbytes;
215 ACE_Message_Block &
216 ACE_POSIX_Asynch_Read_Stream_Result::message_block (void) const
218 return this->message_block_;
221 ACE_HANDLE
222 ACE_POSIX_Asynch_Read_Stream_Result::handle (void) const
224 return this->aio_fildes;
227 ACE_POSIX_Asynch_Read_Stream_Result::ACE_POSIX_Asynch_Read_Stream_Result
228 (const ACE_Handler::Proxy_Ptr &handler_proxy,
229 ACE_HANDLE handle,
230 ACE_Message_Block &message_block,
231 size_t bytes_to_read,
232 const void* act,
233 ACE_HANDLE event,
234 int priority,
235 int signal_number)
236 : ACE_POSIX_Asynch_Result
237 (handler_proxy, act, event, 0, 0, priority, signal_number),
238 message_block_ (message_block)
240 this->aio_fildes = handle;
241 this->aio_buf = message_block.wr_ptr ();
242 this->aio_nbytes = bytes_to_read;
245 void
246 ACE_POSIX_Asynch_Read_Stream_Result::complete (size_t bytes_transferred,
247 int success,
248 const void *completion_key,
249 u_long error)
251 this->bytes_transferred_ = bytes_transferred;
252 this->success_ = success;
253 this->completion_key_ = completion_key;
254 this->error_ = error;
256 // <errno> is available in the aiocb.
257 ACE_UNUSED_ARG (error);
259 // Appropriately move the pointers in the message block.
260 this->message_block_.wr_ptr (bytes_transferred);
262 // Create the interface result class.
263 ACE_Asynch_Read_Stream::Result result (this);
265 // Call the application handler.
266 ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
267 if (handler != 0)
268 handler->handle_read_stream (result);
271 ACE_POSIX_Asynch_Read_Stream_Result::~ACE_POSIX_Asynch_Read_Stream_Result (void)
275 // ************************************************************
277 ACE_POSIX_Asynch_Read_Stream::ACE_POSIX_Asynch_Read_Stream (ACE_POSIX_Proactor *posix_proactor)
278 : ACE_POSIX_Asynch_Operation (posix_proactor)
283 ACE_POSIX_Asynch_Read_Stream::read (ACE_Message_Block &message_block,
284 size_t bytes_to_read,
285 const void *act,
286 int priority,
287 int signal_number)
289 size_t space = message_block.space ();
290 if (bytes_to_read > space)
291 bytes_to_read=space;
293 if (bytes_to_read == 0)
295 errno = ENOSPC;
296 return -1;
299 // Create the Asynch_Result.
300 ACE_POSIX_Asynch_Read_Stream_Result *result = 0;
301 ACE_POSIX_Proactor *proactor = this->posix_proactor ();
302 ACE_NEW_RETURN (result,
303 ACE_POSIX_Asynch_Read_Stream_Result (this->handler_proxy_,
304 this->handle_,
305 message_block,
306 bytes_to_read,
307 act,
308 proactor->get_handle (),
309 priority,
310 signal_number),
311 -1);
313 int return_val = proactor->start_aio (result, ACE_POSIX_Proactor::ACE_OPCODE_READ);
314 if (return_val == -1)
315 delete result;
317 return return_val;
320 ACE_POSIX_Asynch_Read_Stream::~ACE_POSIX_Asynch_Read_Stream (void)
324 // *********************************************************************
326 size_t
327 ACE_POSIX_Asynch_Write_Stream_Result::bytes_to_write (void) const
329 return this->aio_nbytes;
332 ACE_Message_Block &
333 ACE_POSIX_Asynch_Write_Stream_Result::message_block (void) const
335 return this->message_block_;
338 ACE_HANDLE
339 ACE_POSIX_Asynch_Write_Stream_Result::handle (void) const
341 return this->aio_fildes;
344 ACE_POSIX_Asynch_Write_Stream_Result::ACE_POSIX_Asynch_Write_Stream_Result
345 (const ACE_Handler::Proxy_Ptr &handler_proxy,
346 ACE_HANDLE handle,
347 ACE_Message_Block &message_block,
348 size_t bytes_to_write,
349 const void* act,
350 ACE_HANDLE event,
351 int priority,
352 int signal_number)
353 : ACE_POSIX_Asynch_Result
354 (handler_proxy, act, event, 0, 0, priority, signal_number),
355 message_block_ (message_block)
357 this->aio_fildes = handle;
358 this->aio_buf = message_block.rd_ptr ();
359 this->aio_nbytes = bytes_to_write;
362 void
363 ACE_POSIX_Asynch_Write_Stream_Result::complete (size_t bytes_transferred,
364 int success,
365 const void *completion_key,
366 u_long error)
368 // Get all the data copied.
369 this->bytes_transferred_ = bytes_transferred;
370 this->success_ = success;
371 this->completion_key_ = completion_key;
372 this->error_ = error;
374 // <errno> is available in the aiocb.
375 ACE_UNUSED_ARG (error);
377 // Appropriately move the pointers in the message block.
378 this->message_block_.rd_ptr (bytes_transferred);
380 // Create the interface result class.
381 ACE_Asynch_Write_Stream::Result result (this);
383 // Call the application handler.
384 ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
385 if (handler != 0)
386 handler->handle_write_stream (result);
389 ACE_POSIX_Asynch_Write_Stream_Result::~ACE_POSIX_Asynch_Write_Stream_Result (void)
393 // *********************************************************************
395 ACE_POSIX_Asynch_Write_Stream::ACE_POSIX_Asynch_Write_Stream (ACE_POSIX_Proactor *posix_proactor)
396 : ACE_POSIX_Asynch_Operation (posix_proactor)
401 ACE_POSIX_Asynch_Write_Stream::write (ACE_Message_Block &message_block,
402 size_t bytes_to_write,
403 const void *act,
404 int priority,
405 int signal_number)
407 size_t len = message_block.length ();
408 if (bytes_to_write > len)
409 bytes_to_write = len;
411 if (bytes_to_write == 0)
412 ACELIB_ERROR_RETURN
413 ((LM_ERROR,
414 ACE_TEXT ("ACE_POSIX_Asynch_Write_Stream::write:")
415 ACE_TEXT ("Attempt to write 0 bytes\n")),
416 -1);
418 ACE_POSIX_Asynch_Write_Stream_Result *result = 0;
419 ACE_POSIX_Proactor *proactor = this->posix_proactor ();
420 ACE_NEW_RETURN (result,
421 ACE_POSIX_Asynch_Write_Stream_Result (this->handler_proxy_,
422 this->handle_,
423 message_block,
424 bytes_to_write,
425 act,
426 proactor->get_handle (),
427 priority,
428 signal_number),
429 -1);
431 int return_val = proactor->start_aio (result, ACE_POSIX_Proactor::ACE_OPCODE_WRITE);
432 if (return_val == -1)
433 delete result;
435 return return_val;
438 ACE_POSIX_Asynch_Write_Stream::~ACE_POSIX_Asynch_Write_Stream (void)
442 // *********************************************************************
444 ACE_POSIX_Asynch_Read_File_Result::ACE_POSIX_Asynch_Read_File_Result
445 (const ACE_Handler::Proxy_Ptr &handler_proxy,
446 ACE_HANDLE handle,
447 ACE_Message_Block &message_block,
448 size_t bytes_to_read,
449 const void* act,
450 u_long offset,
451 u_long offset_high,
452 ACE_HANDLE event,
453 int priority,
454 int signal_number)
455 : ACE_POSIX_Asynch_Read_Stream_Result (handler_proxy,
456 handle,
457 message_block,
458 bytes_to_read,
459 act,
460 event,
461 priority,
462 signal_number)
464 this->aio_offset = offset;
466 // @@ Use aiocb64??
468 ACE_UNUSED_ARG (offset_high);
471 void
472 ACE_POSIX_Asynch_Read_File_Result::complete (size_t bytes_transferred,
473 int success,
474 const void *completion_key,
475 u_long error)
477 // Copy all the data.
478 this->bytes_transferred_ = bytes_transferred;
479 this->success_ = success;
480 this->completion_key_ = completion_key;
481 this->error_ = error;
483 // <errno> is available in the aiocb.
484 ACE_UNUSED_ARG (error);
486 // Appropriately move the pointers in the message block.
487 this->message_block_.wr_ptr (bytes_transferred);
489 // Create the interface result class.
490 ACE_Asynch_Read_File::Result result (this);
492 // Call the application handler.
493 ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
494 if (handler != 0)
495 handler->handle_read_file (result);
498 ACE_POSIX_Asynch_Read_File_Result::~ACE_POSIX_Asynch_Read_File_Result (void)
502 // *********************************************************************
504 ACE_POSIX_Asynch_Read_File::ACE_POSIX_Asynch_Read_File (ACE_POSIX_Proactor *posix_proactor)
505 : ACE_POSIX_Asynch_Read_Stream (posix_proactor)
510 ACE_POSIX_Asynch_Read_File::read (ACE_Message_Block &message_block,
511 size_t bytes_to_read,
512 u_long offset,
513 u_long offset_high,
514 const void *act,
515 int priority,
516 int signal_number)
518 size_t space = message_block.space ();
519 if ( bytes_to_read > space )
520 bytes_to_read=space;
522 if ( bytes_to_read == 0 )
523 ACELIB_ERROR_RETURN
524 ((LM_ERROR,
525 ACE_TEXT ("ACE_POSIX_Asynch_Read_File::read:")
526 ACE_TEXT ("Attempt to read 0 bytes or no space in the message block\n")),
527 -1);
529 ACE_POSIX_Asynch_Read_File_Result *result = 0;
530 ACE_POSIX_Proactor *proactor = this->posix_proactor ();
531 ACE_NEW_RETURN (result,
532 ACE_POSIX_Asynch_Read_File_Result (this->handler_proxy_,
533 this->handle_,
534 message_block,
535 bytes_to_read,
536 act,
537 offset,
538 offset_high,
539 posix_proactor ()->get_handle (),
540 priority,
541 signal_number),
542 -1);
544 int return_val = proactor->start_aio (result, ACE_POSIX_Proactor::ACE_OPCODE_READ);
545 if (return_val == -1)
546 delete result;
548 return return_val;
551 ACE_POSIX_Asynch_Read_File::~ACE_POSIX_Asynch_Read_File (void)
556 ACE_POSIX_Asynch_Read_File::read (ACE_Message_Block &message_block,
557 size_t bytes_to_read,
558 const void *act,
559 int priority,
560 int signal_number)
562 return ACE_POSIX_Asynch_Read_Stream::read (message_block,
563 bytes_to_read,
564 act,
565 priority,
566 signal_number);
569 // ************************************************************
571 ACE_POSIX_Asynch_Write_File_Result::ACE_POSIX_Asynch_Write_File_Result
572 (const ACE_Handler::Proxy_Ptr &handler_proxy,
573 ACE_HANDLE handle,
574 ACE_Message_Block &message_block,
575 size_t bytes_to_write,
576 const void* act,
577 u_long offset,
578 u_long offset_high,
579 ACE_HANDLE event,
580 int priority,
581 int signal_number)
582 : ACE_POSIX_Asynch_Write_Stream_Result (handler_proxy,
583 handle,
584 message_block,
585 bytes_to_write,
586 act,
587 event,
588 priority,
589 signal_number)
591 this->aio_offset = offset;
593 // @@ Support offset_high with aiocb64.
595 ACE_UNUSED_ARG (offset_high);
598 void
599 ACE_POSIX_Asynch_Write_File_Result::complete (size_t bytes_transferred,
600 int success,
601 const void *completion_key,
602 u_long error)
604 // Copy the data.
605 this->bytes_transferred_ = bytes_transferred;
606 this->success_ = success;
607 this->completion_key_ = completion_key;
608 this->error_ = error;
610 // <error> is available in <aio_resultp.aio_error>
611 ACE_UNUSED_ARG (error);
613 // Appropriately move the pointers in the message block.
614 this->message_block_.rd_ptr (bytes_transferred);
616 // Create the interface result class.
617 ACE_Asynch_Write_File::Result result (this);
619 // Call the application handler.
620 ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
621 if (handler != 0)
622 handler->handle_write_file (result);
625 ACE_POSIX_Asynch_Write_File_Result::~ACE_POSIX_Asynch_Write_File_Result (void)
629 // *********************************************************************
631 ACE_POSIX_Asynch_Write_File::ACE_POSIX_Asynch_Write_File (ACE_POSIX_Proactor *posix_proactor)
632 : ACE_POSIX_Asynch_Write_Stream (posix_proactor)
637 ACE_POSIX_Asynch_Write_File::write (ACE_Message_Block &message_block,
638 size_t bytes_to_write,
639 u_long offset,
640 u_long offset_high,
641 const void *act,
642 int priority,
643 int signal_number)
645 size_t len = message_block.length ();
646 if (bytes_to_write > len)
647 bytes_to_write = len;
649 if (bytes_to_write == 0)
650 ACELIB_ERROR_RETURN
651 ((LM_ERROR,
652 ACE_TEXT ("ACE_POSIX_Asynch_Write_File::write:")
653 ACE_TEXT ("Attempt to write 0 bytes\n")),
654 -1);
656 ACE_POSIX_Asynch_Write_File_Result *result = 0;
657 ACE_POSIX_Proactor *proactor = this->posix_proactor ();
658 ACE_NEW_RETURN (result,
659 ACE_POSIX_Asynch_Write_File_Result (this->handler_proxy_,
660 this->handle_,
661 message_block,
662 bytes_to_write,
663 act,
664 offset,
665 offset_high,
666 proactor->get_handle (),
667 priority,
668 signal_number),
669 -1);
671 int return_val = proactor->start_aio (result, ACE_POSIX_Proactor::ACE_OPCODE_WRITE);
672 if (return_val == -1)
673 delete result;
675 return return_val;
678 ACE_POSIX_Asynch_Write_File::~ACE_POSIX_Asynch_Write_File (void)
683 ACE_POSIX_Asynch_Write_File::write (ACE_Message_Block &message_block,
684 size_t bytes_to_write,
685 const void *act,
686 int priority,
687 int signal_number)
689 return ACE_POSIX_Asynch_Write_Stream::write (message_block,
690 bytes_to_write,
691 act,
692 priority,
693 signal_number);
696 // *********************************************************************
699 size_t
700 ACE_POSIX_Asynch_Accept_Result::bytes_to_read (void) const
702 return this->aio_nbytes;
705 ACE_Message_Block &
706 ACE_POSIX_Asynch_Accept_Result::message_block (void) const
708 return this->message_block_;
711 ACE_HANDLE
712 ACE_POSIX_Asynch_Accept_Result::listen_handle (void) const
714 return this->listen_handle_;
717 ACE_HANDLE
718 ACE_POSIX_Asynch_Accept_Result::accept_handle (void) const
720 return this->aio_fildes;
723 ACE_POSIX_Asynch_Accept_Result::ACE_POSIX_Asynch_Accept_Result
724 (const ACE_Handler::Proxy_Ptr &handler_proxy,
725 ACE_HANDLE listen_handle,
726 ACE_HANDLE accept_handle,
727 ACE_Message_Block &message_block,
728 size_t bytes_to_read,
729 const void* act,
730 ACE_HANDLE event,
731 int priority,
732 int signal_number)
734 : ACE_POSIX_Asynch_Result
735 (handler_proxy, act, event, 0, 0, priority, signal_number),
736 message_block_ (message_block),
737 listen_handle_ (listen_handle)
739 this->aio_fildes = accept_handle;
740 this->aio_nbytes = bytes_to_read;
743 void
744 ACE_POSIX_Asynch_Accept_Result::complete (size_t bytes_transferred,
745 int success,
746 const void *completion_key,
747 u_long error)
749 // Copy the data.
750 this->bytes_transferred_ = bytes_transferred;
751 this->success_ = success;
752 this->completion_key_ = completion_key;
753 this->error_ = error;
755 // Appropriately move the pointers in the message block.
756 this->message_block_.wr_ptr (bytes_transferred);
758 // Create the interface result class.
759 ACE_Asynch_Accept::Result result (this);
761 // Call the application handler.
762 ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
763 if (handler != 0)
764 handler->handle_accept (result);
767 ACE_POSIX_Asynch_Accept_Result::~ACE_POSIX_Asynch_Accept_Result (void)
771 // *********************************************************************
773 ACE_POSIX_Asynch_Accept::ACE_POSIX_Asynch_Accept (ACE_POSIX_Proactor * posix_proactor)
774 : ACE_POSIX_Asynch_Operation (posix_proactor),
775 flg_open_ (false)
779 ACE_POSIX_Asynch_Accept::~ACE_POSIX_Asynch_Accept (void)
781 this->close ();
782 this->reactor (0); // to avoid purge_pending_notifications
785 ACE_HANDLE
786 ACE_POSIX_Asynch_Accept::get_handle (void) const
788 return this->handle_;
791 void
792 ACE_POSIX_Asynch_Accept::set_handle (ACE_HANDLE handle)
794 ACE_ASSERT (handle_ == ACE_INVALID_HANDLE);
795 this->handle_ = handle;
799 ACE_POSIX_Asynch_Accept::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
800 ACE_HANDLE handle,
801 const void *completion_key,
802 ACE_Proactor *proactor)
804 ACE_TRACE ("ACE_POSIX_Asynch_Accept::open");
806 // if we are already opened,
807 // we could not create a new handler without closing the previous
808 if (this->flg_open_)
809 ACELIB_ERROR_RETURN ((LM_ERROR,
810 ACE_TEXT("%N:%l:ACE_POSIX_Asynch_Accept::open:")
811 ACE_TEXT("acceptor already open\n")),
812 -1);
814 if (-1 == ACE_POSIX_Asynch_Operation::open (handler_proxy,
815 handle,
816 completion_key,
817 proactor))
818 return -1;
820 flg_open_ = true;
822 ACE_Asynch_Pseudo_Task & task =
823 this->posix_proactor ()->get_asynch_pseudo_task ();
825 if (-1 == task.register_io_handler (this->get_handle(),
826 this,
827 ACE_Event_Handler::ACCEPT_MASK,
828 1)) // suspend after register
830 this->flg_open_= false;
831 this->handle_ = ACE_INVALID_HANDLE;
832 return -1 ;
835 return 0;
839 ACE_POSIX_Asynch_Accept::accept (ACE_Message_Block &message_block,
840 size_t bytes_to_read,
841 ACE_HANDLE accept_handle,
842 const void *act,
843 int priority,
844 int signal_number,
845 int addr_family)
847 ACE_TRACE ("ACE_POSIX_Asynch_Accept::accept");
849 if (!this->flg_open_)
850 ACELIB_ERROR_RETURN ((LM_ERROR,
851 ACE_TEXT("%N:%l:ACE_POSIX_Asynch_Accept::accept")
852 ACE_TEXT("acceptor was not opened before\n")),
853 -1);
855 // Sanity check: make sure that enough space has been allocated by
856 // the caller.
857 size_t address_size = sizeof (sockaddr_in);
858 #if defined (ACE_HAS_IPV6)
859 if (addr_family == AF_INET6)
860 address_size = sizeof (sockaddr_in6);
861 #else
862 ACE_UNUSED_ARG (addr_family);
863 #endif
864 size_t available_space = message_block.space ();
865 size_t space_needed = bytes_to_read + 2 * address_size;
867 if (available_space < space_needed)
869 ACE_OS::last_error (ENOBUFS);
870 return -1;
873 // Common code for both WIN and POSIX.
874 // Create future Asynch_Accept_Result
875 ACE_POSIX_Asynch_Accept_Result *result = 0;
876 ACE_NEW_RETURN (result,
877 ACE_POSIX_Asynch_Accept_Result (this->handler_proxy_,
878 this->handle_,
879 accept_handle,
880 message_block,
881 bytes_to_read,
882 act,
883 this->posix_proactor()->get_handle (),
884 priority,
885 signal_number),
886 -1);
888 // Enqueue result
890 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
891 if (this->result_queue_.enqueue_tail (result) == -1)
893 ACELIB_ERROR ((LM_ERROR,
894 ACE_TEXT ("ACE_POSIX_Asynch_Accept::accept: %p\n")
895 ACE_TEXT ("enqueue_tail")));
896 delete result; // to avoid memory leak
897 return -1;
900 if (this->result_queue_.size () > 1)
901 return 0;
904 // If this is the only item, then it means there the set was empty
905 // before. So enable the accept handle in the reactor.
907 ACE_Asynch_Pseudo_Task & task =
908 this->posix_proactor ()->get_asynch_pseudo_task ();
910 return task.resume_io_handler (this->get_handle ());
913 //@@ New method cancel_uncompleted
914 // It performs cancellation of all pending requests
916 // Parameter flg_notify can be
917 // 0 - don't send notifications about canceled accepts
918 // !0 - notify user about canceled accepts
919 // according POSIX standards we should receive notifications
920 // on canceled AIO requests
922 // Return value : number of cancelled requests
926 ACE_POSIX_Asynch_Accept::cancel_uncompleted (int flg_notify)
928 ACE_TRACE ("ACE_POSIX_Asynch_Accept::cancel_uncompleted");
930 int retval = 0;
932 for (; ; retval++)
934 ACE_POSIX_Asynch_Accept_Result* result = 0;
936 this->result_queue_.dequeue_head (result);
938 if (result == 0)
939 break;
941 if (this->flg_open_ == 0 || flg_notify == 0) //if we should not notify
942 delete result ; // we have to delete result
943 else //else notify as any cancelled AIO
945 // Store the new handle.
946 result->aio_fildes = ACE_INVALID_HANDLE ;
947 result->set_bytes_transferred (0);
948 result->set_error (ECANCELED);
950 if (this->posix_proactor ()->post_completion (result) == -1)
951 ACELIB_ERROR ((LM_ERROR,
952 ACE_TEXT("(%P | %t):%p\n"),
953 ACE_TEXT("ACE_POSIX_Asynch_Accept::")
954 ACE_TEXT("cancel_uncompleted")
958 return retval;
962 ACE_POSIX_Asynch_Accept::cancel (void)
964 ACE_TRACE ("ACE_POSIX_Asynch_Accept::cancel");
966 // Since this is not a real POSIX asynch I/O operation, we can't
967 // call ::aiocancel () or ACE_POSIX_Asynch_Operation::cancel ().
968 // We delegate real cancelation to cancel_uncompleted (1)
970 int rc = -1 ; // ERRORS
973 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
975 int num_cancelled = cancel_uncompleted (flg_open_);
977 if (num_cancelled == 0)
978 rc = 1 ; // AIO_ALLDONE
979 else if (num_cancelled > 0)
980 rc = 0 ; // AIO_CANCELED
982 if (!this->flg_open_)
983 return rc ;
986 ACE_Asynch_Pseudo_Task & task =
987 this->posix_proactor ()->get_asynch_pseudo_task ();
989 task.suspend_io_handler (this->get_handle());
990 return 0;
994 ACE_POSIX_Asynch_Accept::close ()
996 ACE_TRACE ("ACE_POSIX_Asynch_Accept::close");
998 // 1. It performs cancellation of all pending requests
999 // 2. Removes itself from Reactor ( ACE_Asynch_Pseudo_Task)
1000 // 3. close the socket
1002 // Parameter flg_notify can be
1003 // 0 - don't send notifications about canceled accepts
1004 // !0 - notify user about canceled accepts
1005 // according POSIX standards we should receive notifications
1006 // on canceled AIO requests
1008 // Return codes : 0 - OK ,
1009 // -1 - Errors
1012 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
1013 this->cancel_uncompleted (flg_open_);
1016 if (!this->flg_open_)
1018 if (this->handle_ != ACE_INVALID_HANDLE)
1020 ACE_OS::closesocket (this->handle_);
1021 this->handle_ = ACE_INVALID_HANDLE;
1023 return 0;
1026 if (this->handle_ == ACE_INVALID_HANDLE)
1027 return 0;
1029 ACE_Asynch_Pseudo_Task & task =
1030 this->posix_proactor ()->get_asynch_pseudo_task ();
1032 task.remove_io_handler (this->get_handle ());
1033 if (this->handle_ != ACE_INVALID_HANDLE)
1035 ACE_OS::closesocket (this->handle_);
1036 this->handle_ = ACE_INVALID_HANDLE;
1039 this->flg_open_ = false;
1041 return 0;
1045 ACE_POSIX_Asynch_Accept::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
1047 ACE_TRACE ("ACE_POSIX_Asynch_Accept::handle_close");
1049 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0));
1051 // handle_close is called in two cases:
1052 // 1. Pseudo task is closing (i.e. proactor destructor)
1053 // 2. The listen handle is closed (we don't have exclusive access to this)
1055 this->cancel_uncompleted (0);
1057 this->flg_open_ = false;
1058 this->handle_ = ACE_INVALID_HANDLE;
1059 return 0;
1063 ACE_POSIX_Asynch_Accept::handle_input (ACE_HANDLE /* fd */)
1065 ACE_TRACE ("ACE_POSIX_Asynch_Accept::handle_input");
1067 // An <accept> has been sensed on the <listen_handle>. We should be
1068 // able to just go ahead and do the <accept> now on this <fd>. This
1069 // should be the same as the <listen_handle>.
1071 ACE_POSIX_Asynch_Accept_Result* result = 0;
1074 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0));
1076 // Deregister this info pertaining to this accept call.
1077 if (this->result_queue_.dequeue_head (result) != 0)
1078 ACELIB_ERROR ((LM_ERROR,
1079 ACE_TEXT("%N:%l:(%P | %t):%p\n"),
1080 ACE_TEXT("ACE_POSIX_Asynch_Accept::handle_input:")
1081 ACE_TEXT( " dequeueing failed")));
1083 // Disable the handle in the reactor if no more accepts are pending.
1084 if (this->result_queue_.size () == 0)
1086 ACE_Asynch_Pseudo_Task & task =
1087 this->posix_proactor ()->get_asynch_pseudo_task ();
1089 task.suspend_io_handler (this->get_handle());
1093 // Issue <accept> now.
1094 // @@ We shouldnt block here since we have already done poll/select
1095 // thru reactor. But are we sure?
1097 ACE_HANDLE new_handle = ACE_OS::accept (this->handle_, 0, 0);
1099 if (result == 0) // there is nobody to notify
1101 ACE_OS::closesocket (new_handle);
1102 return 0;
1105 if (new_handle == ACE_INVALID_HANDLE)
1107 result->set_error (errno);
1108 ACELIB_ERROR ((LM_ERROR,
1109 ACE_TEXT("%N:%l:(%P | %t):%p\n"),
1110 ACE_TEXT("ACE_POSIX_Asynch_Accept::handle_input: ")
1111 ACE_TEXT("accept")));
1113 // Notify client as usual, "AIO" finished with errors
1116 // Store the new handle.
1117 result->aio_fildes = new_handle;
1119 // Notify the main process about this completion
1120 // Send the Result through the notification pipe.
1121 if (this->posix_proactor ()->post_completion (result) == -1)
1122 ACELIB_ERROR ((LM_ERROR,
1123 ACE_TEXT("Error:(%P | %t):%p\n"),
1124 ACE_TEXT("ACE_POSIX_Asynch_Accept::handle_input: ")
1125 ACE_TEXT(" <post_completion> failed")));
1127 return 0;
1130 // *********************************************************************
1132 ACE_HANDLE
1133 ACE_POSIX_Asynch_Connect_Result::connect_handle (void) const
1135 return this->aio_fildes;
1138 void ACE_POSIX_Asynch_Connect_Result::connect_handle (ACE_HANDLE handle)
1140 this->aio_fildes = handle;
1144 ACE_POSIX_Asynch_Connect_Result::ACE_POSIX_Asynch_Connect_Result
1145 (const ACE_Handler::Proxy_Ptr &handler_proxy,
1146 ACE_HANDLE connect_handle,
1147 const void* act,
1148 ACE_HANDLE event,
1149 int priority,
1150 int signal_number)
1151 : ACE_POSIX_Asynch_Result
1152 (handler_proxy, act, event, 0, 0, priority, signal_number)
1154 this->aio_fildes = connect_handle;
1155 this->aio_nbytes = 0;
1158 void
1159 ACE_POSIX_Asynch_Connect_Result::complete (size_t bytes_transferred,
1160 int success,
1161 const void *completion_key,
1162 u_long error)
1164 // Copy the data.
1165 this->bytes_transferred_ = bytes_transferred;
1166 this->success_ = success;
1167 this->completion_key_ = completion_key;
1168 this->error_ = error;
1170 // Create the interface result class.
1171 ACE_Asynch_Connect::Result result (this);
1173 // Call the application handler.
1174 ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
1175 if (handler != 0)
1176 handler->handle_connect (result);
1179 ACE_POSIX_Asynch_Connect_Result::~ACE_POSIX_Asynch_Connect_Result (void)
1183 // *********************************************************************
1185 ACE_POSIX_Asynch_Connect::ACE_POSIX_Asynch_Connect (ACE_POSIX_Proactor * posix_proactor)
1186 : ACE_POSIX_Asynch_Operation (posix_proactor),
1187 flg_open_ (false)
1191 ACE_POSIX_Asynch_Connect::~ACE_POSIX_Asynch_Connect (void)
1193 this->close ();
1194 this->reactor(0); // to avoid purge_pending_notifications
1197 ACE_HANDLE
1198 ACE_POSIX_Asynch_Connect::get_handle (void) const
1200 ACE_ASSERT (0);
1201 return ACE_INVALID_HANDLE;
1204 void
1205 ACE_POSIX_Asynch_Connect::set_handle (ACE_HANDLE)
1207 ACE_ASSERT (0) ;
1211 ACE_POSIX_Asynch_Connect::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
1212 ACE_HANDLE handle,
1213 const void *completion_key,
1214 ACE_Proactor *proactor)
1216 ACE_TRACE ("ACE_POSIX_Asynch_Connect::open");
1218 if (this->flg_open_)
1219 return -1;
1221 //int result =
1222 ACE_POSIX_Asynch_Operation::open (handler_proxy,
1223 handle,
1224 completion_key,
1225 proactor);
1227 // Ignore result as we pass ACE_INVALID_HANDLE
1228 //if (result == -1)
1229 // return result;
1231 this->flg_open_ = true;
1233 return 0;
1237 ACE_POSIX_Asynch_Connect::connect (ACE_HANDLE connect_handle,
1238 const ACE_Addr & remote_sap,
1239 const ACE_Addr & local_sap,
1240 int reuse_addr,
1241 const void *act,
1242 int priority,
1243 int signal_number)
1245 ACE_TRACE ("ACE_POSIX_Asynch_Connect::connect");
1247 if (this->flg_open_ == 0)
1248 ACELIB_ERROR_RETURN ((LM_ERROR,
1249 ACE_TEXT("%N:%l:ACE_POSIX_Asynch_Connect::connect")
1250 ACE_TEXT("connector was not opened before\n")),
1251 -1);
1253 // Common code for both WIN and POSIX.
1254 // Create future Asynch_Connect_Result
1255 ACE_POSIX_Asynch_Connect_Result *result = 0;
1256 ACE_NEW_RETURN (result,
1257 ACE_POSIX_Asynch_Connect_Result (this->handler_proxy_,
1258 connect_handle,
1259 act,
1260 this->posix_proactor ()->get_handle (),
1261 priority,
1262 signal_number),
1263 -1);
1265 int rc = connect_i (result,
1266 remote_sap,
1267 local_sap,
1268 reuse_addr);
1270 // update handle
1271 connect_handle = result->connect_handle ();
1273 if (rc != 0)
1274 return post_result (result, true);
1276 // Enqueue result we will wait for completion
1278 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
1280 if (this->result_map_.bind (connect_handle, result) == -1)
1282 ACELIB_ERROR ((LM_ERROR,
1283 ACE_TEXT ("%N:%l:%p\n"),
1284 ACE_TEXT ("ACE_POSIX_Asynch_Connect::connect:")
1285 ACE_TEXT ("bind")));
1287 result->set_error (EFAULT);
1288 return post_result (result, true);
1292 ACE_Asynch_Pseudo_Task & task =
1293 this->posix_proactor ()->get_asynch_pseudo_task ();
1295 rc = task.register_io_handler (connect_handle,
1296 this,
1297 ACE_Event_Handler::CONNECT_MASK,
1298 0); // don't suspend after register
1299 if (rc < 0)
1302 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
1304 this->result_map_.unbind (connect_handle, result);
1306 if (result != 0)
1308 result->set_error (EFAULT);
1309 this->post_result (result, true);
1311 return -1;
1313 else
1314 result = 0;
1317 return 0;
1320 int ACE_POSIX_Asynch_Connect::post_result (ACE_POSIX_Asynch_Connect_Result * result,
1321 bool post_enable)
1323 if (this->flg_open_ && post_enable != 0)
1325 if (this->posix_proactor ()->post_completion (result) == 0)
1326 return 0;
1328 ACELIB_ERROR ((LM_ERROR,
1329 ACE_TEXT("Error:(%P | %t):%p\n"),
1330 ACE_TEXT("ACE_POSIX_Asynch_Connect::post_result: ")
1331 ACE_TEXT(" <post_completion> failed")));
1334 ACE_HANDLE handle = result->connect_handle ();
1336 if (handle != ACE_INVALID_HANDLE)
1337 ACE_OS::closesocket (handle);
1339 delete result;
1341 return -1;
1344 //connect_i
1345 // return code :
1346 // -1 errors before attempt to connect
1347 // 0 connect started
1348 // 1 connect finished ( may be unsuccessfully)
1351 ACE_POSIX_Asynch_Connect::connect_i (ACE_POSIX_Asynch_Connect_Result *result,
1352 const ACE_Addr & remote_sap,
1353 const ACE_Addr & local_sap,
1354 int reuse_addr)
1356 result->set_bytes_transferred (0);
1358 ACE_HANDLE handle = result->connect_handle ();
1360 if (handle == ACE_INVALID_HANDLE)
1362 int protocol_family = remote_sap.get_type ();
1364 handle = ACE_OS::socket (protocol_family,
1365 SOCK_STREAM,
1367 // save it
1368 result->connect_handle (handle);
1369 if (handle == ACE_INVALID_HANDLE)
1371 result->set_error (errno);
1372 ACELIB_ERROR_RETURN
1373 ((LM_ERROR,
1374 ACE_TEXT("ACE_POSIX_Asynch_Connect::connect_i: %p\n"),
1375 ACE_TEXT("socket")),
1376 -1);
1379 // Reuse the address
1380 int one = 1;
1381 if (protocol_family != PF_UNIX &&
1382 reuse_addr != 0 &&
1383 ACE_OS::setsockopt (handle,
1384 SOL_SOCKET,
1385 SO_REUSEADDR,
1386 (const char*) &one,
1387 sizeof one) == -1 )
1389 result->set_error (errno);
1390 ACELIB_ERROR_RETURN
1391 ((LM_ERROR,
1392 ACE_TEXT("ACE_POSIX_Asynch_Connect::connect_i: %p\n"),
1393 ACE_TEXT("setsockopt")),
1394 -1);
1398 if (local_sap != ACE_Addr::sap_any)
1400 sockaddr * laddr = reinterpret_cast<sockaddr *> (local_sap.get_addr ());
1401 size_t size = local_sap.get_size ();
1403 if (ACE_OS::bind (handle, laddr, size) == -1)
1405 result->set_error (errno);
1406 ACELIB_ERROR_RETURN
1407 ((LM_ERROR,
1408 ACE_TEXT("ACE_POSIX_Asynch_Connect::connect_i: %p\n"),
1409 ACE_TEXT("bind")),
1410 -1);
1414 // set non blocking mode
1415 if (ACE::set_flags (handle, ACE_NONBLOCK) != 0)
1417 result->set_error (errno);
1418 ACELIB_ERROR_RETURN
1419 ((LM_ERROR,
1420 ACE_TEXT("ACE_POSIX_Asynch_Connect::connect_i: %p\n")
1421 ACE_TEXT("set_flags")),
1422 -1);
1425 for (;;)
1427 int rc = ACE_OS::connect
1428 (handle,
1429 reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
1430 remote_sap.get_size ());
1431 if (rc < 0) // failure
1433 if (errno == EWOULDBLOCK || errno == EINPROGRESS)
1434 return 0; // connect started
1436 if (errno == EINTR)
1437 continue;
1439 result->set_error (errno);
1442 return 1 ; // connect finished
1445 ACE_NOTREACHED (return 0);
1449 //@@ New method cancel_uncompleted
1450 // It performs cancellation of all pending requests
1452 // Parameter flg_notify can be
1453 // 0 - don't send notifications about canceled accepts
1454 // !0 - notify user about canceled accepts
1455 // according POSIX standards we should receive notifications
1456 // on canceled AIO requests
1458 // Return value : number of cancelled requests
1462 ACE_POSIX_Asynch_Connect::cancel_uncompleted (bool flg_notify,
1463 ACE_Handle_Set & set)
1465 ACE_TRACE ("ACE_POSIX_Asynch_Connect::cancel_uncompleted");
1467 int retval = 0;
1469 MAP_MANAGER::ITERATOR iter (result_map_);
1470 MAP_MANAGER::ENTRY * me = 0;
1472 set.reset ();
1474 for (; iter.next (me) != 0; retval++ , iter.advance ())
1476 ACE_HANDLE handle = me->ext_id_;
1477 ACE_POSIX_Asynch_Connect_Result* result = me->int_id_ ;
1479 set.set_bit (handle);
1481 result->set_bytes_transferred (0);
1482 result->set_error (ECANCELED);
1483 this->post_result (result, flg_notify);
1486 result_map_.unbind_all ();
1488 return retval;
1492 ACE_POSIX_Asynch_Connect::cancel (void)
1494 ACE_TRACE ("ACE_POSIX_Asynch_Connect::cancel");
1496 // Since this is not a real asynch I/O operation, we can't just call
1497 // ::aiocancel () or ACE_POSIX_Asynch_Operation::cancel ().
1498 // Delegate real cancelation to cancel_uncompleted (1)
1500 int rc = -1 ; // ERRORS
1502 ACE_Handle_Set set;
1503 int num_cancelled = 0;
1505 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
1506 num_cancelled = cancel_uncompleted (flg_open_, set);
1508 if (num_cancelled == 0)
1509 rc = 1 ; // AIO_ALLDONE
1510 else if (num_cancelled > 0)
1511 rc = 0 ; // AIO_CANCELED
1513 if (!this->flg_open_)
1514 return rc ;
1516 ACE_Asynch_Pseudo_Task & task =
1517 this->posix_proactor ()->get_asynch_pseudo_task ();
1519 task.remove_io_handler (set);
1520 return rc;
1524 ACE_POSIX_Asynch_Connect::close (void)
1526 ACE_TRACE ("ACE_POSIX_Asynch_Connect::close");
1528 ACE_Handle_Set set ;
1529 int num_cancelled = 0;
1531 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
1532 num_cancelled = cancel_uncompleted (flg_open_, set);
1535 if (num_cancelled == 0 || !this->flg_open_)
1537 this->flg_open_ = false;
1538 return 0;
1541 ACE_Asynch_Pseudo_Task & task =
1542 this->posix_proactor ()->get_asynch_pseudo_task ();
1544 task.remove_io_handler (set);
1545 this->flg_open_ = false;
1547 return 0;
1551 ACE_POSIX_Asynch_Connect::handle_output (ACE_HANDLE fd)
1553 ACE_TRACE ("ACE_POSIX_Asynch_Connect::handle_output");
1555 ACE_POSIX_Asynch_Connect_Result* result = 0;
1558 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0));
1559 if (this->result_map_.unbind (fd, result) != 0) // not found
1560 return -1;
1563 int sockerror = 0 ;
1564 int lsockerror = sizeof sockerror;
1566 ACE_OS::getsockopt (fd,
1567 SOL_SOCKET,
1568 SO_ERROR,
1569 (char*) &sockerror,
1570 &lsockerror);
1572 result->set_bytes_transferred (0);
1573 result->set_error (sockerror);
1575 // This previously just did a "return -1" and let handle_close() clean
1576 // things up. However, this entire object may be gone as a result of
1577 // the application's completion handler, so don't count on 'this' being
1578 // legitimate on return from post_result().
1579 // remove_io_handler() contains flag DONT_CALL
1580 this->posix_proactor ()->get_asynch_pseudo_task ().remove_io_handler (fd);
1581 this->post_result (result, this->flg_open_);
1582 return 0;
1587 ACE_POSIX_Asynch_Connect::handle_close (ACE_HANDLE fd, ACE_Reactor_Mask)
1589 ACE_TRACE ("ACE_POSIX_Asynch_Connect::handle_close");
1591 ACE_Asynch_Pseudo_Task &task =
1592 this->posix_proactor ()->get_asynch_pseudo_task ();
1594 task.remove_io_handler (fd);
1596 ACE_POSIX_Asynch_Connect_Result* result = 0;
1599 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0));
1600 if (this->result_map_.unbind (fd, result) != 0) // not found
1601 return -1;
1604 result->set_bytes_transferred (0);
1605 result->set_error (ECANCELED);
1606 this->post_result (result, this->flg_open_);
1608 return 0;
1611 // *********************************************************************
1613 ACE_HANDLE
1614 ACE_POSIX_Asynch_Transmit_File_Result::socket (void) const
1616 return this->socket_;
1619 ACE_HANDLE
1620 ACE_POSIX_Asynch_Transmit_File_Result::file (void) const
1622 return this->aio_fildes;
1625 ACE_Asynch_Transmit_File::Header_And_Trailer *
1626 ACE_POSIX_Asynch_Transmit_File_Result::header_and_trailer (void) const
1628 return this->header_and_trailer_;
1631 size_t
1632 ACE_POSIX_Asynch_Transmit_File_Result::bytes_to_write (void) const
1634 return this->aio_nbytes;
1637 size_t
1638 ACE_POSIX_Asynch_Transmit_File_Result::bytes_per_send (void) const
1640 return this->bytes_per_send_;
1643 u_long
1644 ACE_POSIX_Asynch_Transmit_File_Result::flags (void) const
1646 return this->flags_;
1649 ACE_POSIX_Asynch_Transmit_File_Result::ACE_POSIX_Asynch_Transmit_File_Result
1650 (const ACE_Handler::Proxy_Ptr &handler_proxy,
1651 ACE_HANDLE socket,
1652 ACE_HANDLE file,
1653 ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer,
1654 size_t bytes_to_write,
1655 u_long offset,
1656 u_long offset_high,
1657 size_t bytes_per_send,
1658 u_long flags,
1659 const void *act,
1660 ACE_HANDLE event,
1661 int priority,
1662 int signal_number)
1663 : ACE_POSIX_Asynch_Result
1664 (handler_proxy, act, event, offset, offset_high, priority, signal_number),
1665 socket_ (socket),
1666 header_and_trailer_ (header_and_trailer),
1667 bytes_per_send_ (bytes_per_send),
1668 flags_ (flags)
1670 this->aio_fildes = file;
1671 this->aio_nbytes = bytes_to_write;
1674 void
1675 ACE_POSIX_Asynch_Transmit_File_Result::complete (size_t bytes_transferred,
1676 int success,
1677 const void *completion_key,
1678 u_long error)
1680 // Copy the data.
1681 this->bytes_transferred_ = bytes_transferred;
1682 this->success_ = success;
1683 this->completion_key_ = completion_key;
1684 this->error_ = error;
1686 // We will not do this because (a) the header and trailer blocks may
1687 // be the same message_blocks and (b) in cases of failures we have
1688 // no idea how much of what (header, data, trailer) was sent.
1690 if (this->success_ && this->header_and_trailer_ != 0)
1692 ACE_Message_Block *header = this->header_and_trailer_->header ();
1693 if (header != 0)
1694 header->rd_ptr (this->header_and_trailer_->header_bytes ());
1696 ACE_Message_Block *trailer = this->header_and_trailer_->trailer ();
1697 if (trailer != 0)
1698 trailer->rd_ptr (this->header_and_trailer_->trailer_bytes ());
1702 // Create the interface result class.
1703 ACE_Asynch_Transmit_File::Result result (this);
1705 // Call the application handler.
1706 ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
1707 if (handler != 0)
1708 handler->handle_transmit_file (result);
1711 ACE_POSIX_Asynch_Transmit_File_Result::~ACE_POSIX_Asynch_Transmit_File_Result (void)
1716 // *********************************************************************
1719 * @class ACE_POSIX_Asynch_Transmit_Handler
1721 * @brief Auxillary handler for doing <Asynch_Transmit_File> in
1722 * Unix. <ACE_POSIX_Asynch_Transmit_File> internally uses this.
1724 * This is a helper class for implementing
1725 * <ACE_POSIX_Asynch_Transmit_File> in Unix systems.
1727 class ACE_Export ACE_POSIX_Asynch_Transmit_Handler : public ACE_Handler
1729 public:
1730 /// Constructor. Result pointer will have all the information to do
1731 /// the file transmission (socket, file, application handler, bytes
1732 /// to write).
1733 ACE_POSIX_Asynch_Transmit_Handler (ACE_POSIX_Proactor *posix_proactor,
1734 ACE_POSIX_Asynch_Transmit_File_Result *result);
1736 /// Destructor.
1737 virtual ~ACE_POSIX_Asynch_Transmit_Handler (void);
1739 /// Do the transmission. All the info to do the transmission is in
1740 /// the <result> member.
1741 int transmit (void);
1743 protected:
1745 /// The asynch result pointer made from the initial transmit file
1746 /// request.
1747 ACE_POSIX_Asynch_Transmit_File_Result *result_;
1749 /// Message bloack used to do the transmission.
1750 ACE_Message_Block *mb_;
1752 enum ACT
1754 HEADER_ACT = 1,
1755 DATA_ACT = 2,
1756 TRAILER_ACT = 3
1759 /// ACT to transmit header.
1760 ACT header_act_;
1762 /// ACT to transmit data.
1763 ACT data_act_;
1765 /// ACT to transmit trailer.
1766 ACT trailer_act_;
1768 /// Current offset of the file being transmitted.
1769 size_t file_offset_;
1771 /// Total size of the file.
1772 size_t file_size_;
1774 /// Number of bytes transferred on the stream.
1775 size_t bytes_transferred_;
1777 /// This is called when asynchronous writes from the socket complete.
1778 virtual void handle_write_stream (const ACE_Asynch_Write_Stream::Result &result);
1780 /// This is called when asynchronous reads from the file complete.
1781 virtual void handle_read_file (const ACE_Asynch_Read_File::Result &result);
1783 /// Issue asynch read from the file.
1784 int initiate_read_file (void);
1786 /// To read from the file to be transmitted.
1787 ACE_POSIX_Asynch_Read_File rf_;
1789 /// Write stream to write the header, trailer and the data.
1790 ACE_POSIX_Asynch_Write_Stream ws_;
1793 // ************************************************************
1795 // Constructor.
1796 ACE_POSIX_Asynch_Transmit_Handler::ACE_POSIX_Asynch_Transmit_Handler
1797 (ACE_POSIX_Proactor *posix_proactor,
1798 ACE_POSIX_Asynch_Transmit_File_Result *result)
1799 : result_ (result),
1800 mb_ (0),
1801 header_act_ (this->HEADER_ACT),
1802 data_act_ (this->DATA_ACT),
1803 trailer_act_ (this->TRAILER_ACT),
1804 file_offset_ (result->offset ()),
1805 file_size_ (0),
1806 bytes_transferred_ (0),
1807 rf_ (posix_proactor),
1808 ws_ (posix_proactor)
1810 // Allocate memory for the message block.
1811 ACE_NEW (this->mb_,
1812 ACE_Message_Block (this->result_->bytes_per_send ()
1813 + 1));
1814 // Init the file size.
1815 file_size_ = ACE_OS::filesize (this->result_->file ());
1818 // Destructor.
1819 ACE_POSIX_Asynch_Transmit_Handler::~ACE_POSIX_Asynch_Transmit_Handler (void)
1821 delete result_;
1822 mb_->release ();
1826 // Do the transmission.
1827 // Initiate transmitting the header. When that completes
1828 // handle_write_stream will be called, there start transmitting the file.
1830 ACE_POSIX_Asynch_Transmit_Handler::transmit (void)
1832 // No proactor is given for the <open>'s. Because we are using the
1833 // concrete implementations of the Asynch_Operations, and we have
1834 // already given them the specific proactor, so they wont need the
1835 // general <proactor> interface pointer.
1837 // Open Asynch_Read_File.
1838 if (this->rf_.open (this->proxy (),
1839 this->result_->file (),
1841 0) == -1)
1842 ACELIB_ERROR_RETURN ((LM_ERROR,
1843 "ACE_Asynch_Transmit_Handler:read_file open failed\n"),
1844 -1);
1846 // Open Asynch_Write_Stream.
1847 if (this->ws_.open (this->proxy (),
1848 this->result_->socket (),
1850 0) == -1)
1851 ACELIB_ERROR_RETURN ((LM_ERROR,
1852 "ACE_Asynch_Transmit_Handler:write_stream open failed\n"),
1853 -1);
1855 // Transmit the header.
1856 if (this->ws_.write (*this->result_->header_and_trailer ()->header (),
1857 this->result_->header_and_trailer ()->header_bytes (),
1858 reinterpret_cast<void *> (&this->header_act_),
1859 0) == -1)
1860 ACELIB_ERROR_RETURN ((LM_ERROR,
1861 "Asynch_Transmit_Handler:transmitting header:write_stream failed\n"),
1862 -1);
1863 return 0;
1866 void
1867 ACE_POSIX_Asynch_Transmit_Handler::handle_write_stream (const ACE_Asynch_Write_Stream::Result &result)
1869 // Update bytes transferred so far.
1870 this->bytes_transferred_ += result.bytes_transferred ();
1872 // Check the success parameter.
1873 if (result.success () == 0)
1875 // Failure.
1877 ACELIB_ERROR ((LM_ERROR,
1878 "Asynch_Transmit_File failed.\n"));
1880 ACE_SEH_TRY
1882 this->result_->complete (this->bytes_transferred_,
1883 0, // Failure.
1884 0, // @@ Completion key.
1885 0); // @@ Error no.
1887 ACE_SEH_FINALLY
1889 // This is crucial to prevent memory leaks. This deletes
1890 // the result pointer also.
1891 delete this;
1895 // Write stream successful.
1897 // Partial write to socket.
1898 size_t unsent_data = result.bytes_to_write () - result.bytes_transferred ();
1899 if (unsent_data != 0)
1901 ACELIB_DEBUG ((LM_DEBUG,
1902 "%N:%l:Partial write to socket: Asynch_write called again\n"));
1904 // Duplicate the message block and retry remaining data
1905 if (this->ws_.write (*result.message_block ().duplicate (),
1906 unsent_data,
1907 result.act (),
1908 this->result_->priority (),
1909 this->result_->signal_number ()) == -1)
1911 // @@ Handle this error.
1912 ACELIB_ERROR ((LM_ERROR,
1913 "Asynch_Transmit_Handler:write_stream failed\n"));
1914 return;
1917 // @@ Handling *partial write* to a socket. Let us not continue
1918 // further before this write finishes. Because proceeding with
1919 // another read and then write might change the order of the
1920 // file transmission, because partial write to the stream is
1921 // always possible.
1922 return;
1925 // Not a partial write. A full write.
1927 // Check ACT to see what was sent.
1928 ACT act = * (ACT *) result.act ();
1930 switch (act)
1932 case TRAILER_ACT:
1933 // If it is the "trailer" that is just sent, then transmit file
1934 // is complete.
1935 // Call the application handler.
1936 ACE_SEH_TRY
1938 this->result_->complete (this->bytes_transferred_,
1939 1, // @@ Success.
1940 0, // @@ Completion key.
1941 0); // @@ Errno.
1943 ACE_SEH_FINALLY
1945 delete this;
1947 break;
1949 case HEADER_ACT:
1950 case DATA_ACT:
1951 // If header/data was sent, initiate the file data transmission.
1952 if (this->initiate_read_file () == -1)
1953 // @@ Handle this error.
1954 ACELIB_ERROR ((LM_ERROR,
1955 "Error:Asynch_Transmit_Handler:read_file couldnt be initiated\n"));
1956 break;
1958 default:
1959 // @@ Handle this error.
1960 ACELIB_ERROR ((LM_ERROR,
1961 "Error:ACE_Asynch_Transmit_Handler::handle_write_stream::Unexpected act\n"));
1965 void
1966 ACE_POSIX_Asynch_Transmit_Handler::handle_read_file (const ACE_Asynch_Read_File::Result &result)
1968 // Failure.
1969 if (result.success () == 0)
1972 ACE_SEH_TRY
1974 this->result_->complete (this->bytes_transferred_,
1975 0, // Failure.
1976 0, // @@ Completion key.
1977 errno); // Error no.
1979 ACE_SEH_FINALLY
1981 delete this;
1983 return;
1986 // Read successful.
1987 if (result.bytes_transferred () == 0)
1988 return;
1990 // Increment offset.
1991 this->file_offset_ += result.bytes_transferred ();
1993 // Write data to network.
1994 if (this->ws_.write (result.message_block (),
1995 result.bytes_transferred (),
1996 (void *)&this->data_act_,
1997 this->result_->priority (),
1998 this->result_->signal_number ()) == -1)
2000 // @@ Handle this error.
2001 ACELIB_ERROR ((LM_ERROR,
2002 "Error:ACE_Asynch_Transmit_File : write to the stream failed\n"));
2003 return;
2008 ACE_POSIX_Asynch_Transmit_Handler::initiate_read_file (void)
2010 // Is there something to read.
2011 if (this->file_offset_ >= this->file_size_)
2013 // File is sent. Send the trailer.
2014 if (this->ws_.write (*this->result_->header_and_trailer ()->trailer (),
2015 this->result_->header_and_trailer ()->trailer_bytes (),
2016 (void *)&this->trailer_act_,
2017 this->result_->priority (),
2018 this->result_->signal_number ()) == -1)
2019 ACELIB_ERROR_RETURN ((LM_ERROR,
2020 "Error:Asynch_Transmit_Handler:write_stream writing trailer failed\n"),
2021 -1);
2022 return 0;
2024 else
2026 // @@ Is this right??
2027 // Previous reads and writes are over. For the new read, adjust
2028 // the wr_ptr and the rd_ptr to the beginning.
2029 this->mb_->rd_ptr (this->mb_->base ());
2030 this->mb_->wr_ptr (this->mb_->base ());
2032 // Inititiate an asynchronous read from the file.
2033 if (this->rf_.read (*this->mb_,
2034 this->mb_->size () - 1,
2035 this->file_offset_,
2036 0, // @@ offset_high !!! if aiocb64 is used.
2037 0, // Act
2038 this->result_->priority (),
2039 this->result_->signal_number ()) == -1)
2040 ACELIB_ERROR_RETURN ((LM_ERROR,
2041 "Error:Asynch_Transmit_Handler::read from file failed\n"),
2042 -1);
2043 return 0;
2047 // *********************************************************************
2049 ACE_POSIX_Asynch_Transmit_File::ACE_POSIX_Asynch_Transmit_File (ACE_POSIX_Proactor *posix_proactor)
2050 : ACE_POSIX_Asynch_Operation (posix_proactor)
2055 ACE_POSIX_Asynch_Transmit_File::transmit_file (ACE_HANDLE file,
2056 ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer,
2057 size_t bytes_to_write,
2058 u_long offset,
2059 u_long offset_high,
2060 size_t bytes_per_send,
2061 u_long flags,
2062 const void *act,
2063 int priority,
2064 int signal_number)
2066 // Adjust these parameters if there are default values specified.
2067 ssize_t file_size = ACE_OS::filesize (file);
2069 if (file_size == -1)
2070 ACELIB_ERROR_RETURN ((LM_ERROR,
2071 ACE_TEXT("Error:%N:%l:%p\n"),
2072 ACE_TEXT("POSIX_Asynch_Transmit_File:filesize failed")),
2073 -1);
2075 if (bytes_to_write == 0)
2076 bytes_to_write = file_size;
2078 if (offset > (size_t) file_size)
2079 ACELIB_ERROR_RETURN ((LM_ERROR,
2080 ACE_TEXT("Error:%p\n"),
2081 ACE_TEXT("Asynch_Transmit_File:File size is less than offset")),
2082 -1);
2084 if (offset != 0)
2085 bytes_to_write = file_size - offset + 1;
2087 if (bytes_per_send == 0)
2088 bytes_per_send = bytes_to_write;
2090 // Configure the result parameter.
2091 ACE_POSIX_Asynch_Transmit_File_Result *result = 0;
2093 ACE_NEW_RETURN (result,
2094 ACE_POSIX_Asynch_Transmit_File_Result (this->handler_proxy_,
2095 this->handle_,
2096 file,
2097 header_and_trailer,
2098 bytes_to_write,
2099 offset,
2100 offset_high,
2101 bytes_per_send,
2102 flags,
2103 act,
2104 this->posix_proactor ()->get_handle (),
2105 priority,
2106 signal_number),
2107 -1);
2109 // Make the auxillary handler and initiate transmit.
2110 ACE_POSIX_Asynch_Transmit_Handler *transmit_handler = 0;
2112 ACE_NEW_RETURN (transmit_handler,
2113 ACE_POSIX_Asynch_Transmit_Handler (this->posix_proactor (),
2114 result),
2115 -1);
2117 ssize_t return_val = transmit_handler->transmit ();
2119 if (return_val == -1)
2120 // This deletes the <result> in it too.
2121 delete transmit_handler;
2123 return 0;
2126 ACE_POSIX_Asynch_Transmit_File::~ACE_POSIX_Asynch_Transmit_File (void)
2130 // *********************************************************************
2131 size_t
2132 ACE_POSIX_Asynch_Read_Dgram_Result::bytes_to_read (void) const
2134 return this->bytes_to_read_;
2138 ACE_POSIX_Asynch_Read_Dgram_Result::remote_address (ACE_Addr& addr) const
2140 int retVal = -1; // failure
2142 // make sure the addresses are of the same type
2143 if (addr.get_type () == this->remote_address_->get_type ())
2144 { // copy the remote_address_ into addr
2145 addr.set_addr (this->remote_address_->get_addr (),
2146 this->remote_address_->get_size ());
2147 retVal = 0; // success
2150 return retVal;
2153 sockaddr *
2154 ACE_POSIX_Asynch_Read_Dgram_Result::saddr () const
2156 return (sockaddr *) this->remote_address_->get_addr ();
2161 ACE_POSIX_Asynch_Read_Dgram_Result::flags (void) const
2163 return this->flags_;
2166 ACE_HANDLE
2167 ACE_POSIX_Asynch_Read_Dgram_Result::handle (void) const
2169 return this->handle_;
2172 ACE_Message_Block*
2173 ACE_POSIX_Asynch_Read_Dgram_Result::message_block () const
2175 return this->message_block_;
2178 ACE_POSIX_Asynch_Read_Dgram_Result::ACE_POSIX_Asynch_Read_Dgram_Result
2179 (const ACE_Handler::Proxy_Ptr &handler_proxy,
2180 ACE_HANDLE handle,
2181 ACE_Message_Block *message_block,
2182 size_t bytes_to_read,
2183 int flags,
2184 int protocol_family,
2185 const void* act,
2186 ACE_HANDLE event,
2187 int priority,
2188 int signal_number)
2189 : ACE_POSIX_Asynch_Result
2190 (handler_proxy, act, event, 0, 0, priority, signal_number),
2191 bytes_to_read_ (bytes_to_read),
2192 message_block_ (message_block),
2193 remote_address_ (0),
2194 addr_len_ (0),
2195 flags_ (flags),
2196 handle_ (handle)
2198 ACE_UNUSED_ARG (protocol_family);
2199 this->aio_fildes = handle;
2200 this->aio_buf = message_block->wr_ptr ();
2201 this->aio_nbytes = bytes_to_read;
2202 ACE_NEW (this->remote_address_, ACE_INET_Addr);
2205 void
2206 ACE_POSIX_Asynch_Read_Dgram_Result::complete (size_t bytes_transferred,
2207 int success,
2208 const void *completion_key,
2209 u_long error)
2211 // Copy the data which was returned by GetQueuedCompletionStatus
2212 this->bytes_transferred_ = bytes_transferred;
2213 this->success_ = success;
2214 this->completion_key_ = completion_key;
2215 this->error_ = error;
2217 // Appropriately move the pointers in the message block.
2218 this->message_block_->wr_ptr (bytes_transferred);
2220 // <errno> is available in the aiocb.
2221 ACE_UNUSED_ARG (error);
2223 this->remote_address_->set_size(this->addr_len_);
2225 // Create the interface result class.
2226 ACE_Asynch_Read_Dgram::Result result (this);
2228 // Call the application handler.
2229 ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
2230 if (handler != 0)
2231 handler->handle_read_dgram (result);
2234 ACE_POSIX_Asynch_Read_Dgram_Result::~ACE_POSIX_Asynch_Read_Dgram_Result (void)
2236 delete this->remote_address_;
2239 //***************************************************************************
2240 size_t
2241 ACE_POSIX_Asynch_Write_Dgram_Result::bytes_to_write (void) const
2243 return this->bytes_to_write_;
2247 ACE_POSIX_Asynch_Write_Dgram_Result::flags (void) const
2249 return this->flags_;
2252 ACE_HANDLE
2253 ACE_POSIX_Asynch_Write_Dgram_Result::handle (void) const
2255 return this->handle_;
2259 ACE_Message_Block*
2260 ACE_POSIX_Asynch_Write_Dgram_Result::message_block () const
2262 return this->message_block_;
2265 ACE_POSIX_Asynch_Write_Dgram_Result::ACE_POSIX_Asynch_Write_Dgram_Result
2266 (const ACE_Handler::Proxy_Ptr &handler_proxy,
2267 ACE_HANDLE handle,
2268 ACE_Message_Block *message_block,
2269 size_t bytes_to_write,
2270 int flags,
2271 const void* act,
2272 ACE_HANDLE event,
2273 int priority,
2274 int signal_number)
2275 : ACE_POSIX_Asynch_Result
2276 (handler_proxy, act, event, 0, 0, priority, signal_number),
2277 bytes_to_write_ (bytes_to_write),
2278 message_block_ (message_block),
2279 flags_ (flags),
2280 handle_ (handle)
2283 this->aio_fildes = handle;
2284 this->aio_buf = message_block->rd_ptr ();
2285 this->aio_nbytes = bytes_to_write;
2288 void
2289 ACE_POSIX_Asynch_Write_Dgram_Result::complete (size_t bytes_transferred,
2290 int success,
2291 const void *completion_key,
2292 u_long error)
2294 // Copy the data which was returned by GetQueuedCompletionStatus
2295 this->bytes_transferred_ = bytes_transferred;
2296 this->success_ = success;
2297 this->completion_key_ = completion_key;
2298 this->error_ = error;
2300 // <errno> is available in the aiocb.
2301 ACE_UNUSED_ARG (error);
2303 // Appropriately move the pointers in the message block.
2304 this->message_block_->rd_ptr (bytes_transferred);
2306 // Create the interface result class.
2307 ACE_Asynch_Write_Dgram::Result result (this);
2309 // Call the application handler.
2310 ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
2311 if (handler != 0)
2312 handler->handle_write_dgram (result);
2315 ACE_POSIX_Asynch_Write_Dgram_Result::~ACE_POSIX_Asynch_Write_Dgram_Result (void)
2319 /***************************************************************************/
2320 ACE_POSIX_Asynch_Read_Dgram::~ACE_POSIX_Asynch_Read_Dgram (void)
2324 ssize_t
2325 ACE_POSIX_Asynch_Read_Dgram::recv (ACE_Message_Block *message_block,
2326 size_t & /*number_of_bytes_recvd*/,
2327 int flags,
2328 int protocol_family,
2329 const void *act,
2330 int priority,
2331 int signal_number)
2333 size_t space = message_block->space ();
2334 // Create the Asynch_Result.
2335 ACE_POSIX_Asynch_Read_Dgram_Result *result = 0;
2336 ACE_POSIX_Proactor *proactor = this->posix_proactor ();
2337 ACE_NEW_RETURN (result,
2338 ACE_POSIX_Asynch_Read_Dgram_Result (this->handler_proxy_,
2339 this->handle_,
2340 message_block,
2341 space,
2342 flags,
2343 protocol_family,
2344 act,
2345 proactor->get_handle (),
2346 priority,
2347 signal_number),
2348 -1);
2350 int return_val = proactor->start_aio (result, ACE_POSIX_Proactor::ACE_OPCODE_READ);
2351 if (return_val == -1)
2352 delete result;
2354 return return_val;
2357 ACE_POSIX_Asynch_Read_Dgram::ACE_POSIX_Asynch_Read_Dgram (ACE_POSIX_Proactor *posix_proactor)
2358 : ACE_POSIX_Asynch_Operation (posix_proactor)
2362 //***************************************************************************
2364 ACE_POSIX_Asynch_Write_Dgram::~ACE_POSIX_Asynch_Write_Dgram (void)
2368 ssize_t
2369 ACE_POSIX_Asynch_Write_Dgram::send (ACE_Message_Block *message_block,
2370 size_t &/*number_of_bytes_sent*/,
2371 int flags,
2372 const ACE_Addr &/*addr*/,
2373 const void *act,
2374 int priority,
2375 int signal_number)
2377 size_t len = message_block->length ();
2378 if (len == 0)
2379 ACELIB_ERROR_RETURN
2380 ((LM_ERROR,
2381 ACE_TEXT ("ACE_POSIX_Asynch_Write_Stream::write:")
2382 ACE_TEXT ("Attempt to write 0 bytes\n")),
2383 -1);
2385 ACE_POSIX_Asynch_Write_Dgram_Result *result = 0;
2386 ACE_POSIX_Proactor *proactor = this->posix_proactor ();
2387 ACE_NEW_RETURN (result,
2388 ACE_POSIX_Asynch_Write_Dgram_Result (this->handler_proxy_,
2389 this->handle_,
2390 message_block,
2391 len,
2392 flags,
2393 act,
2394 proactor->get_handle (),
2395 priority,
2396 signal_number),
2397 -1);
2399 int return_val = proactor->start_aio (result, ACE_POSIX_Proactor::ACE_OPCODE_WRITE);
2400 if (return_val == -1)
2401 delete result;
2403 return return_val;
2406 ACE_POSIX_Asynch_Write_Dgram::ACE_POSIX_Asynch_Write_Dgram
2407 (ACE_POSIX_Proactor *posix_proactor)
2408 : ACE_POSIX_Asynch_Operation (posix_proactor)
2412 ACE_END_VERSIONED_NAMESPACE_DECL
2414 #endif /* ACE_HAS_AIO_CALLS */