#include <POSIX_Asynch_IO.h>
Inheritance diagram for ACE_POSIX_Asynch_Accept:
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_ |
Definition at line 662 of file POSIX_Asynch_IO.h.
|
Constructor.
Definition at line 780 of file POSIX_Asynch_IO.cpp.
00781 : ACE_POSIX_Asynch_Operation (posix_proactor), 00782 flg_open_ (false) 00783 { 00784 } |
|
Destructor.
Definition at line 786 of file POSIX_Asynch_IO.cpp. References close(), and ACE_Event_Handler::reactor().
|
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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(). |
|
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. |
|
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(). |