ACE_POSIX_Asynch_Accept Class Reference

For the POSIX implementation this class is common for all Proactors (AIOCB/SIG/SUN). More...

#include <POSIX_Asynch_IO.h>

Inheritance diagram for ACE_POSIX_Asynch_Accept:

Inheritance graph
[legend]
Collaboration diagram for ACE_POSIX_Asynch_Accept:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 ACE_POSIX_Asynch_Accept (ACE_POSIX_Proactor *posix_proactor)
 Constructor.

virtual ~ACE_POSIX_Asynch_Accept (void)
 Destructor.

int open (const ACE_Handler::Proxy_Ptr &handler_proxy, ACE_HANDLE handle, const void *completion_key, ACE_Proactor *proactor=0)
int accept (ACE_Message_Block &message_block, size_t bytes_to_read, ACE_HANDLE accept_handle, const void *act, int priority, int signal_number=0, int addr_family=AF_INET)
int cancel (void)
int close ()
ACE_HANDLE get_handle (void) const
 virtual from ACE_Event_Handler

void set_handle (ACE_HANDLE handle)
 virtual from ACE_Event_Handler

int handle_input (ACE_HANDLE handle)
int handle_close (ACE_HANDLE handle, ACE_Reactor_Mask close_mask)
 virtual from ACE_Event_Handler


Private Member Functions

int cancel_uncompleted (int flg_notify)

Private Attributes

bool flg_open_
ACE_Unbounded_Queue< ACE_POSIX_Asynch_Accept_Result * > result_queue_
ACE_SYNCH_MUTEX lock_

Detailed Description

For the POSIX implementation this class is common for all Proactors (AIOCB/SIG/SUN).

Definition at line 662 of file POSIX_Asynch_IO.h.


Constructor & Destructor Documentation

ACE_POSIX_Asynch_Accept::ACE_POSIX_Asynch_Accept ACE_POSIX_Proactor posix_proactor  ) 
 

Constructor.

Definition at line 780 of file POSIX_Asynch_IO.cpp.

00781   : ACE_POSIX_Asynch_Operation (posix_proactor),
00782     flg_open_ (false)
00783 {
00784 }

ACE_POSIX_Asynch_Accept::~ACE_POSIX_Asynch_Accept void   )  [virtual]
 

Destructor.

Definition at line 786 of file POSIX_Asynch_IO.cpp.

References close(), and ACE_Event_Handler::reactor().

00787 {
00788   this->close ();
00789   this->reactor (0); // to avoid purge_pending_notifications
00790 }


Member Function Documentation

int ACE_POSIX_Asynch_Accept::accept ACE_Message_Block message_block,
size_t  bytes_to_read,
ACE_HANDLE  accept_handle,
const void *  act,
int  priority,
int  signal_number = 0,
int  addr_family = AF_INET
[virtual]
 

This starts off an asynchronous accept. The asynchronous accept call also allows any initial data to be returned to the . Upto will be read and stored in the . The will be used for the call. If ( == INVALID_HANDLE), a new handle will be created.

must be specified. This is because the address of the new connection is placed at the end of this buffer.

Implements ACE_Asynch_Accept_Impl.

Definition at line 846 of file POSIX_Asynch_IO.cpp.

References ACE_ERROR, ACE_ERROR_RETURN, ACE_GUARD_RETURN, ACE_LIB_TEXT, ACE_NEW_RETURN, ACE_SYNCH_MUTEX, ACE_TRACE, ENOBUFS, ACE_Unbounded_Queue< ACE_POSIX_Asynch_Accept_Result * >::enqueue_tail(), flg_open_, ACE_POSIX_Proactor::get_asynch_pseudo_task(), ACE_OS::last_error(), LM_ERROR, ACE_POSIX_Asynch_Operation::posix_proactor(), result_queue_, ACE_Asynch_Pseudo_Task::resume_io_handler(), ACE_Unbounded_Queue< ACE_POSIX_Asynch_Accept_Result * >::size(), and ACE_Message_Block::space().

00853 {
00854   ACE_TRACE ("ACE_POSIX_Asynch_Accept::accept");
00855 
00856   if (!this->flg_open_)
00857     ACE_ERROR_RETURN ((LM_ERROR,
00858                        ACE_LIB_TEXT("%N:%l:ACE_POSIX_Asynch_Accept::accept")
00859                        ACE_LIB_TEXT("acceptor was not opened before\n")),
00860                       -1);
00861 
00862   // Sanity check: make sure that enough space has been allocated by
00863   // the caller.
00864   size_t address_size = sizeof (sockaddr_in);
00865 #if defined (ACE_HAS_IPV6)
00866   if (addr_family == AF_INET6)
00867     address_size = sizeof (sockaddr_in6);
00868 #else
00869   ACE_UNUSED_ARG (addr_family);
00870 #endif
00871   size_t available_space = message_block.space ();
00872   size_t space_needed = bytes_to_read + 2 * address_size;
00873 
00874   if (available_space < space_needed)
00875     {
00876       ACE_OS::last_error (ENOBUFS);
00877       return -1;
00878     }
00879 
00880   // Common code for both WIN and POSIX.
00881   // Create future Asynch_Accept_Result
00882   ACE_POSIX_Asynch_Accept_Result *result = 0;
00883   ACE_NEW_RETURN (result,
00884                   ACE_POSIX_Asynch_Accept_Result (this->handler_proxy_,
00885                                                   this->handle_,
00886                                                   accept_handle,
00887                                                   message_block,
00888                                                   bytes_to_read,
00889                                                   act,
00890                                                   this->posix_proactor()->get_handle (),
00891                                                   priority,
00892                                                   signal_number),
00893                   -1);
00894 
00895   // Enqueue result
00896   {
00897     ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
00898     if (this->result_queue_.enqueue_tail (result) == -1)
00899       {
00900         ACE_ERROR ((LM_ERROR,
00901                     ACE_LIB_TEXT ("ACE_POSIX_Asynch_Accept::accept: %p\n")
00902                     ACE_LIB_TEXT ("enqueue_tail")));
00903         delete result;  // to avoid memory  leak
00904         return -1;
00905       }
00906 
00907     if (this->result_queue_.size () > 1)
00908       return 0;
00909   }
00910 
00911   // If this is the only item, then it means there the set was empty
00912   // before. So enable the accept handle in the reactor.
00913 
00914   ACE_Asynch_Pseudo_Task & task =
00915     this->posix_proactor ()->get_asynch_pseudo_task ();
00916 
00917   return task.resume_io_handler (this->get_handle ());
00918 }

int ACE_POSIX_Asynch_Accept::cancel void   )  [virtual]
 

Cancel all pending pseudo-asynchronus requests Behavior as usual AIO request

Reimplemented from ACE_POSIX_Asynch_Operation.

Definition at line 969 of file POSIX_Asynch_IO.cpp.

References ACE_GUARD_RETURN, ACE_SYNCH_MUTEX, ACE_TRACE, cancel_uncompleted(), flg_open_, ACE_POSIX_Proactor::get_asynch_pseudo_task(), ACE_POSIX_Asynch_Operation::posix_proactor(), and ACE_Asynch_Pseudo_Task::suspend_io_handler().

00970 {
00971   ACE_TRACE ("ACE_POSIX_Asynch_Accept::cancel");
00972 
00973   // Since this is not a real POSIX asynch I/O operation, we can't
00974   // call ::aiocancel () or ACE_POSIX_Asynch_Operation::cancel ().
00975   // We delegate real cancelation to cancel_uncompleted (1)
00976 
00977   int rc = -1 ;  // ERRORS
00978 
00979   {
00980     ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
00981 
00982     int num_cancelled = cancel_uncompleted (flg_open_);
00983 
00984     if (num_cancelled == 0)
00985       rc = 1 ;        // AIO_ALLDONE
00986     else if (num_cancelled > 0)
00987       rc = 0 ;        // AIO_CANCELED
00988 
00989     if (!this->flg_open_)
00990       return rc ;
00991   }
00992 
00993   ACE_Asynch_Pseudo_Task & task =
00994     this->posix_proactor ()->get_asynch_pseudo_task ();
00995 
00996   task.suspend_io_handler (this->get_handle());
00997   return 0;
00998 }

int ACE_POSIX_Asynch_Accept::cancel_uncompleted int  flg_notify  )  [private]
 

flg_notify points whether or not we should send notification about canceled accepts Parameter flg_notify can be 0 - don't send notifications about canceled accepts 1 - notify user about canceled accepts according POSIX standards we should receive notifications on canceled AIO requests

Definition at line 933 of file POSIX_Asynch_IO.cpp.

References ACE_ERROR, ACE_LIB_TEXT, ACE_TRACE, ACE_Unbounded_Queue< ACE_POSIX_Asynch_Accept_Result * >::dequeue_head(), flg_open_, LM_ERROR, ACE_POSIX_Asynch_Operation::posix_proactor(), ACE_POSIX_Proactor::post_completion(), result_queue_, ACE_POSIX_Asynch_Result::set_bytes_transferred(), and ACE_POSIX_Asynch_Result::set_error().

Referenced by cancel(), close(), and handle_close().

00934 {
00935   ACE_TRACE ("ACE_POSIX_Asynch_Accept::cancel_uncompleted");
00936 
00937   int retval = 0;
00938 
00939   for (; ; retval++)
00940     {
00941       ACE_POSIX_Asynch_Accept_Result* result = 0;
00942 
00943       this->result_queue_.dequeue_head (result);
00944 
00945       if (result == 0)
00946         break;
00947 
00948       if (this->flg_open_ == 0 || flg_notify == 0) //if we should not notify
00949         delete result ;                            // we have to delete result
00950       else                                 //else notify as any cancelled AIO
00951         {
00952           // Store the new handle.
00953           result->aio_fildes = ACE_INVALID_HANDLE ;
00954           result->set_bytes_transferred (0);
00955           result->set_error (ECANCELED);
00956 
00957           if (this->posix_proactor ()->post_completion (result) == -1)
00958             ACE_ERROR ((LM_ERROR,
00959                         ACE_LIB_TEXT("(%P | %t):%p\n"),
00960                         ACE_LIB_TEXT("ACE_POSIX_Asynch_Accept::")
00961                         ACE_LIB_TEXT("cancel_uncompleted")
00962                         ));
00963         }
00964     }
00965   return retval;
00966 }

int ACE_POSIX_Asynch_Accept::close  ) 
 

Close performs cancellation of all pending requests and closure the listen handle

Definition at line 1001 of file POSIX_Asynch_IO.cpp.

References ACE_GUARD_RETURN, ACE_SYNCH_MUTEX, ACE_TRACE, cancel_uncompleted(), ACE_OS::closesocket(), flg_open_, ACE_POSIX_Proactor::get_asynch_pseudo_task(), ACE_POSIX_Asynch_Operation::posix_proactor(), and ACE_Asynch_Pseudo_Task::remove_io_handler().

Referenced by ~ACE_POSIX_Asynch_Accept().

01002 {
01003   ACE_TRACE ("ACE_POSIX_Asynch_Accept::close");
01004 
01005   // 1. It performs cancellation of all pending requests
01006   // 2. Removes itself from Reactor ( ACE_Asynch_Pseudo_Task)
01007   // 3. close the socket
01008   //
01009   //  Parameter flg_notify can be
01010   //     0  - don't send notifications about canceled accepts
01011   //    !0  - notify user about canceled accepts
01012   //          according POSIX standards we should receive notifications
01013   //          on canceled AIO requests
01014   //
01015   //  Return codes : 0 - OK ,
01016   //                -1 - Errors
01017 
01018   {
01019     ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
01020     this->cancel_uncompleted (flg_open_);
01021   }
01022 
01023   if (!this->flg_open_)
01024     {
01025       if (this->handle_ != ACE_INVALID_HANDLE)
01026         {
01027           ACE_OS::closesocket (this->handle_);
01028           this->handle_ = ACE_INVALID_HANDLE;
01029         }
01030       return 0;
01031     }
01032 
01033   if (this->handle_ == ACE_INVALID_HANDLE)
01034     return 0;
01035 
01036   ACE_Asynch_Pseudo_Task & task =
01037     this->posix_proactor ()->get_asynch_pseudo_task ();
01038 
01039   task.remove_io_handler (this->get_handle ());
01040   if (this->handle_ != ACE_INVALID_HANDLE)
01041     {
01042       ACE_OS::closesocket (this->handle_);
01043       this->handle_ = ACE_INVALID_HANDLE;
01044     }
01045 
01046   this->flg_open_ = false;
01047 
01048   return 0;
01049 }

ACE_HANDLE ACE_POSIX_Asynch_Accept::get_handle void   )  const [virtual]
 

virtual from ACE_Event_Handler

Reimplemented from ACE_Event_Handler.

Definition at line 793 of file POSIX_Asynch_IO.cpp.

00794 {
00795   return this->handle_;
00796 }

int ACE_POSIX_Asynch_Accept::handle_close ACE_HANDLE  handle,
ACE_Reactor_Mask  close_mask
[virtual]
 

virtual from ACE_Event_Handler

Reimplemented from ACE_Event_Handler.

Definition at line 1052 of file POSIX_Asynch_IO.cpp.

References ACE_GUARD_RETURN, ACE_Reactor_Mask, ACE_SYNCH_MUTEX, ACE_TRACE, cancel_uncompleted(), and flg_open_.

01053 {
01054   ACE_TRACE ("ACE_POSIX_Asynch_Accept::handle_close");
01055 
01056   ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0));
01057 
01058   // handle_close is called in two cases:
01059   //  1. Pseudo task is closing (i.e. proactor destructor)
01060   //  2. The listen handle is closed (we don't have exclusive access to this)
01061 
01062   this->cancel_uncompleted (0);
01063 
01064   this->flg_open_ = false;
01065   this->handle_ = ACE_INVALID_HANDLE;
01066   return 0;
01067 }

int ACE_POSIX_Asynch_Accept::handle_input ACE_HANDLE  handle  )  [virtual]
 

virtual from ACE_Event_Handler Called when accept event comes up on

Reimplemented from ACE_Event_Handler.

Definition at line 1070 of file POSIX_Asynch_IO.cpp.

References ACE_OS::accept(), ACE_ERROR, ACE_GUARD_RETURN, ACE_LIB_TEXT, ACE_SYNCH_MUTEX, ACE_TRACE, ACE_OS::closesocket(), ACE_Unbounded_Queue< ACE_POSIX_Asynch_Accept_Result * >::dequeue_head(), ACE_POSIX_Proactor::get_asynch_pseudo_task(), LM_ERROR, ACE_POSIX_Asynch_Operation::posix_proactor(), ACE_POSIX_Proactor::post_completion(), result_queue_, ACE_POSIX_Asynch_Result::set_error(), ACE_Unbounded_Queue< ACE_POSIX_Asynch_Accept_Result * >::size(), and ACE_Asynch_Pseudo_Task::suspend_io_handler().

01071 {
01072   ACE_TRACE ("ACE_POSIX_Asynch_Accept::handle_input");
01073 
01074   // An <accept> has been sensed on the <listen_handle>. We should be
01075   // able to just go ahead and do the <accept> now on this <fd>. This
01076   // should be the same as the <listen_handle>.
01077 
01078   ACE_POSIX_Asynch_Accept_Result* result = 0;
01079 
01080   {
01081     ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0));
01082 
01083     // Deregister this info pertaining to this accept call.
01084     if (this->result_queue_.dequeue_head (result) != 0)
01085       ACE_ERROR ((LM_ERROR,
01086                   ACE_LIB_TEXT("%N:%l:(%P | %t):%p\n"),
01087                   ACE_LIB_TEXT("ACE_POSIX_Asynch_Accept::handle_input:")
01088                   ACE_LIB_TEXT( " dequeueing failed")));
01089 
01090     // Disable the handle in the reactor if no more accepts are pending.
01091     if (this->result_queue_.size () == 0)
01092       {
01093         ACE_Asynch_Pseudo_Task & task =
01094           this->posix_proactor ()->get_asynch_pseudo_task ();
01095 
01096         task.suspend_io_handler (this->get_handle());
01097       }
01098   }
01099 
01100   // Issue <accept> now.
01101   // @@ We shouldnt block here since we have already done poll/select
01102   // thru reactor. But are we sure?
01103 
01104   ACE_HANDLE new_handle = ACE_OS::accept (this->handle_, 0, 0);
01105 
01106   if (result == 0) // there is nobody to notify
01107     {
01108       ACE_OS::closesocket (new_handle);
01109       return 0;
01110     }
01111 
01112   if (new_handle == ACE_INVALID_HANDLE)
01113     {
01114       result->set_error (errno);
01115       ACE_ERROR ((LM_ERROR,
01116                   ACE_LIB_TEXT("%N:%l:(%P | %t):%p\n"),
01117                   ACE_LIB_TEXT("ACE_POSIX_Asynch_Accept::handle_input: ")
01118                   ACE_LIB_TEXT("accept")));
01119 
01120       // Notify client as usual, "AIO" finished with errors
01121     }
01122 
01123   // Store the new handle.
01124   result->aio_fildes = new_handle;
01125 
01126   // Notify the main process about this completion
01127   // Send the Result through the notification pipe.
01128   if (this->posix_proactor ()->post_completion (result) == -1)
01129     ACE_ERROR ((LM_ERROR,
01130                 ACE_LIB_TEXT("Error:(%P | %t):%p\n"),
01131                 ACE_LIB_TEXT("ACE_POSIX_Asynch_Accept::handle_input: ")
01132                 ACE_LIB_TEXT(" <post_completion> failed")));
01133 
01134   return 0;
01135 }

int ACE_POSIX_Asynch_Accept::open const ACE_Handler::Proxy_Ptr handler_proxy,
ACE_HANDLE  handle,
const void *  completion_key,
ACE_Proactor proactor = 0
[virtual]
 

This belongs to ACE_POSIX_Asynch_Operation. We forward this call to that method. We have put this here to avoid the compiler warnings.

Reimplemented from ACE_POSIX_Asynch_Operation.

Definition at line 806 of file POSIX_Asynch_IO.cpp.

References ACE_ERROR_RETURN, ACE_LIB_TEXT, ACE_TRACE, flg_open_, ACE_POSIX_Proactor::get_asynch_pseudo_task(), LM_ERROR, ACE_POSIX_Asynch_Operation::open(), ACE_POSIX_Asynch_Operation::posix_proactor(), ACE_Handler::Proxy_Ptr, and ACE_Asynch_Pseudo_Task::register_io_handler().

00810 {
00811   ACE_TRACE ("ACE_POSIX_Asynch_Accept::open");
00812 
00813   // if we are already opened,
00814   // we could not create a new handler without closing the previous
00815   if (this->flg_open_)
00816     ACE_ERROR_RETURN ((LM_ERROR,
00817                        ACE_LIB_TEXT("%N:%l:ACE_POSIX_Asynch_Accept::open:")
00818                        ACE_LIB_TEXT("acceptor already open \n")),
00819                       -1);
00820 
00821   if (-1 == ACE_POSIX_Asynch_Operation::open (handler_proxy,
00822                                               handle,
00823                                               completion_key,
00824                                               proactor))
00825     return -1;
00826 
00827   flg_open_ = true;
00828 
00829   ACE_Asynch_Pseudo_Task & task =
00830     this->posix_proactor ()->get_asynch_pseudo_task ();
00831 
00832   if (-1 == task.register_io_handler (this->get_handle(),
00833                                       this,
00834                                       ACE_Event_Handler::ACCEPT_MASK,
00835                                       1))  // suspend after register
00836     {
00837       this->flg_open_= false;
00838       this->handle_ = ACE_INVALID_HANDLE;
00839       return -1 ;
00840     }
00841 
00842   return 0;
00843 }

void ACE_POSIX_Asynch_Accept::set_handle ACE_HANDLE  handle  )  [virtual]
 

virtual from ACE_Event_Handler

Reimplemented from ACE_Event_Handler.

Definition at line 799 of file POSIX_Asynch_IO.cpp.

References ACE_ASSERT.

00800 {
00801   ACE_ASSERT (handle_ == ACE_INVALID_HANDLE);
00802   this->handle_ = handle;
00803 }


Member Data Documentation

bool ACE_POSIX_Asynch_Accept::flg_open_ [private]
 

true - Accept is registered in ACE_Asynch_Pseudo_Task false - Accept is deregisted in ACE_Asynch_Pseudo_Task

Definition at line 741 of file POSIX_Asynch_IO.h.

Referenced by accept(), cancel(), cancel_uncompleted(), close(), handle_close(), and open().

ACE_SYNCH_MUTEX ACE_POSIX_Asynch_Accept::lock_ [private]
 

The lock to protect the result queue which is shared. The queue is updated by main thread in the register function call and through the auxillary thread in the deregister fun. So let us mutex it.

Definition at line 751 of file POSIX_Asynch_IO.h.

ACE_Unbounded_Queue<ACE_POSIX_Asynch_Accept_Result*> ACE_POSIX_Asynch_Accept::result_queue_ [private]
 

Queue of Result pointers that correspond to all the pending accept operations.

Definition at line 745 of file POSIX_Asynch_IO.h.

Referenced by accept(), cancel_uncompleted(), and handle_input().


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 11:26:28 2006 for ACE by doxygen 1.3.6