summaryrefslogtreecommitdiff
path: root/TAO/tao_ace/Select_IO_Handler_Repository.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao_ace/Select_IO_Handler_Repository.cpp')
-rw-r--r--TAO/tao_ace/Select_IO_Handler_Repository.cpp494
1 files changed, 494 insertions, 0 deletions
diff --git a/TAO/tao_ace/Select_IO_Handler_Repository.cpp b/TAO/tao_ace/Select_IO_Handler_Repository.cpp
new file mode 100644
index 00000000000..667ce235c78
--- /dev/null
+++ b/TAO/tao_ace/Select_IO_Handler_Repository.cpp
@@ -0,0 +1,494 @@
+#include "Select_IO_Handler_Repository.h"
+#include "IO_Event_Handler.h"
+#include "ace/Signal.h"
+
+#if !defined (__ACE_INLINE__)
+#include "Select_IO_Handler_Repository.inl"
+#endif /* __ACE_INLINE__ */
+
+
+ACE_RCSID(tao_ace, Select_IO_Handler_Repository, "$Id$")
+
+
+TAO_ACE_Select_IO_Handler_Repository::TAO_ACE_Select_IO_Handler_Repository (void)
+ : max_size_ (0),
+ max_handlep1_ (0),
+ wait_set_ (),
+# if defined (ACE_WIN32)
+ handler_states_ ()
+#else
+ handler_states_ (0)
+#endif /*ACE_WIN32*/
+{
+ ACE_TRACE ("TAO_ACE_Select_IO_Handler_Repository::Constructor");
+}
+
+
+TAO_ACE_Select_IO_Handler_Repository::TAO_ACE_Select_IO_Handler_Repository (size_t s)
+{
+ ACE_TRACE ("TAO_ACE_Select_IO_Handler_Repository::Constructor");
+ (void) this->open (s);
+}
+
+
+int
+TAO_ACE_Select_IO_Handler_Repository::open (size_t s)
+{
+ ACE_TRACE ("TAO_ACE_Select_IO_Handler_Repository::open");
+#if defined (ACE_WIN32)
+
+ // Just open the cache map where the entries are stored on Win32
+ if (this->handler_states_.open (s) == -1)
+ return -1;
+#else
+
+ // On UNIX based platforms allocate an array of Handler_State so
+ // that we can index directly into the array.
+
+ // If allocated previously just delete them.
+ if (this->handler_states_)
+ delete [] this->handler_states_;
+
+ ACE_NEW_RETURN (this->handler_states_,
+ IO_Handler_State [s],
+ -1);
+#endif /*ACE_WIN32*/
+
+ return 0;
+}
+
+
+int
+TAO_ACE_Select_IO_Handler_Repository::close (void)
+{
+ ACE_TRACE ("TAO_ACE_Select_IO_Handler_Repository::close");
+#if defined (ACE_WIN32)
+ // @@ <todo> Where do we do "unbind" of all the elements?. Let this
+ // be there for the timebeing...
+
+ // Just close the cache map where the entries are stored.
+ if (this->handler_states_.close () == -1)
+ return -1;
+#else
+ // If allocated previously just delete them.
+ if (this->handler_states_)
+ delete [] this->handler_states_;
+
+ this->handler_states_ = 0;
+
+#endif /*ACE_WIN32*/
+
+ return 0;
+}
+
+
+int
+TAO_ACE_Select_IO_Handler_Repository::bind (
+ TAO_ACE_IO_Event_Handler *eh,
+ TAO_ACE_IO_Event_Masks::Event_Masks mask)
+{
+ ACE_TRACE ("TAO_ACE_Select_IO_Handler_Repository::bind");
+
+ // Get the handle
+ ACE_HANDLE handle = eh->get_handle ();
+
+ // Check for the validity of the handle
+ if (this->is_handle_valid (handle) < 0)
+ return -1;
+
+ // Increment the reference count of the event handler. This
+ // reference count indicates the reference that the repository is
+ // holding.
+ eh->incr_ref_count ();
+
+#if defined (ACE_WIN32)
+
+ // Copy the pointer to the Event Handler to the object that is
+ // being added to the Hash Map.
+ TAO_ACE_IO_Handler_Repository::IO_Handle_State handle_state;
+ handle_state.event_handler_ = eh;
+
+ // Just use a rebind even if there was a event handle associated
+ // with the handle before..
+ int retval =
+ this->handler_states_.rebind ((ACE_SOCKET) handle,
+ handle_state);
+
+ if (retval == -1)
+ {
+ ACE_DEBUG_RETURN ((LM_DEBUG,
+ "(%P|%t) Could not register handle [%d] "
+ "with the repository \n"),
+ -1);
+ }
+
+ // This argument is ignored during the select () call on Win32
+ // Winsock 1.1 and Winsock 1.2. We dont do much about this on Win32
+ // platforms..
+ /*this->max_handlep1_ = 0*/
+
+#else /*if !ACE_WIN32*/
+
+ this->handler_states_[handle].event_handler_ = eh;
+
+ if (this->max_handlep1_ < handle + 1)
+ this->max_handlep1_ = handle + 1;
+
+#endif /*ACE_WIN32*/
+
+ // Add the <mask> for this <handle> in to the Select_Reactor's
+ // wait_set.
+ this->add_masks (handle,
+ mask);
+
+ // <Bala>: Do we need this?
+ // this->state_changed_ = 1;
+
+ return 0;
+}
+
+int
+TAO_ACE_Select_IO_Handler_Repository::unbind (
+ TAO_ACE_IO_Event_Handler *eh,
+ TAO_ACE_IO_Event_Masks::Event_Masks mask)
+{
+ ACE_TRACE ("TAO_ACE_Select_IO_Handler_Repository::unbind");
+
+ // Get the handle
+ ACE_HANDLE handle = eh->get_handle ();
+
+ // Check the validity of the handle
+ if (this->is_handle_valid (handle) < 0)
+ return -1;
+
+ // Clear the <mask> for the <handle> from the wait set
+ this->clr_masks (handle, mask);
+
+ // Check whether we have any other event masks left behind for this
+ // handle.
+ if (!this->is_event_mask_available (handle))
+ {
+ // If no masks are left behind, just get the handle state
+# if defined (ACE_WIN32)
+
+ TAO_ACE_IO_Handler_Repository::IO_Handle_State handle_state;
+
+ int retval =
+ this->handler_states_.find ((ACE_SOCKET) handle,
+ handle_state);
+ if (retval < 0)
+ {
+ ACE_DEBUG_RETURN ((LM_DEBUG,
+ "(%P|%t) Could not find handle [%d] "
+ "in the repository \n", (ACE_SOCKET) handle),
+ -1);
+ }
+
+ // We have a few threads making the upcall
+ if (handle_state.thread_count_ != 0)
+ {
+ // Mark the handler for deletion
+ handle_state.marked_for_deletion_ = 1;
+
+ // Leave it back in the hash map.
+ retval =
+ this->handler_states_.rebind ((ACE_SOCKET) handle,
+ handle_state);
+
+ // If error occurs return -1;
+ if (retval == -1)
+ return retval;
+ }
+ else
+ {
+ // Unbind the entry from the hash map
+ retval =
+ this->handler_states_.unbind ((ACE_SOCKET) handle);
+
+ // Decrement the ref count as we have removed the entry from
+ // the map.
+ handle_state.event_handler_.decr_ref_count ();
+ }
+
+#else /*!ACE_WIN32*/
+ if (this->handler_states_[handle].thread_count_ != 0)
+ {
+ this->handler_states_[handle].marked_for_deletion_ = 1;
+ }
+ else
+ {
+ // Decrement the refcount
+ this->handler_states_[handle].event_handler_->decr_ref_count ();
+
+ // Clear up the slot for usage
+ this->handler_states_[handle].thread_count_ = 0;
+ this->handler_states_[handle].marked_for_deletion_ = 0;
+ this->handler_states_[handle].event_handler_ = 0;
+
+ // Re-calculate the max_handlep1_
+
+ if (this->max_handlep1_ == handle + 1)
+ {
+ // We've deleted the last entry, so we need to figure out
+ // the last valid place in the array that is worth looking
+ // at.
+ ACE_HANDLE wait_rd_max = this->wait_set_.rd_mask_.max_set ();
+ ACE_HANDLE wait_wr_max = this->wait_set_.wr_mask_.max_set ();
+ ACE_HANDLE wait_ex_max = this->wait_set_.ex_mask_.max_set ();
+
+ // <todo>Need to include the suspend set too????
+
+ // Compute the maximum of six values.
+ this->max_handlep1_ = wait_rd_max;
+ if (this->max_handlep1_ < wait_wr_max)
+ this->max_handlep1_ = wait_wr_max;
+ if (this->max_handlep1_ < wait_ex_max)
+ this->max_handlep1_ = wait_ex_max;
+
+ this->max_handlep1_++;
+ }
+ }
+#endif /*ACE_WIN32*/
+ }
+
+ return 0;
+}
+
+int
+TAO_ACE_Select_IO_Handler_Repository::add_masks (
+ ACE_HANDLE h,
+ TAO_ACE_IO_Event_Masks::Event_Masks mask)
+{
+ ACE_TRACE ("TAO_ACE_Select_IO_Handler_Repository::add_masks");
+
+ if (this->is_handle_valid (h) < 0)
+ return -1;
+
+#if !defined (ACE_WIN32)
+ ACE_Sig_Guard sb; // Block out all signals until method returns.
+#endif /* ACE_WIN32 */
+
+ // READ, ACCEPT, and CONNECT flag will place the handle in the
+ // read set.
+ if (ACE_BIT_ENABLED (mask, TAO_ACE_IO_Event_Masks::READ_MASK)
+ || ACE_BIT_ENABLED (mask, TAO_ACE_IO_Event_Masks::ACCEPT_MASK)
+ || ACE_BIT_ENABLED (mask, TAO_ACE_IO_Event_Masks::CONNECT_MASK))
+ {
+ this->wait_set_.rd_mask_.set_bit (h);
+ }
+
+ // WRITE and CONNECT flag will place the handle in the write set
+ if (ACE_BIT_ENABLED (mask,
+ TAO_ACE_IO_Event_Masks::WRITE_MASK)
+ || ACE_BIT_ENABLED (mask,
+ TAO_ACE_IO_Event_Masks::CONNECT_MASK))
+ {
+ this->wait_set_.wr_mask_.set_bit (h);
+ }
+
+ // EXCEPT (and CONNECT on Win32) flag will place the handle in
+ // the except set.
+ if (ACE_BIT_ENABLED (mask,
+ TAO_ACE_IO_Event_Masks::EXCEPT_MASK)
+#if defined (ACE_WIN32)
+ || ACE_BIT_ENABLED (mask,
+ TAO_ACE_IO_Event_Masks::CONNECT_MASK)
+#endif /* ACE_WIN32 */
+ )
+ {
+ this->wait_set_.ex_mask_.set_bit (h);
+ }
+
+ return 0;
+}
+
+
+int
+TAO_ACE_Select_IO_Handler_Repository::clr_masks (
+ ACE_HANDLE h,
+ TAO_ACE_IO_Event_Masks::Event_Masks mask)
+{
+ ACE_TRACE ("TAO_ACE_Select_IO_Handler_Repository::clr_masks");
+
+ if (this->is_handle_valid (h) < 0)
+ return -1;
+
+#if !defined (ACE_WIN32)
+ ACE_Sig_Guard sb; // Block out all signals until method returns.
+#endif /* ACE_WIN32 */
+
+ // READ, ACCEPT, and CONNECT flag will place the handle in the
+ // read set.
+ if (ACE_BIT_ENABLED (mask, TAO_ACE_IO_Event_Masks::READ_MASK)
+ || ACE_BIT_ENABLED (mask, TAO_ACE_IO_Event_Masks::ACCEPT_MASK)
+ || ACE_BIT_ENABLED (mask, TAO_ACE_IO_Event_Masks::CONNECT_MASK))
+ {
+ this->wait_set_.rd_mask_.clr_bit (h);
+ }
+
+ // WRITE and CONNECT flag will place the handle in the write set
+ if (ACE_BIT_ENABLED (mask,
+ TAO_ACE_IO_Event_Masks::WRITE_MASK)
+ || ACE_BIT_ENABLED (mask,
+ TAO_ACE_IO_Event_Masks::CONNECT_MASK))
+ {
+ this->wait_set_.wr_mask_.clr_bit (h);
+ }
+
+ // EXCEPT (and CONNECT on Win32) flag will place the handle in
+ // the except set.
+ if (ACE_BIT_ENABLED (mask,
+ TAO_ACE_IO_Event_Masks::EXCEPT_MASK)
+#if defined (ACE_WIN32)
+ || ACE_BIT_ENABLED (mask,
+ TAO_ACE_IO_Event_Handler::CONNECT_MASK)
+#endif /* ACE_WIN32 */
+ )
+ {
+ this->wait_set_.ex_mask_.clr_bit (h);
+ }
+
+ return 0;
+}
+
+
+int
+TAO_ACE_Select_IO_Handler_Repository::find_state (
+ ACE_HANDLE h,
+ TAO_ACE_IO_Handler_Repository::IO_Handler_State &state)
+{
+#if defined (ACE_WIN32)
+
+ // Look at the Hash Map to get the value
+ return this->handle_states_->find ((ACE_SOCKET) h,
+ state);
+#else /*ACE_WIN32*/
+
+ if (h < this->max_handlep1_)
+ {
+ state = this->handler_states_[h];
+
+ return 0;
+ }
+
+ return -1;
+#endif /*!ACE_WIN32*/
+
+}
+
+
+int
+TAO_ACE_Select_IO_Handler_Repository::rebind_state (
+ TAO_ACE_Select_IO_Handler_Repository::IO_Handler_State &state)
+{
+ ACE_HANDLE h = state.event_handler_->get_handle ();
+
+#if defined (ACE_WIN32)
+
+ // Look at the Hash Map to get the value
+ return this->handler_states_->rebind ((ACE_SOCKET)h,
+ state);
+
+#else /*ACE_WIN32*/
+
+ if (h < this->max_handlep1_)
+ {
+ this->handler_states_[h] = state;
+
+ return 0;
+ }
+
+ return -1;
+#endif /*!ACE_WIN32*/
+}
+
+/*************************************************************************/
+TAO_ACE_Select_IO_Handler_Repository_Iterator::TAO_ACE_Select_IO_Handler_Repository_Iterator (
+ const TAO_ACE_Select_IO_Handler_Repository &repo)
+ : repo_ (repo)
+#if defined (ACE_WIN32)
+ , iter_ (handler_states_)
+#else /* !ACE_WIN32*/
+ , index_ (-1)
+#endif /*ACE_WIN32*/
+{
+ this->advance ();
+}
+
+
+int
+TAO_ACE_Select_IO_Handler_Repository_Iterator::next (
+ TAO_ACE_IO_Handler_Repository::IO_Handler_State *&next_item)
+{
+ int retval = 1;
+
+# if defined (ACE_WIN32)
+
+ // On Win32 platforms just fallback on the Hash Map
+ retval =
+ this->iter_->next (next_item);
+# else
+
+ if (this->index_ >= this->repo_.max_handlep1_)
+ retval = 0;
+ else
+ next_item = &this->repo_.handler_states_[this->index_];
+#endif /*ACE_WIN32*/
+
+ return retval;
+}
+
+int
+TAO_ACE_Select_IO_Handler_Repository_Iterator::done (void) const
+{
+#if defined (ACE_WIN32)
+
+ // On Win32 platforms just fallback on the Hash Map
+ return this->iter_.done ();
+#else /*ACE_WIN32*/
+
+ // On non-Win32 platforms just do the check
+ return this->index_ >= this->repo_.max_handlep1_;
+#endif /*ACE_WIN32*/
+}
+
+
+int
+TAO_ACE_Select_IO_Handler_Repository_Iterator::advance (void)
+{
+ int retval = 0;
+
+#if defined (ACE_WIN32)
+
+ // On Win32 platforms just rely on the iterator
+ retval = this->iter_.advance ();
+#else /*ACE_WIN32*/
+
+ // On non-Win32 platforms just do the advance yourself
+ if (this->index_ < this->repo_.max_handlep1_)
+ this->index_++;
+
+ while (this->index_ < this->repo_.max_handlep1_)
+ if (this->repo_.handler_states_[this->index_].event_handler_ != 0)
+ return 1;
+ else
+ this->index_++;
+#endif /* !ACE_WIN32*/
+
+ return retval;
+}
+
+// Dump the state of an object.
+
+void
+TAO_ACE_Select_IO_Handler_Repository_Iterator::dump (void) const
+{
+ ACE_TRACE ("ACE_Select_Reactor_Handler_Repository_Iterator::dump");
+
+ /**
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("repo_ = %u"), this->repo_));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("current_ = %d"), this->current_));
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+ ***/
+}