diff options
author | bala <balanatarajan@users.noreply.github.com> | 2002-01-09 21:28:29 +0000 |
---|---|---|
committer | bala <balanatarajan@users.noreply.github.com> | 2002-01-09 21:28:29 +0000 |
commit | 8374ffc43bd97f8f24149fe696a52e78326b6c39 (patch) | |
tree | 6fd69dc515b89403be081c965b28a3b042b39159 | |
parent | dded420eb76f7bf2f0399cf6d088dcf918a5368d (diff) | |
download | ATCD-8374ffc43bd97f8f24149fe696a52e78326b6c39.tar.gz |
ChangeLogTag:Tue Jan 9 15:25:10 2002 Balachandran Natarajan <bala@cs.wustl.edu>
41 files changed, 2806 insertions, 0 deletions
diff --git a/TAO/tao_ace/Dev_Poll_IO_Handler_Repository.h b/TAO/tao_ace/Dev_Poll_IO_Handler_Repository.h new file mode 100644 index 00000000000..00c8805e161 --- /dev/null +++ b/TAO/tao_ace/Dev_Poll_IO_Handler_Repository.h @@ -0,0 +1,52 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Select_IO_Handler_Repository.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_DEV_POLL_IO_HANDLER_REPOSITORY_H +#define TAO_ACE_DEV_POLL_IO_HANDLER_REPOSITORY_H +#include "ace/pre.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +class Dev_Poll_IO_Handler_State: public TAO_ACE_IO_Handler_Repository::IO_Handler_State +{ +public: + + Dev_Poll_IO_Handler_State (void); + + /// Need to add mask and the suspend status... +}; + +/** + * @class TAO_ACE_Select_IO_Handler_Repository + * + * @brief Provides an abstract interface for handling socket events. + * + * @@ todo<Bala>: Write comments + */ + +class TAO_ACE_Export TAO_ACE_Dev_Poll_IO_Handler_Repository : public TAO_ACE_IO_Handler_Repository +{ +public: + + /// Ctor + TAO_ACE_Dev_Poll_IO_Handler_Repository (void); + +private: + + +}; + +#endif /*TAO_ACE_DEV_POLL_IO_HANDLER_REPOSITORY_H*/ diff --git a/TAO/tao_ace/Event_Dispatcher.cpp b/TAO/tao_ace/Event_Dispatcher.cpp new file mode 100644 index 00000000000..e25ee0aa1e6 --- /dev/null +++ b/TAO/tao_ace/Event_Dispatcher.cpp @@ -0,0 +1,54 @@ +#include "Event_Dispatcher.h" +#include "Event_Reactor_Impl.h" +#include "Event_Wait_Strategy.h" +#include "IO_Event_Handler.h" +#include "ace/Log_Msg.h" + +ACE_RCSID(tao_ace, Event_Dispatcher, "$Id$") + + +TAO_ACE_Event_Dispatcher::TAO_ACE_Event_Dispatcher ( + TAO_ACE_Event_Reactor_Impl *reactor) + : reactor_impl_ (reactor) +{ + +} + +int +TAO_ACE_Event_Dispatcher::dispatch_io_events ( + TAO_ACE_IO_Handler_Repository::IO_Handler_State &state, + TAO_ACE_IO_Event_Masks::Event_Masks &t) +{ + // If marked for deletion just return a -1. + if (state.marked_for_deletion_) + return -1; + + // Increase the thread count + ++state.thread_count_; + + int retval = + this->reactor_impl_->event_wait_strategy_->handler_repository ()->rebind_state (state); + + // Put the state object into the repository. + if (retval < 0) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) Rebind after change of state failed \n")); + + return -1; + } + + // @todo: Release the lock here.. + + // Make the callback + if (state.event_handler_->handle_event (t) < 0) + { + retval = + this->reactor_impl_->remove_io_handler (state.event_handler_, + t); + + return -1; + } + + return 0; +} diff --git a/TAO/tao_ace/Event_Dispatcher.h b/TAO/tao_ace/Event_Dispatcher.h new file mode 100644 index 00000000000..7b2f52232df --- /dev/null +++ b/TAO/tao_ace/Event_Dispatcher.h @@ -0,0 +1,56 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Event_Dispatcher.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_EVENT_DISPATCHER_H +#define TAO_ACE_EVENT_DISPATCHER_H +#include "ace/pre.h" + +#include "IO_Handler_Repository.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class TAO_ACE_Event_Reactor_Impl; + +/** + * @class TAO_ACE_Event_Dispatcher + * + * @brief Provides an interface for dispatching various types of event. + * + * This also hold the various strategies that are used for dispatching. + * + * @@ todo<Bala>: Write comments + */ + +class TAO_ACE_Export TAO_ACE_Event_Dispatcher +{ +public: + + TAO_ACE_Event_Dispatcher (TAO_ACE_Event_Reactor_Impl *reactor); + + + int dispatch_io_events (TAO_ACE_IO_Handler_Repository::IO_Handler_State &state, + TAO_ACE_IO_Event_Masks::Event_Masks &t); + + +private: + + TAO_ACE_Event_Reactor_Impl *reactor_impl_; + + /// Reference to the lock that the Reactor has + +}; + +#include "ace/post.h" +#endif /*TAO_ACE_EVENT_DISPATCHER_H*/ diff --git a/TAO/tao_ace/Event_Reactor.cpp b/TAO/tao_ace/Event_Reactor.cpp new file mode 100644 index 00000000000..544b4251d2b --- /dev/null +++ b/TAO/tao_ace/Event_Reactor.cpp @@ -0,0 +1,166 @@ +#include "Event_Reactor.h" +#include "Event_Reactor_Interface.h" +#include "Event_Reactor_Impl.h" +#include "ace/Object_Manager.h" +#include "ace/Synch.h" + + +#if !defined (__ACE_INLINE__) +#include "Event_Reactor.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(tao_ace, Event_Reactor, "$Id$") + +TAO_ACE_Event_Reactor::TAO_ACE_Event_Reactor ( + TAO_ACE_Event_Reactor_Interface *impl, + int delete_implementation) + : reactor_interface_ (impl), + delete_implementation_ (delete_implementation) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor::TAO_ACE_Event_Reactor"); + + if (this->reactor_interface_ == 0) + { + // For the present let us instantiate the only reactor we + // have. + ACE_NEW (this->reactor_interface_, + TAO_ACE_Event_Reactor_Impl ()); + this->delete_implementation_ = 1; + } +} + +TAO_ACE_Event_Reactor::TAO_ACE_Event_Reactor (void) + : reactor_interface_ (0), + delete_implementation_ (0) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor::TAO_ACE_Event_Reactor"); + + // For the present let us instantiate the only reactor we + // have. + ACE_NEW (this->reactor_interface_, + TAO_ACE_Event_Reactor_Impl ()); + this->delete_implementation_ = 1; +} + + +TAO_ACE_Event_Reactor::~TAO_ACE_Event_Reactor (void) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor::~TAO_ACE_Event_Reactor"); + if (this->delete_implementation_) + delete this->reactor_interface_; +} + +// Process-wide ACE_Reactor. +TAO_ACE_Event_Reactor *TAO_ACE_Event_Reactor::reactor_ = 0; + +// Controls whether the Reactor is deleted when we shut down (we can +// only delete it safely if we created it!) +int TAO_ACE_Event_Reactor::delete_reactor_ = 0; + + +TAO_ACE_Event_Reactor * +TAO_ACE_Event_Reactor::instance (void) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor::instance"); + + if (TAO_ACE_Event_Reactor::reactor_ == 0) + { + // Perform Double-Checked Locking Optimization. + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, + *ACE_Static_Object_Lock::instance (), 0)); + + if (TAO_ACE_Event_Reactor::reactor_ == 0) + { + ACE_NEW_RETURN (TAO_ACE_Event_Reactor::reactor_, + TAO_ACE_Event_Reactor, + 0); + TAO_ACE_Event_Reactor::delete_reactor_ = 1; + } + } + return TAO_ACE_Event_Reactor::reactor_; +} + +TAO_ACE_Event_Reactor * +TAO_ACE_Event_Reactor::instance (TAO_ACE_Event_Reactor *r, + int delete_reactor) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor::instance"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, + *ACE_Static_Object_Lock::instance (), 0)); + + TAO_ACE_Event_Reactor *t = TAO_ACE_Event_Reactor::reactor_; + if (delete_reactor != 0) + TAO_ACE_Event_Reactor::delete_reactor_ = 1; + else + // We can't safely delete it since we don't know who created it! + TAO_ACE_Event_Reactor::delete_reactor_ = 0; + + TAO_ACE_Event_Reactor::reactor_ = r; + return t; +} + +void +TAO_ACE_Event_Reactor::close_singleton (void) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor::close_singleton"); + + ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, + *ACE_Static_Object_Lock::instance ())); + + if (TAO_ACE_Event_Reactor::delete_reactor_) + { + delete TAO_ACE_Event_Reactor::reactor_; + TAO_ACE_Event_Reactor::reactor_ = 0; + TAO_ACE_Event_Reactor::delete_reactor_ = 0; + } +} + + +int +TAO_ACE_Event_Reactor::register_io_handler ( + TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor::register_io_handler"); + return this->reactor_interface_->register_io_handler (eh, + mask); +} + +int +TAO_ACE_Event_Reactor::remove_io_handler ( + TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor::register_io_handler"); + return this->reactor_interface_->remove_io_handler (eh, + mask); +} + +int +TAO_ACE_Event_Reactor::add_event_masks ( + TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor::add_event_masks"); + return this->reactor_interface_->add_event_masks (eh, + mask); +} + +int +TAO_ACE_Event_Reactor::clr_event_masks ( + TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor::clr_event_masks"); + return this->reactor_interface_->clr_event_masks (eh, + mask); +} + + +int +TAO_ACE_Event_Reactor::handle_events (ACE_Time_Value *time) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor::handle_events"); + return this->reactor_interface_->handle_events (time); +} diff --git a/TAO/tao_ace/Event_Reactor.h b/TAO/tao_ace/Event_Reactor.h new file mode 100644 index 00000000000..5440f953553 --- /dev/null +++ b/TAO/tao_ace/Event_Reactor.h @@ -0,0 +1,102 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Event_Reactor.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_EVENT_REACTOR_H +#define TAO_ACE_EVENT_REACTOR_H +#include "ace/pre.h" + +#include "IO_Event_Masks.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Global_Macros.h" + +/** + * @class TAO_ACE_Event_Reactor + * + * @brief Provides an abstract interface for + * + * @@ todo<Bala>: Write comments. + */ + +class TAO_ACE_Event_Reactor_Interface; +class TAO_ACE_IO_Event_Handler; +class ACE_Time_Value; + +class TAO_ACE_Export TAO_ACE_Event_Reactor +{ +public: + + TAO_ACE_Event_Reactor (TAO_ACE_Event_Reactor_Interface *interface, + int delete_impl = 0); + + TAO_ACE_Event_Reactor (void); + + ~TAO_ACE_Event_Reactor (void); + + /// Get pointer to a process-wide <ACE_Reactor>. + static TAO_ACE_Event_Reactor *instance (void); + + /** + * Set pointer to a process-wide <ACE_Reactor> and return existing + * pointer. If <delete_reactor> != 0 then we'll delete the Reactor + * at destruction time. + */ + static TAO_ACE_Event_Reactor *instance (TAO_ACE_Event_Reactor *, + int delete_reactor = 0); + + /// Delete the dynamically allocated Singleton + static void close_singleton (void); + + int register_io_handler (TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask); + + int remove_io_handler (TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask); + + int add_event_masks (TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask); + + int clr_event_masks (TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask); + + int handle_events (ACE_Time_Value *time); + + +private: + + TAO_ACE_Event_Reactor_Interface *reactor_interface_; + + int delete_implementation_; + + /// Pointer to a process-wide <ACE_Reactor> singleton. + static TAO_ACE_Event_Reactor *reactor_; + + /// Must delete the <reactor_> singleton if non-0. + static int delete_reactor_; + +private: + + /// Deny access since member-wise won't work... + ACE_UNIMPLEMENTED_FUNC (TAO_ACE_Event_Reactor (const TAO_ACE_Event_Reactor &)); + ACE_UNIMPLEMENTED_FUNC (TAO_ACE_Event_Reactor &operator = (const TAO_ACE_Event_Reactor &)); +}; + + +#if defined (__ACE_INLINE__) +#include "Event_Reactor.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" +#endif /*TAO_ACE_EVENT_REACTOR_H*/ diff --git a/TAO/tao_ace/Event_Reactor.inl b/TAO/tao_ace/Event_Reactor.inl new file mode 100644 index 00000000000..34b6d78d06d --- /dev/null +++ b/TAO/tao_ace/Event_Reactor.inl @@ -0,0 +1,2 @@ +/* -*- C++ -*- */ +//$Id$ diff --git a/TAO/tao_ace/Event_Reactor_Impl.cpp b/TAO/tao_ace/Event_Reactor_Impl.cpp new file mode 100644 index 00000000000..7fba0099d64 --- /dev/null +++ b/TAO/tao_ace/Event_Reactor_Impl.cpp @@ -0,0 +1,129 @@ +#include "Event_Reactor_Impl.h" +#include "Event_Wait_Strategy.h" +#include "IO_Handler_Repository.h" +#include "IO_Event_Handler.h" +#include "Event_Dispatcher.h" + +#if !defined (__ACE_INLINE__) +#include "Event_Reactor.inl" +#endif /* __ACE_INLINE__ */ + + +ACE_RCSID(tao_ace, Event_Reactor_Impl, "$Id$") + +TAO_ACE_Event_Reactor_Impl::TAO_ACE_Event_Reactor_Impl (void) + : event_wait_strategy_ (0) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor_Impl::TAO_ACE_Event_Reactor_Impl"); +} + +TAO_ACE_Event_Reactor_Impl::~TAO_ACE_Event_Reactor_Impl (void) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor_Impl::~TAO_ACE_Event_Reactor_Impl"); +} + +int +TAO_ACE_Event_Reactor_Impl::register_io_handler ( + TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor_Impl::register_io_handler"); + + // @todo: Lock?? + + return this->event_wait_strategy_->handler_repository ()->bind (eh, + mask); +} + +int +TAO_ACE_Event_Reactor_Impl::remove_io_handler ( + TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor_Impl::remove_io_handler"); + + // @todo: Lock?? + return this->event_wait_strategy_->handler_repository ()->unbind (eh, + mask); + + // We need to call handle_close () or some such thing here +} + +int +TAO_ACE_Event_Reactor_Impl::add_event_masks ( + TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor_Impl::add_event_masks"); + + // @todo: Lock?? + return this->event_wait_strategy_->handler_repository ()->add_masks + (eh->get_handle (), + mask); +} + +int +TAO_ACE_Event_Reactor_Impl::clr_event_masks ( + TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask) +{ + ACE_TRACE ("TAO_ACE_Event_Reactor_Impl::clr_event_masks"); + + // @todo: Lock?? + return this->event_wait_strategy_->handler_repository ()->clr_masks + (eh->get_handle (), + mask); +} + + +int +TAO_ACE_Event_Reactor_Impl::handle_events (ACE_Time_Value * max_wait_time) +{ + // @@todo: Lock + + // Wait for events to arrive.. + + int retval = + this->event_wait_strategy_->wait_for_multiple_events (max_wait_time); + + + // Handle timer events here + + // Handle IO events + retval = this->handle_io_events (); + return 0; +} + + + +int +TAO_ACE_Event_Reactor_Impl::handle_io_events (void) +{ + + TAO_ACE_IO_Event_Masks::Event_Masks t = + TAO_ACE_IO_Event_Masks::NULL_MASK; + + // Select an event to dispatch + ACE_HANDLE h = + this->event_wait_strategy_->dispatchable_io_event (t); + + // Get the handle state + TAO_ACE_IO_Handler_Repository::IO_Handler_State state; + + int retval = + this->event_wait_strategy_->handler_repository ()->find_state (h, + state); + + // Error in finding state + if (retval == -1) + return retval; + + if (state.marked_for_deletion_ == 0) + { + // Hand the handler state off to the dispatcher + retval = + this->event_dispatcher_->dispatch_io_events ( + state, + t); + } +} diff --git a/TAO/tao_ace/Event_Reactor_Impl.h b/TAO/tao_ace/Event_Reactor_Impl.h new file mode 100644 index 00000000000..edf43aecc7a --- /dev/null +++ b/TAO/tao_ace/Event_Reactor_Impl.h @@ -0,0 +1,82 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Event_Reactor_Impl.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_EVENT_REACTOR_IMPLEMENTATION_H +#define TAO_ACE_EVENT_REACTOR_IMPLEMENTATION_H +#include "ace/pre.h" +#include "Event_Reactor_Interface.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + + + +class TAO_ACE_IO_Event_Handler; +class TAO_ACE_Event_Wait_Strategy; +class TAO_ACE_Event_Dispatcher; + +/** + * @class TAO_ACE_Event_Reactor_Impl + * + * @brief Provides an abstract interface for + * + * @@ todo<Bala>: Write comments. + */ + +class TAO_ACE_Export TAO_ACE_Event_Reactor_Impl: public TAO_ACE_Event_Reactor_Interface +{ +public: + + friend class TAO_ACE_Event_Dispatcher; + + TAO_ACE_Event_Reactor_Impl (void); + + ~TAO_ACE_Event_Reactor_Impl (void); + + int register_io_handler ( + TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask); + + int remove_io_handler ( + TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask); + + int add_event_masks ( + TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask); + + int clr_event_masks ( + TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask); + + int handle_events (ACE_Time_Value *time); + +private: + + int handle_io_events (void); + +private: + + TAO_ACE_Event_Wait_Strategy *event_wait_strategy_; + + TAO_ACE_Event_Dispatcher *event_dispatcher_; +}; + +#if defined (__ACE_INLINE__) +#include "Event_Reactor_Impl.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" +#endif /*TAO_ACE_EVENT_REACTOR_IMPLEMENTATION_H*/ diff --git a/TAO/tao_ace/Event_Reactor_Impl.inl b/TAO/tao_ace/Event_Reactor_Impl.inl new file mode 100644 index 00000000000..34b6d78d06d --- /dev/null +++ b/TAO/tao_ace/Event_Reactor_Impl.inl @@ -0,0 +1,2 @@ +/* -*- C++ -*- */ +//$Id$ diff --git a/TAO/tao_ace/Event_Reactor_Interface.cpp b/TAO/tao_ace/Event_Reactor_Interface.cpp new file mode 100644 index 00000000000..d0734ce2f6e --- /dev/null +++ b/TAO/tao_ace/Event_Reactor_Interface.cpp @@ -0,0 +1,10 @@ +#include "Event_Reactor_Interface.h" + + + +ACE_RCSID(tao_ace, Event_Reactor_Interface, "$Id$") + + +TAO_ACE_Event_Reactor_Interface::~TAO_ACE_Event_Reactor_Interface (void) +{ +} diff --git a/TAO/tao_ace/Event_Reactor_Interface.h b/TAO/tao_ace/Event_Reactor_Interface.h new file mode 100644 index 00000000000..204710707ed --- /dev/null +++ b/TAO/tao_ace/Event_Reactor_Interface.h @@ -0,0 +1,61 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Event_Reactor_Interface.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_EVENT_REACTOR_INTERFACE_H +#define TAO_ACE_EVENT_REACTOR_INTERFACE_H +#include "ace/pre.h" +#include "IO_Event_Masks.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class TAO_ACE_IO_Event_Handler; +class ACE_Time_Value; + +/** + * @class TAO_ACE_Event_Reactor_Interface + * + * @brief Provides an abstract interface for + * + * @@ todo<Bala>: Write comments. + */ + +class TAO_ACE_Export TAO_ACE_Event_Reactor_Interface +{ +public: + + virtual ~TAO_ACE_Event_Reactor_Interface (void); + + virtual int register_io_handler ( + TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask) = 0; + + virtual int remove_io_handler ( + TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask) = 0; + + virtual int add_event_masks ( + TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask) = 0; + + virtual int clr_event_masks ( + TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask) = 0; + + virtual int handle_events (ACE_Time_Value *time) = 0; + +}; + + +#include "ace/post.h" +#endif /*TAO_ACE_EVENT_REACTOR_INTERFACE_H*/ diff --git a/TAO/tao_ace/Event_Selection_Strategy.h b/TAO/tao_ace/Event_Selection_Strategy.h new file mode 100644 index 00000000000..0eac4d2ffdb --- /dev/null +++ b/TAO/tao_ace/Event_Selection_Strategy.h @@ -0,0 +1,52 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Event_Selection_Strategy.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_EVENT_SELECTION_STRATEGY_H +#define TAO_ACE_EVENT_SELECTION_STRATEGY_H +#include "ace/pre.h" + +#include "IO_Event_Masks.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class TAO_ACE_Event_Selection_Strategy + * + * @brief Provides an abstract interface for + * + * @todo: If the footprint blows up it could be because of this class + * where we inherit from Service_Object + * @@ todo<Bala>: Write comments. + */ + +class TAO_ACE_Export TAO_ACE_Event_Selection_Strategy +{ +public: + + virtual int event_reselect (void) = 0; + + virtual ACE_HANDLE dispatchable_io_event ( + TAO_ACE_IO_Event_Masks::Event_Masks &t) = 0; + +protected: + + TAO_ACE_Event_Selection_Strategy (void); + +private: + +}; + +#include "ace/post.h" +#endif /*TAO_ACE_EVENT_SLECETION_STRATEGY */ diff --git a/TAO/tao_ace/Event_Wait_Strategy.cpp b/TAO/tao_ace/Event_Wait_Strategy.cpp new file mode 100644 index 00000000000..88e68539e34 --- /dev/null +++ b/TAO/tao_ace/Event_Wait_Strategy.cpp @@ -0,0 +1,22 @@ +#include "Event_Wait_Strategy.h" + + +#if !defined (__ACE_INLINE__) +#include "Event_Wait_Strategy.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(tao_ace, Event_Wait_Strategy, "$Id$") + + +TAO_ACE_Event_Wait_Strategy::~TAO_ACE_Event_Wait_Strategy (void) +{ + ACE_TRACE ("TAO_ACE_Event_Wait_Strategy::Destructor"); +} + +int +TAO_ACE_Event_Wait_Strategy::wait_for_multiple_events (ACE_Time_Value *) +{ + ACE_TRACE ("TAO_ACE_Event_Wait_Strategy::wait_for_multiple_events"); + + return 0; +} diff --git a/TAO/tao_ace/Event_Wait_Strategy.h b/TAO/tao_ace/Event_Wait_Strategy.h new file mode 100644 index 00000000000..cc03adef096 --- /dev/null +++ b/TAO/tao_ace/Event_Wait_Strategy.h @@ -0,0 +1,71 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Event_Wait_Strategy.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_EVENT_WAIT_STRATEGY_H +#define TAO_ACE_EVENT_WAIT_STRATEGY_H +#include "ace/pre.h" +#include "TAO_ACE_export.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ +#include "IO_Event_Masks.h" +#include "ace/Global_Macros.h" + + +class TAO_ACE_IO_Handler_Repository; +class ACE_Time_Value; +class TAO_ACE_Event_Selection_Strategy; + +/** + * @class TAO_ACE_Event_Wait_Strategy + * + * @brief Provides an abstract interface for + * + * @todo: If the footprint blows up it could be because of this class + * where we inherit from Service_Object + * @@ todo<Bala>: Write comments. + */ + +class TAO_ACE_Export TAO_ACE_Event_Wait_Strategy +{ +public: + + virtual ~TAO_ACE_Event_Wait_Strategy (void); + + virtual int wait_for_multiple_events (ACE_Time_Value *time = 0); + + + virtual TAO_ACE_IO_Handler_Repository *handler_repository (void) = 0; + + virtual ACE_HANDLE dispatchable_io_event ( + TAO_ACE_IO_Event_Masks::Event_Masks &t) = 0; + +protected: + + TAO_ACE_Event_Wait_Strategy (void); + + TAO_ACE_Event_Selection_Strategy *event_selection_strategy_; + +private: + + +}; + + +#if defined (__ACE_INLINE__) +#include "Event_Wait_Strategy.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" +#endif /*TAO_ACE_EVENT_WAIT_STRATEGY_H*/ diff --git a/TAO/tao_ace/Event_Wait_Strategy.inl b/TAO/tao_ace/Event_Wait_Strategy.inl new file mode 100644 index 00000000000..b314dd7eeca --- /dev/null +++ b/TAO/tao_ace/Event_Wait_Strategy.inl @@ -0,0 +1,8 @@ +/* -*- C++ -*- */ +//$Id$ +/*protected*/ +ACE_INLINE +TAO_ACE_Event_Wait_Strategy::TAO_ACE_Event_Wait_Strategy (void) +{ + // ACE_TRACE ("TAO_ACE_Event_Wait_Strategy::TAO_ACE_Event_Wait_Strategy"); +} diff --git a/TAO/tao_ace/Fair_Perf_Selection_Strategy.cpp b/TAO/tao_ace/Fair_Perf_Selection_Strategy.cpp new file mode 100644 index 00000000000..ba5a1c13809 --- /dev/null +++ b/TAO/tao_ace/Fair_Perf_Selection_Strategy.cpp @@ -0,0 +1,23 @@ +#include "Fair_Perf_Selection_Strategy.h" + +#if !defined (__ACE_INLINE__) +#include "Fair_Performance_Selection_Strategy.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(tao_ace, Fair_Perf_Selection_Strategy, "$Id$") + + +int +TAO_ACE_Fair_Perf_Selection_Strategy:event_reselect (void) +{ + return 0; +} + + +ACE_HANDLE +TAO_ACE_Fair_Perf_Selection_Strategy::dispatchable_io_event ( + TAO_ACE_Select_Strategy_Handle_Set & /*io_set*/, + TAO_ACE_Event_Masks::Event_Masks & /*t*/) +{ + ACE_NOTSUP_RETURN (ACE_INVALID_HANDLE); +} diff --git a/TAO/tao_ace/Fair_Perf_Selection_Strategy.h b/TAO/tao_ace/Fair_Perf_Selection_Strategy.h new file mode 100644 index 00000000000..4d753ffbd6b --- /dev/null +++ b/TAO/tao_ace/Fair_Perf_Selection_Strategy.h @@ -0,0 +1,55 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Fair_Perf_Selection_Strategy.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_FAIR_PERF_SELECTION_STRATEGY_H +#define TAO_ACE_FAIR_PERF_SELECTION_STRATEGY_H +#include "ace/pre.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class TAO_ACE_Fair_Perf_Selection_Strategy + * + * @brief Provides an abstract interface for + * + * @todo: If the footprint blows up it could be because of this class + * where we inherit from Service_Object + * @@ todo<Bala>: Write comments. + */ + +class TAO_ACE_Export TAO_ACE_Fair_Perf_Selection_Strategy : public TAO_ACE_Event_Selection_Strategy +{ +public: + + virtual int event_reselect (void); + + virtual ACE_HANDLE dispatchable_io_event ( + TAO_ACE_Event_Masks::Event_Masks &t); + + +protected: + + + +}; + + + +#if defined (__ACE_INLINE__) +#include "Fair_Perf_Selection_Strategy.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" +#endif/*TAO_ACE_FAIR_PERF_SELECTION_STRATEGY*/ diff --git a/TAO/tao_ace/Fair_Perf_Selection_Strategy.inl b/TAO/tao_ace/Fair_Perf_Selection_Strategy.inl new file mode 100644 index 00000000000..34b6d78d06d --- /dev/null +++ b/TAO/tao_ace/Fair_Perf_Selection_Strategy.inl @@ -0,0 +1,2 @@ +/* -*- C++ -*- */ +//$Id$ diff --git a/TAO/tao_ace/IO_Event_Handler.cpp b/TAO/tao_ace/IO_Event_Handler.cpp new file mode 100644 index 00000000000..e59325ebd58 --- /dev/null +++ b/TAO/tao_ace/IO_Event_Handler.cpp @@ -0,0 +1,30 @@ +#include "IO_Event_Handler.h" + + +ACE_RCSID(tao_ace, IO_Event_Handler, "$Id$") + + +int +TAO_ACE_IO_Event_Handler::handle_event (TAO_ACE_IO_Event_Masks::Event_Masks t) +{ + ACE_TRACE ("TAO_ACE_IO_Event_Handler::handle_event"); + + switch (t) + { + case TAO_ACE_IO_Event_Masks::CONNECT_MASK: + case TAO_ACE_IO_Event_Masks::WRITE_MASK: + return this->handle_output (this->get_handle ()); + + case TAO_ACE_IO_Event_Masks::ACCEPT_MASK: + case TAO_ACE_IO_Event_Masks::READ_MASK: + return this->handle_input (this->get_handle ()); + + case TAO_ACE_IO_Event_Masks::EXCEPT_MASK: + return this->handle_exception (this->get_handle ()); + default: + return 0; + } + + // default, if it is a NULL mask or anything else + return 0; +} diff --git a/TAO/tao_ace/IO_Event_Handler.h b/TAO/tao_ace/IO_Event_Handler.h new file mode 100644 index 00000000000..c165b6cb42b --- /dev/null +++ b/TAO/tao_ace/IO_Event_Handler.h @@ -0,0 +1,68 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file IO_Event_Handler.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_IO_EVENT_HANDLER_H +#define TAO_ACE_IO_EVENT_HANDLER_H +#include "ace/pre.h" +#include "IO_Event_Masks.h" + + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "Reactive_Handler.h" + +/** + * @class TAO_ACE_IO_Event_Handler + * + * @brief Provides an abstract interface for handling socket events. + * + * @@ todo<Bala>: Write comments + */ + +class TAO_ACE_Export TAO_ACE_IO_Event_Handler: public TAO_ACE_Reactive_Handler +{ +public: + + + /* Callback function that invokes the right callback method based + * on the type of mask that is passed via <t>. The mask should + * indicate only one event. Sending a bitwise 'or' or 'and' of many + * events will lead to none of the events being handled. + */ + virtual int handle_event (TAO_ACE_IO_Event_Masks::Event_Masks t = + TAO_ACE_IO_Event_Masks::NULL_MASK); + + /// Get/Set the handle of the underlying socket + virtual ACE_HANDLE get_handle (void) = 0; + virtual void set_handle (ACE_HANDLE h) = 0; +protected: + + /// Called when input events occur (e.g., connection or data). + virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE) = 0; + + /// Called when output events are possible (e.g., when flow control + /// abates or non-blocking connection completes). + virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE) = 0; + + /// Called when an exceptional events occur (e.g., SIGURG). + virtual int handle_exception (ACE_HANDLE fd = ACE_INVALID_HANDLE) = 0; + +private: + +}; + + +#include "ace/post.h" +#endif /*TAO_ACE_IO_EVENT_HANDLER_H*/ diff --git a/TAO/tao_ace/IO_Event_Masks.h b/TAO/tao_ace/IO_Event_Masks.h new file mode 100644 index 00000000000..b968b0f73cc --- /dev/null +++ b/TAO/tao_ace/IO_Event_Masks.h @@ -0,0 +1,68 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file IO_Event_Masks.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_IO_EVENT_MASKS_H +#define TAO_ACE_IO_EVENT_MASKS_H +#include "ace/pre.h" +#include "TAO_ACE_export.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class TAO_ACE_IO_Event_Masks + * + * @brief Provides an abstract interface for handling socket events. + * + * @@ todo<Bala>: Write comments + */ + +class TAO_ACE_Export TAO_ACE_IO_Event_Masks +{ + +public: + enum + { + NULL_MASK = 0, +#if defined (ACE_USE_POLL) + READ_MASK = POLLIN, + WRITE_MASK = POLLOUT, + EXCEPT_MASK = POLLPRI, +#else /* USE SELECT */ + READ_MASK = (1 << 0), + WRITE_MASK = (1 << 1), + EXCEPT_MASK = (1 << 2), +#endif /* ACE_USE_POLL */ + ACCEPT_MASK = (1 << 3), + CONNECT_MASK = (1 << 4), + ALL_EVENTS_MASK = READ_MASK | + WRITE_MASK | + EXCEPT_MASK | + ACCEPT_MASK | + CONNECT_MASK , + RWE_MASK = READ_MASK | + WRITE_MASK | + EXCEPT_MASK, + // Mask to indicate that the reactor should not make an upcall + // associated with any event if this mask is present. + DONT_CALL = (1 << 5) + }; + + typedef unsigned long Event_Masks; +}; + + + +#include "ace/post.h" +#endif /*TAO_ACE_IO_EVENET_MASKS*/ diff --git a/TAO/tao_ace/IO_Handler_Repository.cpp b/TAO/tao_ace/IO_Handler_Repository.cpp new file mode 100644 index 00000000000..1b5ac902de7 --- /dev/null +++ b/TAO/tao_ace/IO_Handler_Repository.cpp @@ -0,0 +1,16 @@ +#include "IO_Handler_Repository.h" + + +#if !defined (__ACE_INLINE__) +#include "IO_Handler_Repository.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(tao_ace, SOCK_Event_Reactive_Handler, "$Id$") + + +TAO_ACE_IO_Handler_Repository::IO_Handler_State::IO_Handler_State (void) + : thread_count_ (0), + marked_for_deletion_ (0), + event_handler_ (0) +{ +} diff --git a/TAO/tao_ace/IO_Handler_Repository.h b/TAO/tao_ace/IO_Handler_Repository.h new file mode 100644 index 00000000000..bb47b118279 --- /dev/null +++ b/TAO/tao_ace/IO_Handler_Repository.h @@ -0,0 +1,101 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file IO_Handler_Repository.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_IO_HANDLER_REPOSITORY_H +#define TAO_ACE_IO_HANDLER_REPOSITORY_H +#include "ace/pre.h" +#include "TAO_ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "IO_Event_Masks.h" +#include "ace/Global_Macros.h" + +class TAO_ACE_IO_Event_Handler; + + +/** + * @class TAO_ACE_IO_Handler_Repository + * + * @brief Provides an abstract interface for handling socket events. + * + * @@ todo<Bala>: Write comments + */ + +class TAO_ACE_Export TAO_ACE_IO_Handler_Repository +{ +public: + + virtual ~TAO_ACE_IO_Handler_Repository (void) = 0; + + class IO_Handler_State + { + public: + + /// Ctor + IO_Handler_State (void); + + /// Number of threads actually dispatched to the socket handler + long thread_count_; + + /// Has the handler been marked for deletion? + int marked_for_deletion_; + + + /// The IO event handler + TAO_ACE_IO_Event_Handler *event_handler_; + }; + + + /// Some common methods go here.. + + virtual int bind (TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask) = 0; + + + virtual int unbind (TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask) = 0; + + + virtual int add_masks (ACE_HANDLE io, + TAO_ACE_IO_Event_Masks::Event_Masks mask) = 0; + + + virtual int clr_masks (ACE_HANDLE io, + TAO_ACE_IO_Event_Masks::Event_Masks mask) = 0; + + virtual int find_state (ACE_HANDLE h, + TAO_ACE_IO_Handler_Repository::IO_Handler_State &st) = 0; + + virtual int rebind_state ( + TAO_ACE_IO_Handler_Repository::IO_Handler_State &st) = 0; + +protected: + + /// @todo: Cant this be defined here? + virtual int is_handle_valid (ACE_HANDLE handle) = 0; + +private: + + ACE_UNIMPLEMENTED_FUNC (void operator= (const TAO_ACE_IO_Handler_Repository &)); +}; + + +#if defined (__ACE_INLINE__) +#include "IO_Handler_Repository.inl" +#endif /* __ACE_INLINE__ */ + + +#include "ace/post.h" +#endif /*TAO_ACE_IO_HANDLER_REPOSITORY_H*/ diff --git a/TAO/tao_ace/IO_Handler_Repository.inl b/TAO/tao_ace/IO_Handler_Repository.inl new file mode 100644 index 00000000000..34b6d78d06d --- /dev/null +++ b/TAO/tao_ace/IO_Handler_Repository.inl @@ -0,0 +1,2 @@ +/* -*- C++ -*- */ +//$Id$ diff --git a/TAO/tao_ace/IO_Handler_State.cpp b/TAO/tao_ace/IO_Handler_State.cpp new file mode 100644 index 00000000000..e139de519c6 --- /dev/null +++ b/TAO/tao_ace/IO_Handler_State.cpp @@ -0,0 +1,3 @@ +#include "IO_Handler_State.h" + +ACE_RCSID(tao_ace, SOCK_Event_Reactive_Handler, "$Id$") diff --git a/TAO/tao_ace/IO_Handler_State.h b/TAO/tao_ace/IO_Handler_State.h new file mode 100644 index 00000000000..b862261049c --- /dev/null +++ b/TAO/tao_ace/IO_Handler_State.h @@ -0,0 +1,53 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file IO_Handler_State.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_IO_HANDLER_STATE_H +#define TAO_ACE_IO_HANDLER_STATE_H +#include "ace/pre.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class TAO_ACE_IO_Event_Handler; + + +/** + * @class TAO_ACE_IO_Handler_State + * + * @brief Provides an abstract interface for handling socket events. + * + * @@ todo<Bala>: Write comments + */ + +class TAO_ACE_Export TAO_ACE_IO_Handler_State +{ +public: + + /// Ctor + TAO_ACE_IO_Handler_State (void); + + /// Number of threads actually dispatched to the socket handler + long thread_count_; + + /// Has the handler been marked for deletion? + int marked_for_deletion_; + + + /// The IO event handler + TAO_ACE_IO_Event_Handler *event_handler_; +}; + + +#include "ace/post.h" +#endif /*TAO_ACE_IO_HANDLER_STATE_H*/ diff --git a/TAO/tao_ace/IO_Peer_Handler.cpp b/TAO/tao_ace/IO_Peer_Handler.cpp new file mode 100644 index 00000000000..92ce386dfaf --- /dev/null +++ b/TAO/tao_ace/IO_Peer_Handler.cpp @@ -0,0 +1,65 @@ +#include "IO_Peer_Handler.h" + + +#if !defined (__ACE_INLINE__) +#include "IO_Peer_Handler.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(tao_ace, SOCK_Event_Reactive_Handler, "$Id$") + +#define PR_ST_1 ACE_PEER_STREAM_1 +#define PR_ST_2 ACE_PEER_STREAM_2 + +template <PR_ST_1> +TAO_ACE_IO_Peer_Handler<PR_ST_2>::TAO_ACE_IO_Peer_Handler (void) +{ + ACE_TRACE ("TAO_ACE_IO_Peer_Handler::TAO_ACE_IO_Peer_Handler"); +} + + + +template <PR_ST_1> ACE_HANDLE +TAO_ACE_IO_Peer_Handler<PR_ST_2>::get_handle (void) const +{ + ACE_TRACE ("TAO_ACE_SOCK_Peer_Handler::get_handle"); + return this->peer_.get_handle (); +} + +template <PR_ST_1> void +TAO_ACE_IO_Peer_Handler<PR_ST_2>::set_handle (ACE_HANDLE h) +{ + ACE_TRACE ("TAO_ACE_SOCK_Peer_Handler::set_handle"); + this->peer_->set_handle (h); +} + +template <PR_ST_1> ACE_PEER_STREAM & +TAO_ACE_IO_Peer_Handler<PR_ST_2>::peer (void) const +{ + ACE_TRACE ("TAO_ACE_SOCK_Peer_Handler::peer"); + return (ACE_PEER_STREAM &) this->peer_; +} + + +template <PR_ST_1> int +TAO_ACE_IO_Peer_Handler<PR_ST_2>::handle_input (ACE_HANDLE) +{ + ACE_TRACE ("TAO_ACE_SOCK_Peer_Handler::handle_input"); + + return 0; +} + +template <PR_ST_1> int +TAO_ACE_IO_Peer_Handler<PR_ST_2>::handle_output (ACE_HANDLE) +{ + ACE_TRACE ("TAO_ACE_SOCK_Peer_Handler::handle_output"); + + return 0; +} + +template <PR_ST_1> int +TAO_ACE_IO_Peer_Handler<PR_ST_2>::handle_exception (ACE_HANDLE) +{ + ACE_TRACE ("TAO_ACE_SOCK_Peer_Handler::handle_exception"); + + return 0; +} diff --git a/TAO/tao_ace/IO_Peer_Handler.h b/TAO/tao_ace/IO_Peer_Handler.h new file mode 100644 index 00000000000..42b8abb7d25 --- /dev/null +++ b/TAO/tao_ace/IO_Peer_Handler.h @@ -0,0 +1,72 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file IO_Peer_Handler.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_IO_PEER_HANDLER_H +#define TAO_ACE_IO_PEER_HANDLER_H +#include "ace/pre.h" + +#include "IO_Event_Handler.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +/** + * @class TAO_ACE_IO_Peer_Handler + * + * @brief Provides an abstract interface for handling socket events. + * + * @@ todo<Bala>: Write comments + */ + +template <ACE_PEER_STREAM_1> +class TAO_ACE_Export TAO_ACE_IO_Peer_Handler: public TAO_ACE_IO_Event_Handler +{ +public: + + /// Ctor + TAO_ACE_IO_Peer_Handler (void); + + /// Return the underlying peer stream + ACE_PEER_STREAM &peer (void) const; + + /// Get/Set the handle of the underlying socket + ACE_HANDLE get_handle (void) const; + void set_handle (ACE_HANDLE h); + +protected: + + /// Called when input events occur (e.g., connection or data). + virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE); + + /// Called when output events are possible (e.g., when flow control + /// abates or non-blocking connection completes). + virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE); + + /// Called when an exceptional events occur (e.g., SIGURG). + virtual int handle_exception (ACE_HANDLE fd = ACE_INVALID_HANDLE); + +private: + + /// Maintain connection with peer + ACE_PEER_STREAM peer_; +}; + + + +#if defined (__ACE_INLINE__) +#include "IO_Peer_Handler.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" +#endif /*TAO_ACE_IO_PEER_HANDLER_H*/ diff --git a/TAO/tao_ace/IO_Peer_Handler.inl b/TAO/tao_ace/IO_Peer_Handler.inl new file mode 100644 index 00000000000..34b6d78d06d --- /dev/null +++ b/TAO/tao_ace/IO_Peer_Handler.inl @@ -0,0 +1,2 @@ +/* -*- C++ -*- */ +//$Id$ diff --git a/TAO/tao_ace/Reactive_Handler.cpp b/TAO/tao_ace/Reactive_Handler.cpp new file mode 100644 index 00000000000..0153344ca26 --- /dev/null +++ b/TAO/tao_ace/Reactive_Handler.cpp @@ -0,0 +1,23 @@ +#include "Reactive_Handler.h" + + +#if !defined (__ACE_INLINE__) +#include "Reactive_Handler.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(tao_ace, Reactive_Handler, "$Id$") + +TAO_ACE_Reactive_Handler::TAO_ACE_Reactive_Handler (long priority) + : ref_count_ (), + priority_ (priority) +{ + ACE_TRACE ("TAO_ACE_Reactive_Handler::TAO_ACE_Reactive_Handler"); + // Set the reference count to be 1. Doing so we implicitly assume + // that our creator has a refernce to us, whoever it may be. + this->ref_count_ = 1; +} + +TAO_ACE_Reactive_Handler::~TAO_ACE_Reactive_Handler (void) +{ + ACE_TRACE ("TAO_ACE_Reactive_Handler::~TAO_ACE_Reactive_Handler"); +} diff --git a/TAO/tao_ace/Reactive_Handler.h b/TAO/tao_ace/Reactive_Handler.h new file mode 100644 index 00000000000..4803dfa3080 --- /dev/null +++ b/TAO/tao_ace/Reactive_Handler.h @@ -0,0 +1,99 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Reactive_Handler.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_REACTIVE_HANDLER_H +#define TAO_ACE_REACTIVE_HANDLER_H +#include "ace/pre.h" +#include "ace/Atomic_Op.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "TAO_ACE_export.h" + +/** + * @class TAO_ACE_Reactive_Handler + * + * @brief Provides an abstract interface for handling various types of + * Events. + * + * @@ todo<Bala>: Write comments + */ + +class TAO_ACE_Export TAO_ACE_Reactive_Handler +{ +public: + /// Priority as per the CORBA spec. + enum + { + MIN_PRIORITY = 0, + MAX_PRIORITY = 32767 + }; + + /// Destructor is virtual to enable proper cleanup + virtual ~TAO_ACE_Reactive_Handler (void); + + /// Incr/Decr reference counts and return the value of the reference + /// counts. + long incr_ref_count (void); + long decr_ref_count (void); + + /// return the value of the refcount + long refcount (void) const; + + // = Get/set priority + /* Priorities run from MIN_PRIORITY (which is the "lowest priority") + * to MAX_PRIORITY (which is the "highest priority"). The set method + * does error checking and sets priority only in the range of MIN to + * MAX priorities. + * @todo: Need to investigate whether we get anything by putting the + * priority in the base class. + */ + long priority (void) const; + void priority (long priority); + +protected: + + /* Constructor is protected so that this class cannot be + * instantiated by anyone + */ + TAO_ACE_Reactive_Handler (long priority = + TAO_ACE_Reactive_Handler::MIN_PRIORITY); + +private: + + /// Utility typedef + typedef ACE_Atomic_Op <ACE_SYNCH_MUTEX, long> Atomic_Counter; + + /* Reference count for memory management. Object of this class will + * be created with reference count of 1, implying that the creator + * owns us. If he transfers ownership to someone else, the other + * person should increment the refcount and the creator should + * decrement the refcount. This object will be deleted when the + * refcount goes to 0. + */ + Atomic_Counter ref_count_; + + /// Priority of the handler + long priority_; +}; + + +#if defined (__ACE_INLINE__) +#include "Reactive_Handler.inl" +#endif /* __ACE_INLINE__ */ + + +#include "ace/post.h" +#endif /*TAO_ACE_REACTIVE_HANDLER*/ diff --git a/TAO/tao_ace/Reactive_Handler.inl b/TAO/tao_ace/Reactive_Handler.inl new file mode 100644 index 00000000000..df65a2494c4 --- /dev/null +++ b/TAO/tao_ace/Reactive_Handler.inl @@ -0,0 +1,50 @@ +/* -*- C++ -*- */ +//$Id$ +ACE_INLINE long +TAO_ACE_Reactive_Handler::incr_ref_count (void) +{ + ACE_TRACE ("TAO_ACE_Reactive_Handler::incr_ref_count"); + + return ++this->ref_count_; +} + + +ACE_INLINE long +TAO_ACE_Reactive_Handler::decr_ref_count (void) +{ + ACE_TRACE ("TAO_ACE_Reactive_Handler::decr_ref_count"); + --this->ref_count_; + + // Delete the object if the reference count goes yo 0. + if (this->ref_count_ == 0) + { + delete this; + return 0; + } + + return this->ref_count_.value (); +} + +ACE_INLINE long +TAO_ACE_Reactive_Handler::refcount (void) const +{ + ACE_TRACE ("TAO_ACE_Reactive_Handler::refcount"); + return this->ref_count_.value (); +} + +ACE_INLINE long +TAO_ACE_Reactive_Handler::priority (void) const +{ + ACE_TRACE ("TAO_ACE_Reactive_Handler::priority"); + return this->priority_; +} + +ACE_INLINE void +TAO_ACE_Reactive_Handler::priority (long priority) +{ + ACE_TRACE ("TAO_ACE_Reactive_Handler::priority"); + + if (priority < TAO_ACE_Reactive_Handler::MAX_PRIORITY && + priority > TAO_ACE_Reactive_Handler::MIN_PRIORITY) + this->priority_ = priority; +} diff --git a/TAO/tao_ace/Select_Fair_Perf_Strategy.cpp b/TAO/tao_ace/Select_Fair_Perf_Strategy.cpp new file mode 100644 index 00000000000..007d8487204 --- /dev/null +++ b/TAO/tao_ace/Select_Fair_Perf_Strategy.cpp @@ -0,0 +1,89 @@ +#include "Select_Fair_Perf_Strategy.h" + +#if !defined (__ACE_INLINE__) +#include "Select_Fair_Perf_Strategy.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(tao_ace, Select_Fair_Perf_Strategy, "$Id$") + + +ACE_HANDLE +TAO_ACE_Fair_Perf_Selection_Strategy::dispatchable_io_event ( + TAO_ACE_Event_Masks::Event_Masks &t) +{ + ACE_HANDLE handle = ACE_INVALID_HANDLE; + + // Iterate through the write masks first + handle = + this->iterate (this->wr_mask_iter_) + + if (handle != ACE_INVALID_HANDLE) + { + t = TAO_ACE_Event_Masks::WRITE_MASK; + return handle; + } + + // Just reset the state of the <wr_mask_iter_> + this->wr_mask_iter_.reset_state (); + + + // Iterate through the exception mask next + handle = + this->iterate (this->ex_mask_iter_); + + + if (handle != ACE_INVALID_HANDLE) + { + t = TAO_ACE_Event_Masks::EXCEPT_MASK; + return handle; + } + + // Just reset the state of the <ex_mask_iter_> + this->ex_mask_iter_.reset_state (); + + + // Iterate through the read mask next + handle = + this->iterate (this->rd_mask_iter_); + + + if (handle != ACE_INVALID_HANDLE) + { + t = TAO_ACE_Event_Masks::READ_MASK; + return handle; + } + + // Just reset the state of the <wr_mask_iter_> + this->rd_mask_iter_.reset_state (); + + return handle; +} + + + + +void +TAO_ACE_Select_Fair_Perf_Strategy::clear_handle ( + ACE_HANDLE handle) +{ + this->read_handle_set_.wr_mask_.clr_bit (handle); + this->read_handle_set_.ex_mask_.clr_bit (handle); + this->read_handle_set_.rd_mask_.clr_bit (handle); +} + + +ACE_HANDLE +TAO_ACE_Select_Fair_Perf_Strategy::iterate ( + ACE_Handle_Set_Iterator &handle_iter) +{ + ACE_HANDLE handle = ACE_INVALID_HANDLE; + while ((handle = handle_iter ()) != ACE_INVALID_HANDLE) + { + this->clear_bits (io_set, + handle); + + return handle; + } + + return handle; +} diff --git a/TAO/tao_ace/Select_Fair_Perf_Strategy.h b/TAO/tao_ace/Select_Fair_Perf_Strategy.h new file mode 100644 index 00000000000..1d1600ad467 --- /dev/null +++ b/TAO/tao_ace/Select_Fair_Perf_Strategy.h @@ -0,0 +1,60 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Select_Fair_Perf_Strategy.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_SELECT_FAIR_PERF_STRATEGY_H +#define TAO_ACE_SELECT_FAIR_PERF_STRATEGY_H +#include "ace/pre.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class TAO_ACE_Select_Fair_Perf_Strategy + * + * @brief Provides an abstract interface for + * + * @todo: If the footprint blows up it could be because of this class + * where we inherit from Service_Object + * @@ todo<Bala>: Write comments. + */ + +class TAO_ACE_Export TAO_ACE_Select_Fair_Perf_Strategy : public TAO_ACE_Event_Selection_Strategy +{ +public: + + virtual ACE_HANDLE dispatchable_io_event ( + TAO_ACE_Event_Masks::Event_Masks &t); + +private: + + void clear_handle (ACE_HANDLE handle); + + ACE_HANDLE iterate (ACE_Handle_Set_Iterator &handle_iter); + +private: + + ACE_Handle_Set_Iterator rd_mask_iter_; + ACE_Handle_Set_Iterator wr_mask_iter_; + ACE_Handle_Set_Iterator ex_mask_iter_; + + TAO_ACE_Select_Strategy_Handle_Set &read_handle_set_; +}; + + +#if defined (__ACE_INLINE__) +#include "Select_Fair_Perf_Strategy.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" +#endif /*TAO_ACE_SELECT_FAIR_PERF_STRATEGY_H*/ diff --git a/TAO/tao_ace/Select_Fair_Perf_Strategy.inl b/TAO/tao_ace/Select_Fair_Perf_Strategy.inl new file mode 100644 index 00000000000..34b6d78d06d --- /dev/null +++ b/TAO/tao_ace/Select_Fair_Perf_Strategy.inl @@ -0,0 +1,2 @@ +/* -*- C++ -*- */ +//$Id$ 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)); + ***/ +} diff --git a/TAO/tao_ace/Select_IO_Handler_Repository.h b/TAO/tao_ace/Select_IO_Handler_Repository.h new file mode 100644 index 00000000000..d3ba93e9167 --- /dev/null +++ b/TAO/tao_ace/Select_IO_Handler_Repository.h @@ -0,0 +1,213 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Select_IO_Handler_Repository.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_SELECT_IO_HANDLER_REPOSITORY_H +#define TAO_ACE_SELECT_IO_HANDLER_REPOSITORY_H +#include "ace/pre.h" +#include "IO_Handler_Repository.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// @@todo: This pulls OS.h. Need to figure out a way to decouple this +// from OS.h +#include "ace/Handle_Set.h" + + +class TAO_ACE_Select_IO_Handler_Repository_Iterator; + +/** + * @class TAO_ACE_Select_Reactor_Handle_Set + * + * @brief Track handles we are interested for various events. + * + * @todo: This class is the *same* as the + * ACE_Select_Reactor_Handle_Set. As the ACE_Select_Yada is defined + * within some class which would set up a dependency to classes that + * we dont want, I am redefining this class here. + */ + +class TAO_ACE_Export TAO_ACE_Select_Strategy_Handle_Set +{ +public: + /// Read events (e.g., input pending, accept pending). + ACE_Handle_Set rd_mask_; + + /// Write events (e.g., flow control abated, non-blocking connection + /// complete). + ACE_Handle_Set wr_mask_; + + /// Exception events (e.g., SIG_URG). + ACE_Handle_Set ex_mask_; +}; + + +/** + * @class TAO_ACE_Select_IO_Handler_Repository + * + * @brief Provides an abstract interface for handling socket events. + * + * @@ todo<Bala>: Write comments + */ +class TAO_ACE_Export TAO_ACE_Select_IO_Handler_Repository : public TAO_ACE_IO_Handler_Repository +{ +public: + friend class TAO_ACE_Select_IO_Handler_Repository_Iterator; + + /// Ctor + TAO_ACE_Select_IO_Handler_Repository (void); + + /* Initialize the repository on construction. The constructor calls + * the underlying open () method to initialize the repository. This + * cannot be of much use for error checking. + */ + TAO_ACE_Select_IO_Handler_Repository (size_t s = ACE_FD_SETSIZE); + + ~TAO_ACE_Select_IO_Handler_Repository (void); + + /* Initialize the <TAO_ACE_IO_Event_Handler_Repository> for + * use. The <s> denotes the number of <IO_Event_Handlers> that + * can be stored in it + */ + int open (size_t s = ACE_FD_SETSIZE); + + /// Close down the repository and release the resources that we + /// held. + int close (void); + + virtual int bind (TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask); + + + virtual int unbind (TAO_ACE_IO_Event_Handler *eh, + TAO_ACE_IO_Event_Masks::Event_Masks mask); + + + virtual int add_masks (ACE_HANDLE h, + TAO_ACE_IO_Event_Masks::Event_Masks mask); + + + virtual int clr_masks (ACE_HANDLE h, + TAO_ACE_IO_Event_Masks::Event_Masks mask); + + virtual int find_state (ACE_HANDLE h, + TAO_ACE_IO_Handler_Repository::IO_Handler_State &st); + + virtual int rebind_state ( + TAO_ACE_IO_Handler_Repository::IO_Handler_State &st); + + /// Local methods .. + int max_handlep1 (void) const; + + TAO_ACE_Select_Strategy_Handle_Set &wait_set (void); + +private: + + int is_handle_valid (ACE_HANDLE handle); + + int is_event_mask_available (ACE_HANDLE handle); + +private: + + ssize_t max_size_; + + /// The highest currently active handle, plus 1 (ranges between 0 and + /// <max_size_>. + int max_handlep1_; + + + TAO_ACE_Select_Strategy_Handle_Set wait_set_; + + +#if defined (ACE_WIN32) + + /// Useful typedef to the place where we store the data. + typedef ACE_Hash_Map_Manager <ACE_SOCKET, + TAO_ACE_IO_Handler_Repository::IO_Handler_State, + ACE_Null_Mutex> Handler_Map; + + typedef ACE_Hash_Map_Iterator <ACE_SOCKET, + TAO_ACE_IO_Handler_Repository::IO_Handler_State, + ACE_Null_Mutex> Handler_Map_Iter; + + /// Map where the sockets and the respective handler states are + /// housed for easy access and something better than O(n) most of + /// the time. + Handler_Map handler_states_; + +#else + + /// On Unix based platforms we can maintain an array of handler + /// states and directly index into this for easy access. + TAO_ACE_IO_Handler_Repository::IO_Handler_State *handler_states_; +#endif /*ACE_WIN32*/ + + + ///@ + + +}; + + +/** + * @class TAO_ACE_Select_IO_Handler_Repository + * + * @brief Provides an abstract interface for handling socket events. + * + * @@ todo<Bala>: Write comments + */ + +class TAO_ACE_Export TAO_ACE_Select_IO_Handler_Repository_Iterator +{ +public: + + TAO_ACE_Select_IO_Handler_Repository_Iterator ( + const TAO_ACE_Select_IO_Handler_Repository &repo); + + // = Iteration methods. + + /// Pass back the <next_item> that hasn't been seen in the Set. + /// Returns 0 when all items have been seen, else 1. + int next ( + TAO_ACE_IO_Handler_Repository::IO_Handler_State *&next_item); + + /// Returns 1 when all items have been seen, else 0. + int done (void) const; + + /// Move forward by one element in the set. Returns 0 when all the + /// items in the set have been seen, else 1. + int advance (void); + + /// Dump the state of an object. + void dump (void) const; + +private: + + const TAO_ACE_Select_IO_Handler_Repository &repo_; + +#if defined (ACE_WIN32) + TAO_ACE_Select_IO_Handler_Repository::Handler_Map_Iter iter_; +#else /* !ACE_WIN32*/ + ssize_t index_; +#endif /*ACE_WIN32*/ + +}; + +#if defined (__ACE_INLINE__) +#include "Select_IO_Handler_Repository.inl" +#endif /* __ACE_INLINE__ */ + + +#include "ace/post.h" +#endif /*TAO_ACE_SELECT_IO_HANDLER_REPOSITORY_H*/ diff --git a/TAO/tao_ace/Select_IO_Handler_Repository.inl b/TAO/tao_ace/Select_IO_Handler_Repository.inl new file mode 100644 index 00000000000..a8ab7d5badc --- /dev/null +++ b/TAO/tao_ace/Select_IO_Handler_Repository.inl @@ -0,0 +1,48 @@ +/* -*- C++ -*- */ +//$Id$ +ACE_INLINE int +TAO_ACE_Select_IO_Handler_Repository::max_handlep1 (void) const +{ + return this->max_handlep1_; +} + +ACE_INLINE TAO_ACE_Select_Strategy_Handle_Set & +TAO_ACE_Select_IO_Handler_Repository:: wait_set (void) +{ + return this->wait_set_; +} + + +ACE_INLINE int +TAO_ACE_Select_IO_Handler_Repository::is_handle_valid (ACE_HANDLE h) +{ + ACE_TRACE ("TAO_ACE_Select_IO_Handler_Repository::is_handle_valid"); + +#if defined (ACE_WIN32) + // Not exactly sure how to get the validity of Win32 handles that + // are passed. + if (h == ACE_INVALID_HANDLE) +#else /* !ACE_WIN32 */ + + if (h < 0 || h >= this->max_size_) +#endif /* ACE_WIN32 */ + { + errno = EINVAL; + return -1; + } + + return 0; +} + +ACE_INLINE int +TAO_ACE_Select_IO_Handler_Repository::is_event_mask_available (ACE_HANDLE h) +{ + ACE_TRACE ("TAO_ACE_Select_IO_Handler_Repository::is_event_mask_available"); + + if (this->wait_set_.rd_mask_.is_set (h) == 0 + && this->wait_set_.wr_mask_.is_set (h) == 0 + && this->wait_set_.ex_mask_.is_set (h) == 0) + return 0; + + return 1; +} diff --git a/TAO/tao_ace/Select_Wait_Strategy.cpp b/TAO/tao_ace/Select_Wait_Strategy.cpp new file mode 100644 index 00000000000..2f5fe2f206a --- /dev/null +++ b/TAO/tao_ace/Select_Wait_Strategy.cpp @@ -0,0 +1,185 @@ +#include "Select_Wait_Strategy.h" +#include "Event_Selection_Strategy.h" +#include "IO_Event_Handler.h" + + +ACE_RCSID(tao_ace, Select_Wait_Strategy, "$Id$") + +TAO_ACE_IO_Handler_Repository * +TAO_ACE_Select_Wait_Strategy::handler_repository (void) +{ + ACE_TRACE ("TAO_ACE_Select_Wait_Strategy::handle_repository"); + + return &this->io_handler_repo_; +} + +ACE_HANDLE +TAO_ACE_Select_Wait_Strategy::dispatchable_io_event ( + TAO_ACE_IO_Event_Masks::Event_Masks &t) +{ + ACE_TRACE ("TAO_ACE_Select_Wait_Strategy::dispatchable_io_event"); + + return this->event_selection_strategy_->dispatchable_io_event (t); +} + +int +TAO_ACE_Select_Wait_Strategy::wait_for_multiple_events ( + ACE_Time_Value *max_wait_time) +{ + ACE_TRACE ("TAO_ACE_Select_Wait_Strategy::wait_for_multiple_events"); + + int no_active_handles = 0; + + // Check the strategy + if (!this->event_selection_strategy_->event_reselect () && + ((no_active_handles = this->active_handles ()) > 0)) + { + return no_active_handles; + } + + // We need to handle events that have not been handled before... + do + { + // @@<todo>: Do timeouts calculations here + ACE_Time_Value *timeout = max_wait_time; + + // Get the wait set from the repo + TAO_ACE_Select_Strategy_Handle_Set &wait_set = + this->io_handler_repo_.wait_set (); + + // Make a copy of the latest set bits.. + this->ready_set_.rd_mask_ = wait_set.rd_mask_; + this->ready_set_.wr_mask_ = wait_set.wr_mask_; + this->ready_set_.ex_mask_ = wait_set.ex_mask_; + + // Do the select now + no_active_handles = ACE_OS::select (this->io_handler_repo_.max_handlep1 (), + this->ready_set_.rd_mask_, + this->ready_set_.wr_mask_, + this->ready_set_.ex_mask_, + timeout); + } + while (no_active_handles == -1 && this->handle_error () > 0); + + if (no_active_handles > 0) + { +#if !defined (ACE_WIN32) + + // Resynchronize the fd_sets so their "max" is set properly. + this->ready_set_.rd_mask_.sync (this->io_handler_repo_.max_handlep1 ()); + this->ready_set_.wr_mask_.sync (this->io_handler_repo_.max_handlep1 ()); + this->ready_set_.ex_mask_.sync (this->io_handler_repo_.max_handlep1 ()); +#endif /* ACE_WIN32 */ + } + + // Return the number of events to dispatch. + return no_active_handles; +} + + +int +TAO_ACE_Select_Wait_Strategy::active_handles (void) +{ + ACE_TRACE ("TAO_ACE_Select_Wait_Strategy::active_handles"); + +# if 0 + if (this->mask_signals_) + { +#if !defined (ACE_WIN32)*/ + // Make this call signal safe. + ACE_Sig_Guard sb; +#endif /* ACE_WIN32 */ + } +#endif /*if 0*/ + + return this->ready_set_.rd_mask_.num_set () + + this->ready_set_.wr_mask_.num_set () + + this->ready_set_.ex_mask_.num_set (); +} + +int +TAO_ACE_Select_Wait_Strategy::handle_error (void) +{ + ACE_TRACE ("TAO_ACE_Select_Wait_Strategy::handle_error"); + + if (errno == EINTR) + return 1; +#if defined (__MVS__) || defined (ACE_WIN32) || defined (VXWORKS) + // On MVS Open Edition and Win32, there can be a number of failure + // codes on a bad socket, so check_handles on anything other than + // EINTR. VxWorks doesn't even bother to always set errno on error + // in select (specifically, it doesn't return EBADF for bad FDs). + else + return this->check_handles (); +#else +# if defined (ACE_PSOS) + else if (errno == EBADS) + return this->check_handles (); +# else + else if (errno == EBADF) + return this->check_handles (); +# endif /* ACE_PSOS */ + else + return -1; +#endif /* __MVS__ || ACE_WIN32 */ + +} + +int +TAO_ACE_Select_Wait_Strategy::check_handles (void) +{ + ACE_TRACE ("TAO_ACE_Select_Wait_Strategy::check_handles"); + +#if defined (ACE_WIN32) || defined (__MVS__) || defined (ACE_PSOS) || defined (VXWORKS) + ACE_Time_Value time_poll = ACE_Time_Value::zero; + ACE_Handle_Set rd_mask; +#endif /* ACE_WIN32 || MVS || ACE_PSOS || VXWORKS */ + + TAO_ACE_IO_Handler_Repository::IO_Handler_State *state = 0; + int result = 0; + + for (TAO_ACE_Select_IO_Handler_Repository_Iterator iter (this->io_handler_repo_); + iter.next (state) != 0; + iter.advance ()) + { + ACE_HANDLE handle = + state->event_handler_->get_handle (); + + // Skip back to the beginning of the loop if the HANDLE is + // invalid. + if (handle == ACE_INVALID_HANDLE) + continue; + +#if defined (ACE_WIN32) || defined (__MVS__) || defined (ACE_PSOS) || defined (VXWORKS) + // Win32 needs to do the check this way because fstat won't work on + // a socket handle. MVS Open Edition needs to do it this way because, + // even though the docs say to check a handle with either select or + // fstat, the fstat method always says the handle is ok. + // pSOS needs to do it this way because file handles and socket handles + // are maintained by separate pieces of the system. VxWorks needs the select + // variant since fstat always returns an error on socket FDs. + rd_mask.set_bit (handle); + + if (ACE_OS::select (int (handle) + 1, + rd_mask, 0, 0, + &time_poll) < 0) + { + result = 1; + this->io_handler_repo_.unbind (state->evenet_handler_, + TAO_ACE_Event_Masks::ALL_EVENTS_MASK); + } + rd_mask.clr_bit (handle); +#else /* !ACE_WIN32 && !MVS && !ACE_PSOS */ + struct stat temp; + + if (ACE_OS::fstat (handle, &temp) == -1) + { + result = 1; + this->io_handler_repo_.unbind (state->event_handler_, + TAO_ACE_IO_Event_Masks::ALL_EVENTS_MASK); + } +#endif /* ACE_WIN32 || MVS || ACE_PSOS */ + } + + return result; +} diff --git a/TAO/tao_ace/Select_Wait_Strategy.h b/TAO/tao_ace/Select_Wait_Strategy.h new file mode 100644 index 00000000000..90fd84fde7c --- /dev/null +++ b/TAO/tao_ace/Select_Wait_Strategy.h @@ -0,0 +1,68 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Select_Wait_Strategy.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + +#ifndef TAO_ACE_SELECT_WAIT_STRATEGY_H +#define TAO_ACE_SELECT_WAIT_STRATEGY_H +#include "ace/pre.h" +#include "Event_Wait_Strategy.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "Select_IO_Handler_Repository.h" + + +/** + * @class TAO_ACE_Select_Wait_Strategy + * + * @brief Provides an abstract interface for + * + * @@ todo<Bala>: Write comments + */ + +class TAO_ACE_Export TAO_ACE_Select_Wait_Strategy : public TAO_ACE_Event_Wait_Strategy +{ +public: + + virtual TAO_ACE_IO_Handler_Repository* handler_repository (void); + + virtual int wait_for_multiple_events ( + ACE_Time_Value *max_wait_time = 0); + + virtual ACE_HANDLE dispatchable_io_event ( + TAO_ACE_IO_Event_Masks::Event_Masks &t); + +protected: + + int active_handles (void); + + int handle_error (void); + + int check_handles (void); + +protected: + + TAO_ACE_Select_Strategy_Handle_Set ready_set_; + +private: + + TAO_ACE_Select_IO_Handler_Repository io_handler_repo_; + + TAO_ACE_Event_Selection_Strategy *event_selection_strategy_; + +}; + + +#include "ace/post.h" +#endif /*TAO_ACE_SELECT_WAIT_STRATEGY_H*/ diff --git a/TAO/tao_ace/TAO_ACE_export.h b/TAO/tao_ace/TAO_ACE_export.h new file mode 100644 index 00000000000..1024cb52895 --- /dev/null +++ b/TAO/tao_ace/TAO_ACE_export.h @@ -0,0 +1,46 @@ +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by +// generate_export_file.pl +// ------------------------------ +#ifndef TAO_ACE_EXPORT_H +#define TAO_ACE_EXPORT_H + +#include "ace/config-all.h" + +#if defined (ACE_AS_STATIC_LIBS) +# if !defined (ACE_HAS_DLL) +# define ACE_HAS_DLL 0 +# endif /* ! ACE_HAS_DLL */ +#else +# if !defined (ACE_HAS_DLL) +# define ACE_HAS_DLL 1 +# endif /* ! ACE_HAS_DLL */ +#endif /* ACE_AS_STATIC_LIB */ + +#if defined (ACE_HAS_DLL) +# if (ACE_HAS_DLL == 1) +# if defined (ACE_BUILD_DLL) +# define TAO_ACE_Export ACE_Proper_Export_Flag +# define ACE_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define ACE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else +# define TAO_ACE_Export ACE_Proper_Import_Flag +# define ACE_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define ACE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* ACE_BUILD_DLL */ +# else +# define TAO_ACE_Export +# define ACE_SINGLETON_DECLARATION(T) +# define ACE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* ! ACE_HAS_DLL == 1 */ +#else +# define TAO_ACE_Export +# define ACE_SINGLETON_DECLARATION(T) +# define ACE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* ACE_HAS_DLL */ + +#endif /* TAO_ACE_EXPORT_H */ + +// End of auto generated file. |