diff options
Diffstat (limited to 'TAO/orbsvcs/orbsvcs')
63 files changed, 20508 insertions, 5 deletions
diff --git a/TAO/orbsvcs/orbsvcs/AVStreams_i.cpp b/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.cpp index 260cb5f455e..db4f65f84a3 100644 --- a/TAO/orbsvcs/orbsvcs/AVStreams_i.cpp +++ b/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.cpp @@ -14,7 +14,7 @@ // // ============================================================================ -#include "AVStreams_i.h" +#include "orbsvcs/AV/AVStreams_i.h" // ---------------------------------------------------------------------- // TAO_Basic_StreamCtrl diff --git a/TAO/orbsvcs/orbsvcs/AVStreams_i.h b/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.h index 6fb54485268..6fb54485268 100644 --- a/TAO/orbsvcs/orbsvcs/AVStreams_i.h +++ b/TAO/orbsvcs/orbsvcs/AV/AVStreams_i.h diff --git a/TAO/orbsvcs/orbsvcs/Event/BCU.cpp b/TAO/orbsvcs/orbsvcs/Event/BCU.cpp new file mode 100644 index 00000000000..374fe783ef9 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/BCU.cpp @@ -0,0 +1,31 @@ +// $Id$ + +#include "ace/ACE.h" +#include "BCU.h" + + +u_long +ACE_BCU (u_long n) +{ + const u_long ACE_BCU_PRIME_NUMBER = 9619; + + u_long retval = 0; + + while (n-- > 0) + retval = ACE::is_prime (ACE_BCU_PRIME_NUMBER, 2, ACE_BCU_PRIME_NUMBER / 2); + + return retval; +} + + +u_long +ACE_BCU (u_long number, + u_long n) +{ + u_long retval = 0; + + while (n-- > 0) + retval = ACE::is_prime (number, 2, number); + + return retval; +} diff --git a/TAO/orbsvcs/orbsvcs/Event/BCU.h b/TAO/orbsvcs/orbsvcs/Event/BCU.h new file mode 100644 index 00000000000..9eaf5fdf96b --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/BCU.h @@ -0,0 +1,35 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ace ORB +// +// = FILENAME +// Benchmark Computation Units +// +// = AUTHOR +// David Levine and Tim Harrison (harrison@cs.wustl.edu) +// +// = DESCRIPTION +// +// Times how long it takes to generate each of the first N prime +// numbers. +// ============================================================================ + +#if !defined (ACE_BCU_H) +#define ACE_BCU_H + +#include "ace/OS.h" + + +u_long ACE_BCU (u_long n); +// Check if a specific, hardcoded number is prime (via ACE::is_prime) <n> +// times. + + +u_long ACE_BCU (u_long number, u_long n); +// Check if <number> is prime (via ACE::is_prime ()) <n> times. + +#endif /* ACE_BCU_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/CORBA_Utils_T.cpp b/TAO/orbsvcs/orbsvcs/Event/CORBA_Utils_T.cpp new file mode 100644 index 00000000000..cdffb8aa443 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/CORBA_Utils_T.cpp @@ -0,0 +1,349 @@ +// $Id$ + +#if !defined (ACE_CORBA_UTILS_C) +#define ACE_CORBA_UTILS_C + +#include "ace/Log_Msg.h" +#include "CORBA_Utils_T.h" + +#if !defined (__ACE_INLINE__) +#include "CORBA_Utils_T.i" +#endif /* __ACE_INLINE__ */ + +template <class TYPE> +ACE_CORBA_Sequence<TYPE>::ACE_CORBA_Sequence (const ACE_CORBA_Sequence<TYPE> &source) + : maximum_ (0), + length_ (0), + buffer_ (0), + release_ (0) +{ + (*this) = source; +} + +template <class TYPE> +ACE_CORBA_Sequence<TYPE>::ACE_CORBA_Sequence (void) + : maximum_ (0), + length_ (0), + buffer_ (0), + release_ (0) +{ +} + +template <class TYPE> +ACE_CORBA_Sequence<TYPE>::~ACE_CORBA_Sequence (void) +{ + if (release_) + { + this->delete_array (buffer_, maximum_); + } +} + +template <class TYPE> +ACE_CORBA_Sequence<TYPE>::ACE_CORBA_Sequence (CORBA::ULong max) + : maximum_ (max), + length_ (0), + buffer_ (0), + + release_ (0) +{ + if (maximum_ > 0) + { + buffer_ = this->new_array (maximum_); + release_ = 1; + } +} + +template <class TYPE> TYPE * +ACE_CORBA_Sequence<TYPE>::new_array (size_t len) +{ + return new TYPE[len]; +} + +template <class TYPE> void +ACE_CORBA_Sequence<TYPE>::delete_array (TYPE *buf, size_t) +{ + delete [] buf; +} + +template <class TYPE> +ACE_CORBA_Sequence<TYPE>::ACE_CORBA_Sequence (CORBA::ULong max, + CORBA::ULong length, + TYPE* data, + CORBA::Boolean release) + : maximum_ (max), + length_ (length), + buffer_ (data), + release_ (release) +{ + if ((buffer_ == 0) && (max > 0)) + { + // @@ What should we do here? + errno = ENOMEM; + ACE_ERROR ((LM_ERROR, "No memory.\n")); + } +} + +// @@ This makes a deep copy, dig? +template <class TYPE> ACE_CORBA_Sequence<TYPE> & +ACE_CORBA_Sequence<TYPE>::operator= (const ACE_CORBA_Sequence<TYPE> &source) +{ + if (source.length () > 0) + { + // If our buffer is too small, release it and allocate one just big + // enough. If buffer_ == 0, this works fine. + if (this->maximum () < source.length ()) + { + if (release_) + { + this->delete_array (buffer_, maximum_); + } + maximum_ = source.length (); + buffer_ = this->new_array (maximum_); + release_ = 1; + } + + // Copy each of the items from the source. + for (CORBA::ULong index=0; index < source.length (); index++) + (*this)[index] = source[index]; + + this->length (source.length ()); + } + + return *this; +} + +template <class TYPE> void +ACE_CORBA_Sequence<TYPE>::length (CORBA::ULong len) +{ + if (len > maximum_) + { + // Allocate the space that we need. + TYPE* tmp = this->new_array (len); + // Copy over the old sequence. + for (CORBA::ULong i = 0; i < maximum_; ++i) + { + tmp[i] = buffer_[i]; + } + if (release_) + { + this->delete_array (buffer_, maximum_); + } + buffer_ = tmp; + release_ = 1; + maximum_ = len; + // The destructor of -old- will release the old buffer_ if + // necessary. + } + + length_ = len; +} + + +// g++ can't handle these operator [] functions if they're inline +template <class TYPE> TYPE& +ACE_CORBA_Sequence<TYPE>::operator [] (CORBA::ULong i) +{ + // @@ Should we do bounds checking? + if (i >= maximum_) + { + ACE_ERROR ((LM_ERROR, "Trying to write past maximum.\n")); + return buffer_[maximum_ - 1]; + } + else + return buffer_[i]; +} + +template <class TYPE> const TYPE& +ACE_CORBA_Sequence<TYPE>::operator [] (CORBA::ULong i) const +{ + if (i >= length_) + { + ACE_ERROR ((LM_ERROR, "Trying to read past length.\n")); + return buffer_[length_ - 1]; + } + + return buffer_[i]; +} + +// ******************** + +/* +template <class TYPE> void +dump (const ACE_CORBA_Sequence<TYPE> &seq) +{ + for (CORBA::ULong index=0; index < seq.length (); index++) + dump (seq[index]); +} +*/ + +/* +template <class TYPE> ACE_INLINE void +operator += (ACE_CORBA_Sequence<TYPE> &seq, + const TYPE &item) +{ + CORBA::ULong length = seq.length (); + seq.length (length + 1); + seq[length] = item; +} +*/ + +template <class TYPE> ACE_INLINE void +operator += (ACE_CORBA_Sequence<TYPE> &dest, + const ACE_CORBA_Sequence<TYPE> &source) +{ + int old_length = dest.length (); + int new_length = old_length + source.length (); + dest.length (new_length); + + int difference = new_length - old_length; + + for (int x=0; x < difference; x++) + dest[old_length + x] = source[x]; +} + +/* +template <class TYPE> ACE_INLINE void +remove_item (TYPE &seq, CORBA::ULong index) +{ + int new_length = seq.length () - 1; + + // Shift the set back one, starting at <index>. + for (int x = index; x < new_length; x++) + seq[x] = seq[x+1]; + + // Set the new length. + seq.length (new_length); +} +*/ + +// ************************************************************ +// ************************************************************ +// ************************************************************ + +template<class TYPE> +ACE_CORBA_var<TYPE>::ACE_CORBA_var (const ACE_CORBA_var<TYPE> &source) +{ + if (source.me_ != 0) + me_ = (TYPE *) source.me_->_duplicate (); + // CORBA::duplicate (source.me_); +} + +template<class TYPE> +ACE_CORBA_var<TYPE>::ACE_CORBA_var (void) + : me_ (0) +{ +} + +template<class TYPE> +ACE_CORBA_var<TYPE>::ACE_CORBA_var (TYPE *source) +{ + me_ = (TYPE *) source->_duplicate (); + // CORBA::duplicate (source); +} + +template<class TYPE> +ACE_CORBA_var<TYPE>::~ACE_CORBA_var (void) +{ + if (me_ != 0) + me_->_release (); + //CORBA::release (me_); +} + +template<class TYPE> ACE_CORBA_var<TYPE> & +ACE_CORBA_var<TYPE>::operator= (TYPE *source) +{ + if (me_ != source && + me_ != 0) + me_->_release (); + //CORBA::release (me_); + + me_ = (TYPE *) source->_duplicate (); + // CORBA::duplicate (source); + return *this; +} + +template<class TYPE> ACE_CORBA_var<TYPE> & +ACE_CORBA_var<TYPE>::operator= (const ACE_CORBA_var<TYPE> &source) +{ + if (me_ != source.me_ && + me_ != 0) + me_->_release (); + // CORBA::release (me_); + + me_ = (TYPE *) source.me_->_duplicate (); + // CORBA::duplicate (source.me_); + return *this; +} + +template<class TYPE> TYPE * +ACE_CORBA_var<TYPE>::operator->(void) +{ + return me_; +} + +template<class TYPE> +ACE_CORBA_var<TYPE>::operator TYPE *(void) const +{ + return me_; +} + +/* +template<class TYPE> +ACE_CORBA_var<TYPE>::operator TYPE *&(void) +{ + return me_; +} +*/ + +template<class TYPE> +ACE_CORBA_var<TYPE>::operator TYPE &(void) const +{ + return *me_; +} + +// ************************************************************ +// ************************************************************ + +/* +ACE_CORBA_Object_Ref<IMPL>::ACE_CORBA_Object_Ref (void) + : impl_ (0) +{ +} + +ACE_CORBA_Object_Ref<IMPL>::ACE_CORBA_Object_Ref (IMPL *impl) + : impl_ (impl) +{ +} + +ACE_CORBA_Object_Ref<IMPL>::~ACE_CORBA_Object_Ref (void) + : impl_ (0) +{ +} + +ACE_CORBA_Object_Ref<IMPL> & +ACE_CORBA_Object_Ref<IMPL>::operator= (const ACE_CORBA_Object_Ref<IMPL> &source) +{ + return *this; +} + +IMPL * +ACE_CORBA_Object_Ref<IMPL>::operator->(void) +{ + return impl_; +} + +IMPL * +ACE_CORBA_Object_Ref<IMPL>::operator IMPL *(void) +{ + return impl_; +} + +ACE_CORBA_Object_Ref<IMPL> * +ACE_CORBA_Object_Ref<IMPL>::_duplicate (ACE_CORBA_Object_Ref<IMPL> *source) +{ + source->ref_count_++; + return source; +} + +*/ +#endif /* ACE_CORBA_UTILS_C */ diff --git a/TAO/orbsvcs/orbsvcs/Event/CORBA_Utils_T.h b/TAO/orbsvcs/orbsvcs/Event/CORBA_Utils_T.h new file mode 100644 index 00000000000..8abf180d9e1 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/CORBA_Utils_T.h @@ -0,0 +1,236 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ace_orb +// +// = FILENAME +// CORBA_Utilities.h +// +// = AUTHORS +// Tim Harrison. +// +// = NOTE +// This class is a bit ackward when using a real ORB, but we cannot +// easily remove it since some of the types are used in the +// implementation of the EC. TODO +// +// ============================================================================ + +#if !defined (ACE_CORBA_UTILS_H) +#define ACE_CORBA_UTILS_H + +#include "ace/Time_Value.h" +#include "tao/corba.h" + +template <class TYPE> +class ACE_CORBA_Sequence// : public CORBA::Object +// = TITLE +// +// = DESCRIPTION +{ +public: + + ACE_CORBA_Sequence (const ACE_CORBA_Sequence<TYPE> &source); + // Copy construction. + + ACE_CORBA_Sequence (CORBA::ULong max); + ACE_CORBA_Sequence (CORBA::ULong max, + CORBA::ULong length, + TYPE* data, + CORBA::Boolean release = 0); + ACE_CORBA_Sequence (void); + + virtual ~ACE_CORBA_Sequence (void); + + ACE_CORBA_Sequence<TYPE> &operator= (const ACE_CORBA_Sequence<TYPE> &); + + // static TYPE* allocbuf(CORBA::ULong nelems); + // static void freebuf(TYPE* data); + + CORBA::ULong maximum (void) const; + CORBA::ULong length (void) const; + void length (CORBA::ULong len); + + TYPE& operator [] (CORBA::ULong IT_i); + + const TYPE& operator [] (CORBA::ULong IT_i) const; + + virtual TYPE *new_array (size_t len); + // Allocates TYPE[len]. This facilitates template methods through + // template specialization to allow the use of different memory + // pools. + + virtual void delete_array (TYPE *buf, size_t len); + // delete [] <buf>. + +protected: + CORBA::ULong maximum_; + CORBA::ULong length_; + TYPE* buffer_; + unsigned char release_; +}; + +// Utility for debugging sequences. +//template <class TYPE> +//void dump (const ACE_CORBA_Sequence<TYPE> &seq); + +// Utility for appending single items. Increases the length of <set> +// and adds <event> to the end of <set>. +template <class TYPE> void +operator += (ACE_CORBA_Sequence<TYPE> &seq, + const TYPE &item) +{ + CORBA::ULong length = seq.length (); + seq.length (length + 1); + seq[length] = item; +} + +// Utility for appending sequences. +template <class TYPE> void +operator += (ACE_CORBA_Sequence<TYPE> &dest, + const ACE_CORBA_Sequence<TYPE> &source); + +template <class TYPE> void +remove_item (TYPE &seq, CORBA::ULong index) +{ + int new_length = seq.length () - 1; + + // Shift the set back one, starting at <index>. + for (int x = index; x < new_length; x++) + seq[x] = seq[x+1]; + + // Set the new length. + seq.length (new_length); +} +// Removes seq[index] by moving everything after <index> back and +// decrementing the length. + +// ************************************************************ + +template <class TYPE> +class ACE_CORBA_var +// = TITLE +// +// = DESCRIPTION +{ +public: + ACE_CORBA_var (const ACE_CORBA_var<TYPE> &source); + ACE_CORBA_var (void); + ACE_CORBA_var (TYPE *source); + ~ACE_CORBA_var (void); + ACE_CORBA_var<TYPE> &operator= (TYPE *source); + ACE_CORBA_var<TYPE> &operator= (const ACE_CORBA_var<TYPE> &source); + TYPE *operator->(void); + operator TYPE *(void) const; + // operator TYPE *&(void); + operator TYPE &(void) const; +private: + TYPE *me_; +}; + +// ************************************************************ + +/* +template <class IMPL> +class ACE_CORBA_Object_Ref : public CORBA::Object +// = TITLE +// ACE CORBA Object Reference +// +// = DESCRIPTION +// A wrapper for making CORBA Object References. For a single +// address space ORB, this points directly to the IMPL +// class. This is supposed to look like a pointer to +// IMPL with an additional static _duplicate method. +{ +public: + // ACE_CORBA_Object_Ref (ACE_CORBA_Object_Ref<IMPL> &obj); + ACE_CORBA_Object_Ref (void); + ACE_CORBA_Object_Ref (IMPL *impl); + ~ACE_CORBA_Object_Ref (void); + // ACE_CORBA_Object_Ref<IMPL> &operator= (IMPL *source); + ACE_CORBA_Object_Ref<IMPL> &operator= + (const ACE_CORBA_Object_Ref<IMPL> &source); + + IMPL *operator->(void); + // A distributed ORB would require that the CORBA Object Reference + // implement all IMPL interfaces, marshall the parameters, + // and transmit over IIOP. For this single address space ORB, we'll + // just delegate method calls to the IMPL directly. + + operator IMPL *(void) const; + // operator IMPL *&(void); + // operator IMPL &(void) const; + + static ACE_CORBA_Object_Ref<IMPL> *_duplicate + (ACE_CORBA_Object_Ref<IMPL> *source); + +private: + IMPL *impl_; +}; +*/ + +// ************************************************************ + +template <class ITEM, size_t SIZE> +class ACE_ES_Simple_Array +// = TITLE +// Simple Array +// +// = DESCRIPTION +// Wraps ITEM[SIZE] with insert and an iterator. There is no +// remove. It allows duplicates. It is truly very simple. +{ + public: + ACE_ES_Simple_Array (void); + int insert (const ITEM ©_me); + size_t size (void); + ITEM *data (void); + protected: + ITEM data_[SIZE]; + size_t size_; +}; + +template <class ITEM> +class ACE_ES_Array_Iterator +// = TITLE +// Simple Iterator +// +// = DESCRIPTION +// Iterates through an array of ITEMs. +{ +public: + ACE_ES_Array_Iterator (ITEM *data, size_t size); + + int next (ITEM *&next_item); + // Returns 0 when all items have been seen, else 1. Sets + // <next_item> to point at the next ITEM. + + int advance (void); + // Move forward by one element in the Stack. Returns 0 when all the + // items in the Stack have been seen, else 1. + + int done (void) const; + // Returns 1 when all items have been seen, else 0. + +private: + ITEM *data_; + size_t size_; + size_t index_; +}; + +#if defined (__ACE_INLINE__) +#include "CORBA_Utils_T.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "CORBA_Utils_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("CORBA_Utils_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_CORBA_UTILS_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/CORBA_Utils_T.i b/TAO/orbsvcs/orbsvcs/Event/CORBA_Utils_T.i new file mode 100644 index 00000000000..d9ebb9247ad --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/CORBA_Utils_T.i @@ -0,0 +1,75 @@ +/* -*- C++ -*- */ +// $Id$ + +template <class TYPE> ACE_INLINE CORBA::ULong +ACE_CORBA_Sequence<TYPE>::maximum (void) const +{ + return maximum_; +} + +template <class TYPE> ACE_INLINE CORBA::ULong +ACE_CORBA_Sequence<TYPE>::length() const +{ + return length_; +} + + +// ************************************************************ + +template <class ITEM, size_t SIZE> ACE_INLINE +ACE_ES_Simple_Array<ITEM, SIZE>::ACE_ES_Simple_Array (void) : + size_ (0) +{ +} + +template <class ITEM, size_t SIZE> ACE_INLINE int +ACE_ES_Simple_Array<ITEM, SIZE>::insert (const ITEM ©_me) +{ + if (size_ >= SIZE) + return -1; + + data_[size_++] = copy_me; + return 0; +} + +template <class ITEM, size_t SIZE> ACE_INLINE size_t +ACE_ES_Simple_Array<ITEM, SIZE>::size (void) +{ + return size_; +} + +template <class ITEM, size_t SIZE> ACE_INLINE ITEM * +ACE_ES_Simple_Array<ITEM, SIZE>::data (void) +{ + return data_; +} + +// ************************************************************ + +template <class ITEM> ACE_INLINE +ACE_ES_Array_Iterator<ITEM>::ACE_ES_Array_Iterator (ITEM *data, size_t size) : + data_ (data), + size_ (size), + index_ (0) +{ +} + +template <class ITEM> ACE_INLINE int +ACE_ES_Array_Iterator<ITEM>::next (ITEM *&next_item) +{ + next_item = &data_[index_]; + return index_ < (size_ - 1); +} + +template <class ITEM> ACE_INLINE int +ACE_ES_Array_Iterator<ITEM>::advance (void) +{ + index_++; + return index_ < size_; +} + +template<class ITEM> ACE_INLINE int +ACE_ES_Array_Iterator<ITEM>::done (void) const +{ + return index_ < size_; +} diff --git a/TAO/orbsvcs/orbsvcs/Event/Channel_Clients.i b/TAO/orbsvcs/orbsvcs/Event/Channel_Clients.i new file mode 100644 index 00000000000..6318deb79a0 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Channel_Clients.i @@ -0,0 +1,2 @@ +/* -*- C++ -*- */ +// $Id$ diff --git a/TAO/orbsvcs/orbsvcs/Event/Channel_Clients_T.i b/TAO/orbsvcs/orbsvcs/Event/Channel_Clients_T.i new file mode 100644 index 00000000000..f7c0760fd86 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Channel_Clients_T.i @@ -0,0 +1,35 @@ +/* -*- C++ -*- */ +// $Id$ + +template <class TARGET> ACE_INLINE +ACE_PushConsumer_Adapter<TARGET>::ACE_PushConsumer_Adapter (TARGET *target) + : target_ (target) +{ +} + +template <class TARGET> ACE_INLINE void +ACE_PushConsumer_Adapter<TARGET>::push (const RtecEventComm::EventSet& events, + CORBA::Environment &_env) +{ + target_->_push (events, _env); +} + +template <class TARGET> ACE_INLINE void +ACE_PushConsumer_Adapter<TARGET>::disconnect_push_consumer (CORBA::Environment &_env) +{ + target_->_disconnect_push_consumer (_env); +} + +// ************************************************************ + +template <class TARGET> ACE_INLINE +ACE_PushSupplier_Adapter<TARGET>::ACE_PushSupplier_Adapter (TARGET *target) + : target_ (target) +{ +} + +template <class TARGET> ACE_INLINE void +ACE_PushSupplier_Adapter<TARGET>::disconnect_push_supplier (CORBA::Environment &_env) +{ + target_->_disconnect_push_supplier (_env); +} diff --git a/TAO/orbsvcs/orbsvcs/Event/Debug_Macros.h b/TAO/orbsvcs/orbsvcs/Event/Debug_Macros.h new file mode 100644 index 00000000000..8db3d169082 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Debug_Macros.h @@ -0,0 +1,11 @@ + +#if defined (ACE_ES_NOLOGGING) +#define ACE_ES_DEBUG(X) +#define ACE_ES_DEBUG_ST(X) +#else +#define ACE_ES_DEBUG(X) \ + do { \ + ACE_Log_Msg::instance ()->log X; \ + } while (0) +#define ACE_ES_DEBUG_ST(X) X +#endif /* ACE_ES_NOLOGGING */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.cpp b/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.cpp new file mode 100644 index 00000000000..521905e3423 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.cpp @@ -0,0 +1,613 @@ +// $Id$ + +#include "ace/Sched_Params.h" +#include "orbsvcs/Scheduler_Factory.h" +#include "orbsvcs/Time_Utilities.h" +#include "Memory_Pools.h" + +#include "Dispatching_Modules.h" + +#if !defined (__ACE_INLINE__) +#include "Dispatching_Modules.i" +#endif /* __ACE_INLINE__ */ + +// ************************************************************ + +void +ACE_ES_Dispatch_Request::make_copy (RtecEventComm::EventSet &dest) const +{ + if (use_single_event_) + { + dest.length (1); + dest[0] = single_event_; + } + else + { + dest.length (event_set_.length ()); + + for (CORBA::ULong index=0; index < event_set_.length (); index++) + { + RtecEventComm::Event &dest_event = dest[index]; + ACE_ES_Event_Container_var &source_event_var = ((ACE_ES_Event_Container_var &) event_set_[index]); + dest_event = *(source_event_var.operator->()); + } + } +} + +int +ACE_ES_Dispatch_Request::execute (u_long &command_action) +{ + ACE_TIMEPROBE (" dispatch (dequeue) the event"); + + return dispatching_module_->dispatch_event (this, command_action); +} + +#if 0 +void * +ACE_ES_Dispatch_Request::operator new (size_t nbytes) +{ + if (nbytes > sizeof (ACE_ES_Dispatch_Request)) + { + ACE_ERROR ((LM_ERROR, "nbytes = %d, sizeof (ACE_ES_Dispatch_Request_Chunk) = %d.\n", + sizeof (ACE_ES_Dispatch_Request))); + ACE_ASSERT (nbytes <= sizeof (ACE_ES_Dispatch_Request)); + } + + return ACE_ES_Memory_Pools::new_Dispatch_Request (); +} + +void +ACE_ES_Dispatch_Request::operator delete (void *mem) +{ + ACE_ES_Memory_Pools::delete_Dispatch_Request (mem); +} +#endif /* 0 */ + +// ************************************************************ + +ACE_ES_Priority_Dispatching::ACE_ES_Priority_Dispatching (ACE_EventChannel *channel, + int threads_per_queue) + : ACE_ES_Dispatching_Base (channel), + notification_strategy_ (this), + highest_priority_ (0), + shutdown_ (0), + threads_per_queue_ (threads_per_queue) +{ + // If we're single threaded, then we need to use the notification strategy. + if ((threads_per_queue_ == 0) && + (notification_strategy_.open () == -1)) + ACE_ERROR ((LM_ERROR, "%p.\n", "ACE_ES_Priority_Dispatching")); + + // Initialize the queues. + for (int x=0; x < ACE_Scheduler_MAX_PRIORITIES; x++) + { + queues_[x] = 0; + delete_me_queues_[x] = 0; + } + + this->initialize_queues (); +} + +ACE_ES_Priority_Dispatching::~ACE_ES_Priority_Dispatching (void) +{ + // Delete the queues. + for (int x=0; x < ACE_Scheduler_MAX_PRIORITIES; x++) + delete delete_me_queues_[x]; +} + + +void +ACE_ES_Priority_Dispatching::initialize_queues (void) +{ + for (int x=0; x < ACE_Scheduler_MAX_PRIORITIES; x++) + { + // @@ Apparently Period is measured in a different unit that the + // time, beats me. + ACE_hrtime_t nanosecs; + ORBSVCS_Time::TimeT_to_hrtime (nanosecs, ACE_Scheduler_Rates[x]); + + RtecScheduler::Period period = nanosecs; + + queues_[x] = new ACE_ES_Dispatch_Queue (this, ¬ification_strategy_); + if (queues_[x] == 0 || + queues_[x]->open_queue (period, threads_per_queue_) == -1) + { + ACE_ERROR ((LM_ERROR, "%p.\n", "ACE_ES_Priority_Dispatching::initialize_queues")); + return; + } + + queue_count_[x] = 1; + } + + highest_priority_ = ACE_Scheduler_MAX_PRIORITIES - 1; +} + +void +ACE_ES_Priority_Dispatching::connected (ACE_Push_Consumer_Proxy *consumer, + CORBA::Environment &_env) +{ + down_->connected (consumer, _env); + + // This code does dynamic allocation of channel dispatch threads. + // It requires that consumer's priorities are known at connection + // time and that threads can request priorities from the scheduler + // at run-time. These are both antithetical to static scheduling. + // The constructor now allocates a thread per rate group. +#if 0 + // We have to tell the lower portions of the channel about the + // consumer first. This is so that any changes to the consumer's + // qos will take effect when we get the dispatch priority. + down_->connected (consumer, _env); + + RtecScheduler::OS_Priority priority = + ACE_Scheduler::instance ().preemption_priority (consumer->qos ().rt_info_); + + { + ACE_ES_GUARD ace_mon (lock_); + + // If a queue has not been created for the consumer's priority, + // create one. + if (queues_[priority] == 0) + { + // Allocate a new dispatch queue. + queues_[priority] = new ACE_ES_Dispatch_Queue (this, ¬ification_strategy_); + if (queues_[priority] == 0) + TAO_THROW (CORBA::NO_MEMORY (0, CORBA::COMPLETED_NO, + "ACE_ES_Priority_Dispatching::connected")); + + // Initialize the dispatch queue corresponding to the + // consumer's priority. With a full implementation of the + // run-time scheduler, the dispatch queue can find it's + // scheduling qos online. However, we pass the rate in case + // one is not found. The rate can be used to obtain the + // proper priority. If threads_per_queue_ == 0, then these + // queues will be passive. Otherwise, they will be active. + // This switches us between MT_ORB and ST_ORB. If we're + // single-threaded, this registers us with the ReactorEx using + // our notification_strategy_. If we're multi-threaded, this + // spawns the threads. + if (queues_[priority]->open_queue (priority, + threads_per_queue_) == -1) + TAO_THROW (DISPATCH_ERROR (0, CORBA::COMPLETED_NO, + "ACE_ES_Priority_Dispatching::connected:" + "queue open failed.\n")); + + // When this goes down to 0, we will shutdown the queue. + queue_count_[priority] = 1; + + // Keep track of this to optimize handle_signal. + if (priority > highest_priority_) + highest_priority_ = priority; + + ACE_DEBUG ((LM_DEBUG, "Created queue priority = %d.\n", priority)); + } + else + queue_count_[priority]++; + } +#endif +} + +void +ACE_ES_Priority_Dispatching::disconnected (ACE_Push_Consumer_Proxy *consumer) +{ + // We'll not dynamically close down queues. + ACE_UNUSED_ARG (consumer); + +#if 0 + RtecScheduler::OS_Priority priority = + ACE_Scheduler::instance ().preemption_priority (consumer->qos ().rt_info_); + + { + ACE_ES_GUARD ace_mon (lock_); + + // If there are no more users of this queue, then we *could* shut + // it down. However, we will not. + if (--queue_count_[priority] <= 0) + { + ACE_DEBUG ((LM_DEBUG, "(%t) unused dispatch queue priority = %d, " + "is_empty = %d.\n", + priority, queues_[priority]->msg_queue ()->is_empty ())); + + queues_[priority]->shutdown_task (); + } + } +#endif +} + +// @@ This method could have a bypass optimization. +// <request> has been dynamically allocated by the filtering module. +void +ACE_ES_Priority_Dispatching::push (ACE_ES_Dispatch_Request *request, + CORBA::Environment &_env) +{ + ACE_TIMEPROBE (" push_source_type: Correlation Module"); + + RtecScheduler::OS_Priority thread_priority; + RtecScheduler::Sub_Priority subpriority; + RtecScheduler::Preemption_Priority preemption_priority; + + if (request->rt_info () != 0) + { + // @@ TODO use TAO_TRY&friends + ACE_TIMEPROBE (" Priority_Dispatching::push - priority requested"); + ACE_Scheduler_Factory::server ()->priority + (request->rt_info (), + thread_priority, + subpriority, + preemption_priority, + _env); + ACE_TIMEPROBE (" Priority_Dispatching::push - priority obtained"); + if (_env.exception ()) + { + return; + } + } + else + { + thread_priority = + ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, + ACE_SCOPE_PROCESS); + subpriority = ACE_Scheduler_MIN_SUB_PRIORITY; + preemption_priority = ACE_Scheduler_MIN_PREEMPTION_PRIORITY; + } + + // If it's a request to forward an event, it needs a reference to us + // to call dispatch_event. + request->set (this, preemption_priority, subpriority); + + // Make sure that a queue exists for this priority. + if (queues_[preemption_priority] == 0) + { + ACE_ERROR ((LM_ERROR, "Push to closed queue %d, dropping event.\n", preemption_priority)); + return; +#if 0 + TAO_THROW (SYNC_ERROR (0, CORBA::COMPLETED_NO, "ACE_ES_Priority_Dispatching::push")); +#endif /* 0 */ + } + + // Enqueue the request. If we're multi-threaded, this request is a + // command object that will be called by the threads in the queue, + // or will be dequeued by this->handle_signal if we're + // single-threaded. + if (queues_[preemption_priority]->try_put (request) == -1) + { + if (ACE_ES_Dispatch_Request::release (request) != 0) + ACE_ERROR ((LM_ERROR, "ACE_ES_Priority_Dispatching::push" + " release failed.\n")); + if (errno != EPIPE) + { + TAO_THROW (CORBA::NO_MEMORY (CORBA::COMPLETED_NO)); + // @@ Orbix parameters + // 0, CORBA::COMPLETED_NO, + // "ACE_ES_Priority_Dispatching::push enqueue failed")); + } + else + { + ACE_DEBUG ((LM_DEBUG, + "Request rejected from closed queue %d.\n", + preemption_priority)); + } + } +} + +// Start at highest priority queue checking for queued events +// continuing to lowest priority queue. If an event is ever found, +// dispatch it and then start back at the highest priority queue +// again. +int +ACE_ES_Priority_Dispatching::handle_signal (int, siginfo_t *, ucontext_t *) +{ + int done; + + do + { + done = 1; + for (int x = 0; x <= highest_priority_; x++) + { + // If the queue is not empty, dispatch the request and then + // start the for loop from the beginning. + if ((queues_[x] != 0) && (!queues_[x]->msg_queue ()->is_empty ())) + { + // Dequeue and service the request. + queues_[x]->svc_one (); + + // Exit the for loop and start over. + done = 0; + break; + } + + // If we get through the whole for loop without dispatching + // anything, then we're done. + } + } + while (!done); + + + return 0; +} + +// This is only for the non-win32 single-threaded implementation. +int +ACE_ES_Priority_Dispatching::handle_input (ACE_HANDLE) +{ + return this->handle_signal (0, 0, 0); +} + +// Shutdown each queue. When each queue exits, they will call back +// this->dispatch_queue_closed which allows us to free up resources. +// When the last queue has closed, we'll delete ourselves. +void +ACE_ES_Priority_Dispatching::shutdown (void) +{ + if (shutdown_) + return; + + ACE_DEBUG ((LM_DEBUG, "(%t) ACE_ES_Priority_Dispatching " + "module shutting down.\n")); + + shutdown_ = 1; + + // If we're single threaded, then we need to shut down the + // notification strategy so it can remove itself from the reactor. + if (threads_per_queue_ == 0) + notification_strategy_.shutdown (); + + // Whether these are active or not, they must be shut down. + for (int x = 0; x <= highest_priority_; x++) + if (queues_[x] != 0) + { + ACE_DEBUG ((LM_DEBUG, "shutting down dispatch queue %d.\n", x)); + queues_[x]->shutdown_task (); + } +} + +// This gets called every time a Dispatch Queue closes down. We +// search for <queue> and delete it. If we have been told to delete +// ourself, after the last queue has been deleted, we delete +// ourselves. +void +ACE_ES_Priority_Dispatching::dispatch_queue_closed (ACE_ES_Dispatch_Queue *queue) +{ + ACE_ES_GUARD ace_mon (lock_); + + // Find the queue. + for (int x = 0; x <= highest_priority_; x++) + { + if (queues_[x] == queue) + { + ACE_DEBUG ((LM_DEBUG, "(%t) Dispatch queue %d is closed.\n", x)); + + // Store the queue for deleting in this object's destructor. + delete_me_queues_[x] = queues_[x]; + queues_[x] = 0; + + // Reset highest_priority_. + if (x == highest_priority_) + { + while ((--highest_priority_ >= 0) && + (queues_[highest_priority_] == 0)); + + if (highest_priority_ < 0) + { + ACE_DEBUG ((LM_DEBUG, "Dispatching module shut down.\n")); + up_->shutdown (); + return; + } + } + + // If we found the queue, we can exit the for loop. + break; + } + } +} + +/* +ACE_HANDLE +ACE_ES_Priority_Dispatching::get_handle (void) const +{ + ACE_ES_Priority_Dispatching *fake_this = (ACE_ES_Priority_Dispatching *) this; + return fake_this->notification_strategy_.get_handle (); +} +*/ + +// ************************************************************ + +ACE_ES_Dispatch_Queue::ACE_ES_Dispatch_Queue (ACE_ES_Dispatching_Base *dispatching_module, + ACE_ES_Notification_Strategy *notification_strategy) + : dispatching_module_ (dispatching_module), + notification_strategy_ (notification_strategy) +{ +} + +int +ACE_ES_Dispatch_Queue::open_queue (RtecScheduler::Period &period, + int threads) +{ + // First set up the correct message queue according to whether the + // dispatch queue will be active or not. + + // If there are no threads specified, we'll register with the + // reactor to be called back when someone queues a message. + if (threads == 0) + { + // Allocate a message queue that notifies a reactor when events + // arrive via the msg_queue call. If that succeeds, set the + // notification strategy in our message queue via the open call. + if (this->msg_queue () == 0 || + this->msg_queue ()->open (ACE_ES_QUEUE::DEFAULT_HWM, + ACE_ES_QUEUE::DEFAULT_LWM, + notification_strategy_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p msg_queue.open failed.\n", + "ACE_ES_Dispatch_Queue::open_queue"), -1); + } + else + { + // Allocate a message queue that does not notify. + ACE_ES_MQ *mq = new ACE_ES_MQ; + if (mq == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", + "ACE_ES_Dispatch_Queue::open_queue"), -1); + else + { + // This deletes previous message queue. + this->msg_queue (mq); + // Set this so that the destructor of ACE_Task deletes our + // message queue. Note, this must be after the call to + // msg_queue. + delete_msg_queue_ = 1; + } + } + + // Create a name for ourselves using the priority. + char temp[64]; + ACE_OS::sprintf (temp, "ACE_ES_Dispatch_Queue-%u", period); + + // Open the task. This will query the scheduler for our qos + // structure. It will also synch_threads if it succeeds. + int result = this->open_task (temp); + + switch (result) + { + case -1: + // Error. + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", + "ACE_ES_Dispatch_Queue::open_queue"), -1); + case 0: + TAO_TRY + {// @@ TODO: Handle exceptions... + ACE_Scheduler_Factory::server()->set (rt_info_, + ORBSVCS_Time::zero, + ORBSVCS_Time::zero, + ORBSVCS_Time::zero, + 0, + RtecScheduler::VERY_LOW, + ORBSVCS_Time::zero, + 1, TAO_TRY_ENV); + TAO_CHECK_ENV; + } + TAO_CATCHANY + { + ACE_ERROR_RETURN ((LM_ERROR, + "ACE_ES_Display_Queue::exception"), -1); + } + TAO_ENDTRY; + case 1: + // Found. + break; + } + + // Spawn threads. + return this->synch_threads (threads); +} + +// This is called back by ACE_RT_Task when all the threads have +// exited. We're going to forward this event to the dispatching +// module so it can clean up any resources. +void +ACE_ES_Dispatch_Queue::threads_closed (void) +{ + dispatching_module_->dispatch_queue_closed (this); +} + +// ************************************************************ + +ACE_ES_EFD_Dispatching::ACE_ES_EFD_Dispatching (ACE_EventChannel *channel) + : ACE_ES_Dispatching_Base (channel) +{ +} + +void +ACE_ES_EFD_Dispatching::push (ACE_ES_Dispatch_Request *request, + CORBA::Environment &) +{ + // If it's a request to forward an event, it needs a reference to us + // to call dispatch_event. + request->set (this, 0, ACE_Scheduler_MIN_SUB_PRIORITY); + + u_long command_action = ACE_RT_Task_Command::RELEASE; + + // This may be a request to delete a push consumer proxy, so we + // should execute it instead of just forwarding it. + request->execute (command_action); + + switch (command_action) + { + case ACE_RT_Task_Command::RELEASE: + // Free the request. + if (ACE_ES_Dispatch_Request::release (request) != 0) + ACE_ERROR ((LM_ERROR, "ACE_ES_EFD_Dispatching::push" + " release failed.\n")); + break; + + default: + ACE_ERROR ((LM_ERROR, "ACE_ES_EFD_Dispatching::push: unknown command action.\n")); + } +} + +// ************************************************************ + +ACE_ES_RTU_Dispatching::ACE_ES_RTU_Dispatching (ACE_EventChannel *channel) + : ACE_ES_Priority_Dispatching (channel, 0) +{ +} + +// We're called from a dispatch queue, so we can not release the request. +int +ACE_ES_RTU_Dispatching::dispatch_event (ACE_ES_Dispatch_Request *request, + u_long &command_action) +{ + // Store the priority of the task currently running. + channel_->rtu_manager ()->priority (request->priority ()); + + TAO_TRY + { + // Forward the request. + up_->push (request, TAO_TRY_ENV); + TAO_CHECK_ENV; + } + TAO_CATCHANY + { + ACE_ERROR ((LM_ERROR, "ACE_ES_RTU_Dispatching::dispatch_event unknown exception.\n")); + } + TAO_ENDTRY; + + // Reset the priority. + channel_->rtu_manager ()->priority (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, ACE_SCOPE_PROCESS)); + + // If the task was preempted, enqueue the request on the head of the + // dispatch queue. + if (channel_->rtu_manager ()->not_done ()) + command_action = ACE_RT_Task_Command::UNGETQ; + else + // We're done with it. + command_action = ACE_RT_Task_Command::RELEASE; + + return 0; +} + +void +ACE_ES_RTU_Dispatching::push (ACE_ES_Dispatch_Request *request, + CORBA::Environment &_env) +{ + // First enqueue the message in the proper queue. + ACE_ES_Priority_Dispatching::push (request, _env); + + // If the current event is higher priority (lower value) than the + // current running task, then tell the task to preempt itself. + int request_priority = request->priority (); + int running_priority = channel_->rtu_manager ()->priority (); + if (request_priority < running_priority) + channel_->rtu_manager ()->should_preempt (1); + return; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_CORBA_Sequence<ACE_CORBA_var<ACE_ES_Event_Container> >; +template void operator+=(ACE_CORBA_Sequence<ACE_CORBA_var<ACE_ES_Event_Container> > &, ACE_CORBA_var<ACE_ES_Event_Container> const &); + +#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate ACE_CORBA_Sequence<ACE_CORBA_var<ACE_ES_Event_Container> > +#pragma instantiate void operator+=(ACE_CORBA_Sequence<ACE_CORBA_var<ACE_ES_Event_Container> > &, ACE_CORBA_var<ACE_ES_Event_Container> const &) + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.h b/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.h new file mode 100644 index 00000000000..bf872280346 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.h @@ -0,0 +1,486 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// orbsvcs +// +// = FILENAME +// Dispatching_Module +// +// = AUTHOR +// Tim Harrison (harrison@cs.wustl.edu) +// +// = DESCRIPTION +// This file holds the different Event Service dispatching +// mechanisms. These include null-dispatching (EFD), +// single-threaded with (RTU) and without preemption (LAME), and a +// multithreaded implementation. +// +// ============================================================================ + +#ifndef ACE_DISPATCHING_MODULES_H +#define ACE_DISPATCHING_MODULES_H + +#include "tao/Timeprobe.h" +#include "ReactorTask.h" +#include "Event_Channel.h" + +// ************************************************************ + +// Forward declarations. +class ACE_ES_Dispatch_Queue; +class ACE_ES_Dispatch_Request; + +// ************************************************************ + +// Forward declarations. +class ACE_ES_Consumer_Module; + +class ACE_ES_Dispatching_Base : public ACE_Event_Handler +// = TITLE +// Event Service Dispatch Module base class +// +// = DESCRIPTION +// We inherit from ACE_Event_Handler so that we can be called back +// by the ReactorEx when requests are queued. The virtual +// dispatch_event method allows ACE_ES_Dispatch_Requests to call +// back the dispatching module when acting as command objects. When +// this implementation is used by the Event Channel it forwards all +// dispatch calls without any queuing. Therefore, it can be +// used to build an EFD. It is also inherited by the Priority +// Dispatching module. +{ +public: + ACE_ES_Dispatching_Base (ACE_EventChannel *channel); + // Default construction. + + virtual void open (ACE_ES_Consumer_Module *up, + ACE_ES_Correlation_Module *down); + // Link to adjacent modules. + + virtual void connected (ACE_Push_Consumer_Proxy *consumer, + CORBA::Environment &); + // Forward down_. + + virtual void disconnecting (ACE_Push_Consumer_Proxy *consumer, + CORBA::Environment &); + // Forward down_. + + virtual void disconnected (ACE_Push_Consumer_Proxy *consumer); + // Release any unneeded dispatching resources. + + // = Not needed. + // void connected (ACE_Push_Supplier_Proxy *supplier); + // void disconnecting (ACE_Push_Supplier_Proxy *supplier); + + virtual void push (ACE_ES_Dispatch_Request *request, + CORBA::Environment &) = 0; + // Forward up_. + + virtual int dispatch_event (ACE_ES_Dispatch_Request *request, + u_long &command_action); + // Called by ACE_ES_Dispatch_Requests when dequeued by RT_Tasks. + + virtual void dispatch_queue_closed (ACE_ES_Dispatch_Queue *q); + // Called when all the threads of a <q> have exited. + + virtual void shutdown (void); + // This is called by the Event Channel. This will attempt to shut + // down all of its threads gracefully. Wish it luck. + +protected: + ACE_EventChannel *channel_; + // Dat der channel. + + ACE_ES_MUTEX lock_; + // To synchronize thr_count_. + + int thr_count_; + // The total number of threads in the Dispatching Module. This will + // be the sum of all the Dispatch Queue threads. + + ACE_ES_Consumer_Module *up_; + // Next module up. + + ACE_ES_Correlation_Module *down_; + // Next module down. +}; + +// ************************************************************ + +class ACE_ES_Dispatch_Request : public ACE_RT_Task_Command +// = TITLE +// ACE Event Service Dispatch Request +// +// = DESCRIPTION +// Encapsulates a consumer and the events that will be sent to the +// consumer. Right now, this class keeps a single_event_ that can +// be used when only one event is sent to the consumer. Since this +// is frequently the case (except for correlations), this +// optimization reduces the amount of dynamic memory allocation is +// necessary. This class is also a GOF Command object since it can +// be dequeued by an RT_Task to call back the dispatching module +// for request dispatching. +{ +public: + typedef ACE_CORBA_Sequence<ACE_ES_Event_Container_var> Event_Set; + + ACE_ES_Dispatch_Request (void); + // Default construction. + + virtual ~ACE_ES_Dispatch_Request (void); + // Default destruction. + + ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, + RtecScheduler::handle_t rt_info); + // All the events must be added after construction to the + // event_set. + + ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, + const Event_Set &event_set, + RtecScheduler::handle_t rt_info); + // Set consumer_ to <consumer> and copy <event_set> to event_set_. + // <rt_info> describes the method receiving this dispatch. + + ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, + const RtecEventComm::Time &time, + RtecScheduler::handle_t rt_info); + // Set consumer_ to <consumer> and sets single_event_.creation_time_ + // to <time>. Sets use_single_event_ to 1. <rt_info> describes the + // method receiving this dispatch. + + ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, + ACE_ES_Event_Container *event, + RtecScheduler::handle_t rt_info); + // Sets consumer_ and the first slot of event_set_. We use the + // event_set_ instead of the single_event_ so that we can just carry + // around the pointer to <event>. <rt_info> describes the method + // receiving this dispatch. + + RtecScheduler::handle_t rt_info (void); + // Description of the method receiving this request. + + void set (ACE_ES_Dispatching_Base *dispatching_module, + RtecScheduler::OS_Priority priority, + RtecScheduler::Sub_Priority sub_priority); + // For multi-threaded implementations, <dispatching_module> is + // called back when a request is dequeued. <priority> is the + // dispatch priority of the event. <sub_priority> is the enqueue + // priority of the event and will be forwarded to + // ACE_Message_Block. + + ACE_Push_Consumer_Proxy *consumer (void) const; + // Consumer accessor. + + const Event_Set &event_set (void) const; + // If accessed, make_copy will use event_set_. + + Event_Set &event_set (void); + // If accessed, make_copy will use event_set_. + + CORBA::ULong number_of_events (void) const; + // Returns 1 if we're using single_event, or event_set_.size (). + + void make_copy (RtecEventComm::EventSet &dest) const; + // Copy single_event or event_set into <dest>. + + virtual int execute (u_long &command_action); + // Calls dispatching_module_->dispatch_event. + + RtecScheduler::OS_Priority priority (void); + // Priority accessor. + +#if 0 + // @@ This cannot be done: the object would be allocated using this + // class operator new, but it will be removed using the + // ACE_Message_Block operator delete! + void *operator new (size_t nbytes); + // Allocates memory from a thread-specific memory pool. + + void operator delete (void *); + // Returns memory to a thread-specific memory pool. +#endif + +protected: + RtecScheduler::OS_Priority priority_; + + RtecScheduler::handle_t rt_info_; + // Describes the method receiving this dispatch. + + ACE_ES_Dispatching_Base *dispatching_module_; + // The dispatching module called back when we're dequeued by a + // thread. + + int use_single_event_; + // Is true if we're using a single event. Is 0 is we're using + // event_set_. + + ACE_Push_Consumer_Proxy *consumer_; + // The final destination for single_event_ or event_set_. + + ACE_ES_Event_Container single_event_; + // This is used for single event dispatches. + + Event_Set event_set_; + // This is used for event sets that need to be dispatched. +}; + +// ************************************************************ + +#if defined (ACE_WIN32) +class ACE_ES_ReactorEx_NS : public ACE_Notification_Strategy +// = TITLE +// Event Service ReactorEx Notification Strategy +// +// = DESCRIPTION +// Integrates the ACE_Message_Queue notification to signal a +// handle that will wake up the ACE_ES_Priority_Dispatching +// module. This is used in place of the +// ACE_ReactorEx_Notification_Strategy to avoid any queueing by +// the ReactorEx::notify mechanism. +{ +public: + ACE_ES_ReactorEx_NS (ACE_Event_Handler *eh); + // Stores away <eh> for when this->open is called. + + int open (void); + // Registers eh_ with the ReactorEx to be notified when this->notify + // is called. + + void shutdown (void); + // Removes self from the reactor. + + // = These result in eh_->handle_signal getting called. eh_ should + // point to a dispatching module. + virtual int notify (void); + virtual int notify (ACE_Event_Handler *, + ACE_Reactor_Mask mask); + + // ACE_HANDLE get_handle (void); + // Returns event_.handle (). + +private: + ACE_Auto_Event event_; + // Registered with the ReactorEx. +}; + +typedef ACE_ES_ReactorEx_NS ACE_ES_Notification_Strategy; + +#else // ******************************************************* + +class ACE_ES_Reactor_NS : public ACE_Reactor_Notification_Strategy +// = TITLE +// Event Service Reactor Notification Strategy +// +// = DESCRIPTION +// Maps to the ACE_Reactor_Notification_Strategy interface. This +// version is for non WIN32 platforms. +{ +public: + ACE_ES_Reactor_NS (ACE_Event_Handler *eh); + // Calls ACE_Reactor_Notification_Strategy with the ORB's reactor + // and signal mask. + + int open (void); + // Does nothing. + + void shutdown (void); + // Does nothing. +}; + +typedef ACE_ES_Reactor_NS ACE_ES_Notification_Strategy; + +#endif /* ACE_WIN32 */ + +// ************************************************************ + +class ACE_ES_MQ : public ACE_ES_QUEUE +// = TITLE +// Event Service Message Queue +{ + virtual int notify (void) { return 0;} + // Does nothing. +}; + +// ************************************************************ + +class ACE_ES_Dispatch_Queue : public ACE_RT_Task +// = TITLE +// Event Service Dispatch Queue +// +// = DESCRIPTION +// An encapsulation of a dispatch queue. By inheriting from +// ACE_RT_Task, we can make this zero-threaded or multi-threaded. +{ +public: + ACE_ES_Dispatch_Queue (ACE_ES_Dispatching_Base *dispatching_module, + ACE_ES_Notification_Strategy *notification_strategy); + // Stores <dispatching_module> for this->threads_closed. Stores + // away <notification_strategy> for this->synch_threads. + + int open_queue (RtecScheduler::Period &period, + int threads); + // This is a hack to get the channel to work with the new + // scheduler. + +#if 0 + int open_queue (RtecScheduler::OS_Priority priority, + int threads); + // Creates a name from the <priority> and tries to find a scheduling + // qos structure. If one is not found, but created, qos_ is set + // with default values. Either way, if qos_->thread_ > 0, it calls + // this->synch_threads. Otherwise, our message queue will use + // notification_strategy_. This will cause the ReactorEx to call + // back the dispatching_module_ when requests are queued on our + // message queue. Returns 0 on success, -1 on failure. +#endif + + virtual void threads_closed (void); + // Called when every thread has exited. This will call + // dispatching_module_->dispatch_queue_closed. + +private: + ACE_ES_Dispatching_Base *dispatching_module_; + // Used in threads_closed. + + ACE_ES_Notification_Strategy *notification_strategy_; + // Notifies the Dispatching Module when a request has been queued on + // our message queue. +}; + +// ************************************************************ + +class ACE_ES_Priority_Dispatching : public ACE_ES_Dispatching_Base +// = TITLE +// Event Service Priority Dispatching Module +// +// = DESCRIPTION +// Inherits from ACE_Event_Handler to utilitize the +// ACE_Message_Queue notification strategy. This implementation +// does priority dispatching without preemption. +{ +public: + ACE_ES_Priority_Dispatching (ACE_EventChannel *channel, + int threads_per_queue); + // Store <channel>. Spawns <threads_per_queue> thread for each + // dispatch queue. If != 0, then the channel is an MT_CHANNEL. If + // == 0, then the channel is an ST_CHANNEL. + + ~ACE_ES_Priority_Dispatching (void); + // Delete queues. + + void connected (ACE_Push_Consumer_Proxy *consumer, + CORBA::Environment &); + // Allocate any needed dispatching resources for this consumers + // priority. + + void disconnected (ACE_Push_Consumer_Proxy *consumer); + // Release unneeded dispatch queues. + + // = Not needed. + // void connected (ACE_Push_Supplier_Proxy *supplier); + // void disconnecting (ACE_Push_Supplier_Proxy *supplier); + + virtual void push (ACE_ES_Dispatch_Request *request, + CORBA::Environment &); + // Enqueues the request on the appropriate Dispatch Queue. + + virtual void shutdown (void); + // Closes all queues "asynchronously." When all queues are closed, + // deletes them all and then deletes itself. + + virtual void dispatch_queue_closed (ACE_ES_Dispatch_Queue *q); + // Called when all the threads of a <q> have exited. Deletes <q>. + + // virtual ACE_HANDLE get_handle (void) const; + // Get the I/O handle. + +protected: + virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); + // Called when input has arrived on a message queue. This is used + // for single-threaded implementations. + + virtual int handle_input (ACE_HANDLE); + // For single-threaded implementations on non-win32 platforms that + // use the ACE_Reactor_Notification_Strategy. This just forwards + // all calls to this->handle_signal (). + + ACE_ES_Notification_Strategy notification_strategy_; + // Shared between all dispatch queues. + + void initialize_queues (void); + // This is a hack to create a queue for each of the 4 rate groups. + + ACE_ES_Dispatch_Queue *queues_[ACE_Scheduler_MAX_PRIORITIES]; + // Pointers to dispatch queues. + + ACE_ES_Dispatch_Queue *delete_me_queues_[ACE_Scheduler_MAX_PRIORITIES]; + // Pointers to dispatch queues that want to die. + + int queue_count_[ACE_Scheduler_MAX_PRIORITIES]; + // The number of consumers using each queue. + + int highest_priority_; + // The highest priority queue in queues_. This allows us to + // optimize the handle_signal method. + + int shutdown_; + // Make sure to only shutdown the dispatching module once. + + int threads_per_queue_; + // The number of threads to spawn for each dispatch queue. +}; + +// ************************************************************ + +class ACE_ES_EFD_Dispatching : public ACE_ES_Dispatching_Base +// = TITLE +// Event Service EFD Dispatching Module +// +// = DESCRIPTION +// Implements a zero-threaded dispatcher with no preemption. +{ +public: + ACE_ES_EFD_Dispatching (ACE_EventChannel *channel); + // Acquires the proper qos structure and passes <channel> onto to + // the dispatching base constructor. + + virtual void push (ACE_ES_Dispatch_Request *request, + CORBA::Environment &); + // Forward up_. +}; + +// ************************************************************ + +class ACE_ES_RTU_Dispatching : public ACE_ES_Priority_Dispatching +// = TITLE +// Event Service RTU Dispatching Module +// +// = DESCRIPTION +// Implements a single-threaded dispatcher with delayed preemption. +{ +public: + ACE_ES_RTU_Dispatching (ACE_EventChannel *channel); + // Store <channel>. + + virtual int dispatch_event (ACE_ES_Dispatch_Request *request, + u_long &command_action); + // Called by ACE_Dispatch_Queues and handle_signal when an event + // needs to be dequeued. Implements an RTU-like delayed preemption + // policy. + + virtual void push (ACE_ES_Dispatch_Request *request, + CORBA::Environment &); + // Calls ACE_ES_Priority_Dispatching::push and then checks if + // preemption is necessary. +}; + +#if defined (__ACE_INLINE__) +#include "Dispatching_Modules.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_DISPATCHING_MODULES_H */ + + diff --git a/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.i b/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.i new file mode 100644 index 00000000000..7148766c9b7 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.i @@ -0,0 +1,267 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_ES_Dispatch_Request::ACE_ES_Dispatch_Request (void) : + priority_ (0), + rt_info_ (0), + dispatching_module_ (0), + use_single_event_ (0), + consumer_ (0), + single_event_ (), + event_set_ () +{ +} + +ACE_INLINE +ACE_ES_Dispatch_Request::~ACE_ES_Dispatch_Request (void) +{ +} + +ACE_INLINE +ACE_ES_Dispatch_Request::ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, + RtecScheduler::handle_t rt_info) : + priority_ (0), + rt_info_ (rt_info), + dispatching_module_ (0), + use_single_event_ (0), + consumer_ (consumer), + single_event_ (), + event_set_ () +{ +} + +ACE_INLINE +ACE_ES_Dispatch_Request::ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, + const Event_Set &event_set, + RtecScheduler::handle_t rt_info) : + priority_ (0), + rt_info_ (rt_info), + dispatching_module_ (0), + use_single_event_ (0), + consumer_ (consumer), + single_event_ (), + event_set_ (event_set) +{ +} + +ACE_INLINE +ACE_ES_Dispatch_Request::ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, + ACE_ES_Event_Container *event, + RtecScheduler::handle_t rt_info) : + priority_ (0), + rt_info_ (rt_info), + dispatching_module_ (0), + use_single_event_ (0), + consumer_ (consumer), + single_event_ (), + event_set_ () +{ + event_set_ += event; +} + +ACE_INLINE +ACE_ES_Dispatch_Request::ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, + const RtecEventComm::Time &time, + RtecScheduler::handle_t rt_info) : + priority_ (0), + rt_info_ (rt_info), + dispatching_module_ (0), + use_single_event_ (1), + consumer_ (consumer), + single_event_ (), + event_set_ () +{ + single_event_.creation_time_ = time; + single_event_.type_ = ACE_ES_EVENT_TIMEOUT; +} + +ACE_INLINE void +ACE_ES_Dispatch_Request::set (ACE_ES_Dispatching_Base *dispatching_module, + RtecScheduler::OS_Priority preemption_priority, + RtecScheduler::Sub_Priority sub_priority) +{ + dispatching_module_ = dispatching_module; + priority_ = preemption_priority; + ACE_Message_Block::msg_priority (sub_priority); +} + +ACE_INLINE ACE_Push_Consumer_Proxy * +ACE_ES_Dispatch_Request::consumer (void) const +{ + return consumer_; +} + +ACE_INLINE const ACE_ES_Dispatch_Request::Event_Set & +ACE_ES_Dispatch_Request::event_set (void) const +{ + return event_set_; +} + +ACE_INLINE ACE_ES_Dispatch_Request::Event_Set & +ACE_ES_Dispatch_Request::event_set (void) +{ + return event_set_; +} + +ACE_INLINE CORBA::ULong +ACE_ES_Dispatch_Request::number_of_events (void) const +{ + if (use_single_event_) + return 1; + else + return event_set_.length (); +} + +ACE_INLINE RtecScheduler::OS_Priority +ACE_ES_Dispatch_Request::priority (void) +{ + return priority_; +} + +ACE_INLINE RtecScheduler::handle_t +ACE_ES_Dispatch_Request::rt_info (void) +{ + return rt_info_; +} + +// ************************************************************ + +ACE_INLINE +ACE_ES_Dispatching_Base::ACE_ES_Dispatching_Base (ACE_EventChannel *channel) + : channel_ (channel), + thr_count_ (0), + up_ (0), + down_ (0) +{ +} + +ACE_INLINE void +ACE_ES_Dispatching_Base::open (ACE_ES_Consumer_Module *up, + ACE_ES_Correlation_Module *down) +{ + up_ = up; + down_ = down; + // 1 == 2. +} + +ACE_INLINE void +ACE_ES_Dispatching_Base::connected (ACE_Push_Consumer_Proxy *consumer, + CORBA::Environment &_env) +{ + down_->connected (consumer, _env); +} + +ACE_INLINE void +ACE_ES_Dispatching_Base::disconnected (ACE_Push_Consumer_Proxy *consumer) +{ + // Do nothing. + ACE_UNUSED_ARG (consumer); +} + +ACE_INLINE void +ACE_ES_Dispatching_Base::disconnecting (ACE_Push_Consumer_Proxy *consumer, + CORBA::Environment &_env) +{ + down_->disconnecting (consumer, _env); +} + +ACE_INLINE void +ACE_ES_Dispatching_Base::dispatch_queue_closed (ACE_ES_Dispatch_Queue *q) +{ + ACE_UNUSED_ARG (q); +} + +// Just forward the request. This is basically a hook for the RTU +// stuff. +ACE_INLINE int +ACE_ES_Dispatching_Base::dispatch_event (ACE_ES_Dispatch_Request *request, + u_long &command_action) +{ + ACE_TIMEPROBE (" decode the event"); + + TAO_TRY + { + // Forward the request. + up_->push (request, TAO_TRY_ENV); + TAO_CHECK_ENV; + } + TAO_CATCHANY + { + ACE_ERROR ((LM_ERROR, "ACE_ES_Dispatching_Base::dispatch_event unknown exception.\n")); + } + TAO_ENDTRY; + + // Tell our caller to release the request. + command_action = ACE_RT_Task_Command::RELEASE; + + // Return zero so our calling thread does not exit. + return 0; +} + +ACE_INLINE void +ACE_ES_Dispatching_Base::shutdown (void) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) ACE_ES_Dispatching_Base module shutting down.\n")); +} + +// ************************************************************ + +#if defined (ACE_WIN32) +ACE_INLINE +ACE_ES_ReactorEx_NS::ACE_ES_ReactorEx_NS (ACE_Event_Handler *eh) + : ACE_Notification_Strategy (eh, ACE_Event_Handler::NULL_MASK) +{ +} + +ACE_INLINE int +ACE_ES_ReactorEx_NS::open (void) +{ + return ACE_Task_Manager::instance ()-> + GetReactorTask (0)->get_reactor ().register_handler (eh_, event_.handle ()); +} + +ACE_INLINE void +ACE_ES_ReactorEx_NS::shutdown (void) +{ + ACE_Task_Manager::instance ()->GetReactorTask (0)-> + get_reactor ().remove_handler (eh_, ACE_Event_Handler::DONT_CALL); +} + +ACE_INLINE int +ACE_ES_ReactorEx_NS::notify (void) +{ + return event_.signal (); +} + +ACE_INLINE int +ACE_ES_ReactorEx_NS::notify (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) +{ + return event_.signal (); +} + +#else /* !defined (ACE_WIN32) */ +// This class is only necessary on non-win32 platforms. +ACE_INLINE +ACE_ES_Reactor_NS::ACE_ES_Reactor_NS (ACE_Event_Handler *eh) + : ACE_Reactor_Notification_Strategy (&(ACE_Task_Manager::instance ()-> + GetReactorTask (0)->get_reactor ()), + eh, ACE_Event_Handler::READ_MASK) +{ +} + +ACE_INLINE int +ACE_ES_Reactor_NS::open (void) +{ + return 0; +} + +ACE_INLINE void +ACE_ES_Reactor_NS::shutdown (void) +{ +} + +#endif /* ACE_WIN32 */ + +// ************************************************************ diff --git a/TAO/orbsvcs/orbsvcs/Event/Event_Channel.cpp b/TAO/orbsvcs/orbsvcs/Event/Event_Channel.cpp new file mode 100644 index 00000000000..e289cacbf33 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Event_Channel.cpp @@ -0,0 +1,2771 @@ +// $Id$ + + + +#include "ace/Service_Config.h" +#include "orbsvcs/Scheduler_Factory.h" + +#include "Dispatching_Modules.h" +#include "Memory_Pools.h" +#include "Event_Channel.h" + +// These are to save space. +#define WRITE_GUARD ACE_ES_WRITE_GUARD +#define READ_GUARD ACE_ES_READ_GUARD + +#if !defined (__ACE_INLINE__) +#include "Event_Channel.i" +#endif /* __ACE_INLINE__ */ + +// ************************************************************ + +static RtecScheduler::OS_Priority +Preemption_Priority (RtecScheduler::handle_t rtinfo) +{ + RtecScheduler::OS_Priority thread_priority; + RtecScheduler::Sub_Priority subpriority; + RtecScheduler::Preemption_Priority preemption_priority; + + TAO_TRY + { + ACE_TIMEPROBE (" Preemption_Priority - priority requested"); + ACE_Scheduler_Factory::server ()->priority + (rtinfo, + thread_priority, + subpriority, + preemption_priority, + TAO_TRY_ENV); + TAO_CHECK_ENV + ACE_TIMEPROBE (" connected - priority obtained"); + } + TAO_CATCH (RtecScheduler::UNKNOWN_TASK, ex_ut) + { + ACE_ERROR_RETURN ((LM_ERROR, "UNKNOWN_TASK %p.\n", + "Preemption_Priority"), 0); + } + TAO_CATCHANY + { + ACE_ERROR_RETURN ((LM_ERROR, "Unexpected exception %p.\n", + "Preemption_Priority"), 0); + + } + TAO_ENDTRY; + return preemption_priority; +} + +static RtecScheduler::OS_Priority +IntervalToPriority (RtecScheduler::Time interval) +{ + for (int x=0; x < ACE_Scheduler_MAX_PRIORITIES; x++) + if (interval <= ACE_Scheduler_Rates[x]) + return x; + + return ACE_Scheduler_MIN_PREEMPTION_PRIORITY; +} + +// ************************************************************ + +class Shutdown_Consumer : public ACE_ES_Dispatch_Request +// = TITLE +// Shutdown Consumer command +// +// = DESCRIPTION +// This command object is sent through the system when a consumer +// disconnects. When the Dispatching Module dequeues this request, +// it calls execute which execute calls back to the Consumer +// Module. At that point, the Consumer Module can tell the rest of +// the system that the consumer has disconnected and delete the +// consumer proxy. This allows all events queued for the consumer +// to be flushed to the consumer proxy (which will drop them). +// Events can be queued in the ReactorEx (in a dispatch set), or in +// the Dispatching Module. +{ +public: + // When executed, tells <consumer_module> that <consumer> has shut + // down. + Shutdown_Consumer (ACE_ES_Consumer_Module *consumer_module, + ACE_Push_Consumer_Proxy *consumer) + : consumer_module_ (consumer_module) + { + consumer_ = consumer; + + // Set rt_info_ to the lowest priority rt_info in consumer_. + // This is so the dispatching module can query us as a dispatch + // request to get the appropriate preemption priority. + ACE_ES_Dependency_Iterator iter (consumer->qos ().dependencies); + while (iter.advance_dependency () == 0) + { + RtecEventComm::EventType &type = (*iter).event_.type_; + if (type != ACE_ES_GLOBAL_DESIGNATOR && + type != ACE_ES_CONJUNCTION_DESIGNATOR && + type != ACE_ES_DISJUNCTION_DESIGNATOR) + { + if (rt_info_ == 0 || + ::Preemption_Priority ((*iter).rt_info) < + ::Preemption_Priority (rt_info_)) + rt_info_ = (*iter).rt_info; + } + } + } + + // Report to the consumer module that consumer_ has shutdown. + virtual int execute (u_long &command_action) + { + consumer_module_->shutdown_request (this); + command_action = ACE_RT_Task_Command::RELEASE; + return 0; + } + + void *operator new (size_t /* nbytes */) + { return ::new char[sizeof (Shutdown_Consumer)]; } + + void operator delete (void *buf) + { ::delete [] buf; } + + // The module that we report to. + ACE_ES_Consumer_Module *consumer_module_; +}; + +// ************************************************************ + +class Shutdown_Channel : public ACE_ES_Dispatch_Request +{ +public: + Shutdown_Channel (ACE_EventChannel *channel) : + channel_ (channel) {} + + // Report to the consumer module that consumer_ has shutdown. + virtual int execute (u_long &command_action) + { +#if 0 + channel_->destroy_i (); +#endif + command_action = ACE_RT_Task_Command::RELEASE; + return 0; + } + + void *operator new (size_t /* nbytes */) + { return ::new char[sizeof (Shutdown_Channel)]; } + + void operator delete (void *buf) + { ::delete [] buf; } + + ACE_EventChannel *channel_; +}; + +// ************************************************************ + +class ACE_ES_Priority_Timer : public ACE_Event_Handler +// = TITLE +// Event Service Timer +// +// = DESCRIPTION +// Manages a thread per priority, each of which sits on its own +// ReactorEx dispatching the timers for its given priority. +{ +public: + ACE_ES_Priority_Timer (void); + // Default construction. + + int connected (RtecScheduler::handle_t rt_info); + // This allows the Priority Timer to prespawn threads. Returns 0 on + // success, -1 on failure. + + int schedule_timer (RtecScheduler::handle_t rt_info, + const ACE_ES_Timer_ACT *act, + RtecScheduler::OS_Priority preemption_priority, + const RtecScheduler::Time& delta, + const RtecScheduler::Time& interval = ORBSVCS_Time::zero); + // Schedule a timer at the appropriate priority for <preemption_priority>. + // Returns the preemption priority used on success, -1 on failure. + + int cancel_timer (RtecScheduler::OS_Priority preemption_priority, + int id, ACE_ES_Timer_ACT *&act); + // Cancel the timer associated with the priority of + // <preemption_priority> and <id>. <act> is filled in with the + // Timer_ACT used when scheduling the timer. Returns 0 on success, + // -1 on failure. + +private: + virtual int handle_timeout (const ACE_Time_Value &tv, + const void *act); + // Casts <act> to ACE_ES_Timer_ACT and calls execute. +}; + +// ************************************************************ + +class Flush_Queue_ACT : public ACE_ES_Timer_ACT +// = TITLE +// Flush Queue Asynchronous Completion Token +// +// = DESCRIPTION +// Carries a single dispatch request through the ReactorEx. +// Deletes itself when execute is called. +{ +public: + Flush_Queue_ACT (ACE_ES_Dispatch_Request *request, + ACE_ES_Dispatching_Module *dispatching_module) : + request_ (request), + dispatching_module_ (dispatching_module) { } + + virtual void execute (void) + { + TAO_TRY + { + ACE_ES_Dispatch_Request *request = request_; + dispatching_module_->push (request, TAO_TRY_ENV); + TAO_CHECK_ENV; + delete this; + } + TAO_CATCHANY + { + ACE_ERROR ((LM_ERROR, "(%t) Flush_Queue_ACT::execute: " + "Unknown exception..\n")); + } + TAO_ENDTRY; + } + + ACE_ES_Dispatch_Request *request_; + ACE_ES_Dispatching_Module *dispatching_module_; +}; + +// ************************************************************ + +// Since this class is *defined* in the cpp file, the INLINE +// definitions must also be in the cpp file. The should go here +// before any use of these methods. + +ACE_INLINE int +ACE_ES_Priority_Timer::schedule_timer (RtecScheduler::handle_t rt_info, + const ACE_ES_Timer_ACT *act, + RtecScheduler::OS_Priority preemption_priority, + const RtecScheduler::Time &delta, + const RtecScheduler::Time &interval) +{ + if (rt_info != 0) + { + // Add the timer to the task's dependency list. + RtecScheduler::handle_t timer_rtinfo = + ACE_Task_Manager::instance()->GetReactorTask (preemption_priority)->rt_info (); + + TAO_TRY + { + ACE_Scheduler_Factory::server()->add_dependency + (rt_info, timer_rtinfo, 1, TAO_TRY_ENV); + TAO_CHECK_ENV; + } + TAO_CATCHANY + { + ACE_ERROR ((LM_ERROR, "add dependency failed")); + } + TAO_ENDTRY; + } + + // @@ We're losing resolution here. + ACE_Time_Value tv_delta; + ORBSVCS_Time::TimeT_to_Time_Value (tv_delta, delta); + + ACE_Time_Value tv_interval; + ORBSVCS_Time::TimeT_to_Time_Value (tv_interval, interval); + + return ACE_Task_Manager::instance()-> + GetReactorTask (preemption_priority)-> + get_reactor ().schedule_timer (this, + (void *) act, + tv_delta, tv_interval); +} + +ACE_INLINE int +ACE_ES_Priority_Timer::cancel_timer (RtecScheduler::OS_Priority preemption_priority, + int id, ACE_ES_Timer_ACT *&act) +{ + const void *vp; + + int result = ACE_Task_Manager::instance()-> + GetReactorTask (preemption_priority)-> + get_reactor ().cancel_timer (id, &vp); + + if (result == 0) + { + ACE_ERROR ((LM_ERROR, "ACE_ES_Priority_Timer::cancel_timer: " + "Tried to cancel nonexistent timer.\n")); + act = 0; + } + else + act = (ACE_ES_Timer_ACT *) vp; + + return result; +} + +// ************************************************************ + +ACE_ES_Event_Container::ACE_ES_Event_Container (void) : + // ACE_ES_Event (), + ref_count_ (1) +{ +} + +ACE_ES_Event_Container::~ACE_ES_Event_Container (void) +{ +} + +ACE_ES_Event_Container::ACE_ES_Event_Container (const ACE_ES_Event_Container &ec) + : RtecEventComm_Event (ec), + ref_count_ (1) +{ +} + +ACE_ES_Event_Container::ACE_ES_Event_Container (const RtecEventComm_Event &e) + : RtecEventComm_Event (e), + ref_count_ (1) +{ +} + +ACE_ES_Event_Container * +ACE_ES_Event_Container::_duplicate (void) +{ + ref_count_++; + return this; +} + +void +ACE_ES_Event_Container::_release (void) +{ + if (--ref_count_ == 0) + delete this; +} + +int +ACE_ES_Event_Container::operator== (const ACE_ES_Event_Container &event) +{ + RtecEventComm::Event &event1 = (RtecEventComm::Event &) *this; + RtecEventComm::Event &event2 = (RtecEventComm::Event &) event; + return event1 == event2; +} + +void * +ACE_ES_Event_Container::operator new (size_t nbytes) +{ + ACE_ASSERT (nbytes <= sizeof (ACE_ES_Event_Container)); + return ACE_ES_Memory_Pools::new_Event_Container (); +} + +void +ACE_ES_Event_Container::operator delete (void *mem) +{ + ACE_ES_Memory_Pools::delete_Event_Container (mem); +} + +void +ACE_ES_Event_Container::dump (void) +{ + ::dump_event ((RtecEventComm::Event &) *this); +} + +// ************************************************************ + +ACE_Push_Supplier_Proxy::ACE_Push_Supplier_Proxy (ACE_ES_Supplier_Module *sm) + : supplier_module_ (sm), + push_supplier_ (0) +{ +} + +void +ACE_Push_Supplier_Proxy::connect_push_supplier (RtecEventComm::PushSupplier_ptr push_supplier, + const RtecEventChannelAdmin::SupplierQOS &qos, + CORBA::Environment &_env) +{ + if (this->connected ()) + TAO_THROW (RtecEventChannelAdmin::AlreadyConnected); + + push_supplier_ = + RtecEventComm::PushSupplier::_duplicate(push_supplier); + + // ACE_SupplierQOS_Factory::debug (qos); + + // Copy by value. + qos_ = qos; + + // ACE_SupplierQOS_Factory::debug (qos_); + + // @@ TODO: The SupplierQOS should have a more reasonable interface to + // obtain the supplier_id(), BTW, a callback to push_supplier will + // not work: it usually results in some form of dead-lock. + source_id_ = qos_.publications_[0].event_.source_; + + supplier_module_->connected (this, _env); +} + +void +ACE_Push_Supplier_Proxy::push (const RtecEventComm::EventSet &event, + CORBA::Environment &_env) +{ + ACE_TIMEPROBE (" enter Push_Supplier_Proxy::push"); + + // @@ TOTAL HACK + ACE_hrtime_t ec_recv = ACE_OS::gethrtime (); + for (CORBA::ULong i = 0; i < event.length (); ++i) + { + RtecEventComm::Event& ev = + ACE_const_cast(RtecEventComm::Event&,event[i]); + ORBSVCS_Time::hrtime_to_TimeT (ev.ec_recv_time_, ec_recv); + } + supplier_module_->push (this, event, _env); +} + +void +ACE_Push_Supplier_Proxy::disconnect_push_consumer (CORBA::Environment &_env) +{ + ACE_TIMEPROBE_PRINT; + if (this->connected ()) + { + push_supplier_ = 0; + supplier_module_->disconnecting (this, _env); + } +} + +void +ACE_Push_Supplier_Proxy::shutdown (void) +{ + TAO_TRY + { + push_supplier_->disconnect_push_supplier (TAO_TRY_ENV); + TAO_CHECK_ENV; + } + TAO_CATCHANY + { + ACE_ERROR ((LM_ERROR, "ACE_Push_Supplier_Proxy::shutdown failed.\n")); + } + TAO_ENDTRY; +} + +// ************************************************************ + +ACE_Push_Consumer_Proxy::ACE_Push_Consumer_Proxy (ACE_ES_Consumer_Module *cm) + : push_consumer_ (0), + consumer_module_ (cm) +{ +} + +ACE_Push_Consumer_Proxy::~ACE_Push_Consumer_Proxy (void) +{ +} + + +void +ACE_Push_Consumer_Proxy::connect_push_consumer (RtecEventComm::PushConsumer_ptr push_consumer, + const RtecEventChannelAdmin::ConsumerQOS &qos, + CORBA::Environment &_env) +{ + if (this->connected ()) + TAO_THROW (RtecEventChannelAdmin::AlreadyConnected); + + push_consumer_ = + RtecEventComm::PushConsumer::_duplicate(push_consumer); + // @@ TODO Find out why are two duplicates needed... + RtecEventComm::PushConsumer::_duplicate(push_consumer); + + // ACE_ConsumerQOS_Factory::debug (qos); + + // Copy by value. + qos_ = qos; + + // ACE_ConsumerQOS_Factory::debug (qos_); + + consumer_module_->connected (this, _env); +} + +void +ACE_Push_Consumer_Proxy::disconnect_push_supplier (CORBA::Environment &_env) +{ + ACE_TIMEPROBE_PRINT; + consumer_module_->disconnecting (this, _env); + push_consumer_ = 0; +} + +void +ACE_Push_Consumer_Proxy::suspend (CORBA::Environment &) +{ + correlation_.suspend (); +} + +void +ACE_Push_Consumer_Proxy::resume (CORBA::Environment &) +{ + correlation_.resume (); +} + +void +ACE_Push_Consumer_Proxy::shutdown (void) +{ + TAO_TRY + { + push_consumer_->disconnect_push_consumer (TAO_TRY_ENV); + TAO_CHECK_ENV; + } + TAO_CATCHANY + { + ACE_ERROR ((LM_ERROR, "ACE_Push_Consumer_Proxy::shutdown failed.\n")); + } + TAO_ENDTRY; +} + +// ************************************************************ + +ACE_EventChannel::ACE_EventChannel (u_long type) + : rtu_manager_ (0), + type_ (type), + state_ (INITIAL_STATE), + destroyed_ (0) +{ + consumer_module_ = new ACE_ES_Consumer_Module (this); + // RtecEventChannelAdmin::ConsumerAdmin_duplicate(consumer_module_); + + ACE_NEW(dispatching_module_, + ACE_ES_Priority_Dispatching(this, THREADS_PER_DISPATCH_QUEUE)); + + correlation_module_ = new ACE_ES_Correlation_Module (this); + subscription_module_ = new ACE_ES_Subscription_Module (this); + supplier_module_ = new ACE_ES_Supplier_Module (this); + timer_ = new ACE_ES_Priority_Timer; + + consumer_module_->open (dispatching_module_); + dispatching_module_->open (consumer_module_, correlation_module_); + correlation_module_->open (dispatching_module_, subscription_module_); + subscription_module_->open (correlation_module_, supplier_module_); + supplier_module_->open (subscription_module_); +} + +ACE_EventChannel::~ACE_EventChannel (void) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) ACE_EventChannel deleting all modules.\n")); + + TAO_TRY + { + this->destroy (TAO_TRY_ENV); + TAO_CHECK_ENV; + } + TAO_CATCHANY + { + ACE_ERROR ((LM_ERROR, "%p.\n", "ACE_EventChannel::~ACE_EventChannel")); + } + TAO_ENDTRY; + // @@ TODO: Shouldn't we use _release() instead? + delete rtu_manager_; + delete consumer_module_; + delete dispatching_module_; + delete correlation_module_; + delete subscription_module_; + delete supplier_module_; + delete timer_; +} + +void +ACE_EventChannel::destroy (CORBA::Environment &_env) +{ + ACE_UNUSED_ARG (_env); + + ACE_ES_GUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + ACE_ERROR ((LM_ERROR, "ACE_EventChannel::destroy")); + + if (destroyed_ != 0) + return; + + destroyed_ = 1; + ACE_DEBUG ((LM_DEBUG, "(%t) Event Channel shutting down.\n")); + + // Send a shutdown message through the modules. + supplier_module_->shutdown (); + +#if 0 + // Flush all messages in the channel. + Shutdown_Channel *sc = new Shutdown_Channel (this); + if (sc == 0) + TAO_THROW (CORBA::NO_MEMORY (CORBA::COMPLETED_NO)); + + // Create a wrapper around the dispatch request. + Flush_Queue_ACT *act = new Flush_Queue_ACT (sc, dispatching_module_); + if (act == 0) + TAO_THROW (CORBA::NO_MEMORY (CORBA::COMPLETED_NO)); + + // Set a 100ns timer. + if (this->timer ()->schedule_timer (0, // no rt-info + act, + ACE_Scheduler_MIN_PREEMPTION_PRIORITY, + 100, // 10 usec delta + 0) == -1) // no interval + { + ACE_ERROR ((LM_ERROR, "%p queue_request failed.\n", "ACE_ES_Consumer_Module")); + delete sc; + delete act; + } +#endif +} + +void +ACE_EventChannel::shutdown (void) +{ + // @@ TODO: Find a portable way to shutdown the ORB, on Orbix we have + // to call deactive_impl () on a CORBA::POA is that the portable + // way? + // With TAO we need access to the ORB (to call shutdown() on it). + TAO_ORB_Core_instance ()->orb ()->shutdown (); +} + +void +ACE_EventChannel::report_connect (u_long event) +{ + ACE_ES_GUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + ACE_ERROR ((LM_ERROR, "ACE_EventChannel::report_connect")); + + ACE_CLR_BITS (state_, event); +} + +void +ACE_EventChannel::report_disconnect (u_long event) +{ + ACE_ES_GUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + ACE_ERROR ((LM_ERROR, "ACE_EventChannel::report_disconnect")); + + ACE_SET_BITS (state_, event); + if (state_ == SHUTDOWN) + ACE_DEBUG ((LM_DEBUG, "(%t) Event Channel has no consumers or suppliers.\n")); +} + +// ************************************************************ + +ACE_ES_Subscription_Info::~ACE_ES_Subscription_Info (void) +{ + Subscriber_Map_Iterator iter (type_subscribers_); + + // Delete all type collections. + for (Subscriber_Map_Entry *temp = 0; + iter.next (temp) != 0; + iter.advance ()) + { + delete temp->int_id_; + } +} + +/* +void +ACE_ES_Subscription_Info::Type_Subscribers::operator= +(const ACE_ES_Subscription_Info::Type_Subscribers &rhs) +{ + ACE_ES_Subscription_Info::Subscriber_Set_Iterator iter (rhs.subscribers_); + + for (ACE_ES_Consumer_Rep **consumer = 0; + iter.next (consumer) != 0; + iter.advance ()) + { + if (subscribers_.insert (consumer) != 0) + ACE_ERROR ((LM_ERROR, "%p insert failed.\n", + "ACE_ES_Subscription_Info::Type_Subscribers::operator=")); + } + + // Pointer copy. + dependency_info_ = rhs.dependency_info_; +} +*/ + +// Remove <consumer> from the consumer set in <type_map> set +// corresponding to <type>. +int +ACE_ES_Subscription_Info::remove (Subscriber_Map &type_map, + ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventType type) +{ + Type_Subscribers *subscribers; + + // Find the type set within the type collection. + if (type_map.find (type, subscribers) == -1) + // type_map does not contain the type. + return -1; + + // Remove the consumer from the type set. + if (subscribers->consumers_.remove (consumer) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p remove failed.\n", + "ACE_ES_Subscriber_Info::remove"), -1); + // @@ Should probably remove the supplier from the consumers caller + // list. + + // If the set is empty, remove it from the type collection. + if (subscribers->consumers_.size () == 0) + { + Type_Subscribers *removed_subscribers; + if (type_map.unbind (type, removed_subscribers) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p unbind failed.\n", + "ACE_ES_Subscriber_Info::remove"), -1); + + // Sanity check. + if (removed_subscribers != subscribers) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_ES_Subscriber_Info::remove: " + "removed wrong set!\n"), -1); + + // Free up the set removed. + delete removed_subscribers; + } + + return 0; +} + + +int +ACE_ES_Subscription_Info::remove (SourceID_Map &source_subscribers, + ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventSourceID sid) +{ + Subscriber_Set *subscribers; + + // Find the subscribers of <sid>. + if (source_subscribers.find (sid, subscribers) == -1) + // does not contain the <sid>. + return -1; + + // Remove the consumer from the subscriber set. + if (subscribers->remove (consumer) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p remove failed.\n", + "ACE_ES_Subscriber_Info::remove"), -1); + // @@ Should probably remove the supplier from the consumers caller + // list. + + // If the set is empty, remove it from the type collection. + if (subscribers->size () == 0) + { + Subscriber_Set *removed_subscribers; + if (source_subscribers.unbind (sid, removed_subscribers) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p unbind failed.\n", + "ACE_ES_Subscriber_Info::remove"), -1); + + // Sanity check. + if (removed_subscribers != subscribers) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_ES_Subscriber_Info::remove: " + "removed wrong set!\n"), -1); + + // Free up the set removed. + delete removed_subscribers; + } + + return 0; +} + + +void +ACE_ES_Subscription_Info::append_subscribers (Subscriber_Set &dest, + Subscriber_Set &src) +{ + Subscriber_Set_Iterator src_iter (src); + + // Iterate through the source set. Add each source proxy to the + // destination set. + for (ACE_ES_Consumer_Rep **proxy = 0; + src_iter.next (proxy) != 0; + src_iter.advance ()) + { + if (dest.insert (*proxy) == -1) + ACE_ERROR ((LM_ERROR, "%p: insert failed.\n", "append_subscribers")); + } +} + +int +ACE_ES_Subscription_Info::insert_or_allocate (SourceID_Map &sid_map, + ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventSourceID sid) +{ + Subscriber_Set *subscribers; + + if (sid_map.find (sid, subscribers) == -1) + { + // If the correct type set does not exist, make one with a null + // dependency info (since there is no supplier of this event). + subscribers = new Subscriber_Set; + + if (sid_map.bind (sid, subscribers) == -1) + { + ACE_ERROR ((LM_ERROR, "%p bind failed.\n", + "ACE_ES_Subscription_Info::insert_or_allocate")); + delete subscribers; + return -1; + } + } + + // 0 and 1 are success for insert. + return subscribers->insert (consumer) == -1 ? -1 : 0; +} + +int +ACE_ES_Subscription_Info::insert_or_allocate (Subscriber_Map &type_map, + ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventType type) +{ + Type_Subscribers *subscribers; + + if (type_map.find (type, subscribers) == -1) + { + // If the correct type set does not exist, make one with a null + // dependency info (since there is no supplier of this event). + subscribers = new Type_Subscribers (0); + + if (type_map.bind (type, subscribers) == -1) + { + ACE_ERROR ((LM_ERROR, "%p bind failed.\n", + "ACE_ES_Subscription_Info::insert_or_allocate")); + delete subscribers; + return -1; + } + } + + return subscribers->consumers_.insert (consumer); +} + +int +ACE_ES_Subscription_Info::insert_or_fail (Subscriber_Map &type_map, + ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventType type, + RtecScheduler::Dependency_Info *&dependency) +{ + Type_Subscribers *subscribers; + + // Get the subscriber set for <type>. + if (type_map.find (type, subscribers) == -1) + return -1; + + // Pass back the description of the method generating <type>. + dependency = subscribers->dependency_info_; + + // Insert the new consumer into the subscriber set. + return subscribers->consumers_.insert (consumer); +} + +// ************************************************************ + +ACE_ES_Consumer_Module::ACE_ES_Consumer_Module (ACE_EventChannel* channel) + : lock_ (), + all_consumers_ (), + channel_ (channel), + down_ (0) +{ +} + +void +ACE_ES_Consumer_Module::open (ACE_ES_Dispatching_Module *down) +{ + down_ = down; +} + +void +ACE_ES_Consumer_Module::connected (ACE_Push_Consumer_Proxy *consumer, + CORBA::Environment &_env) +{ + channel_->report_connect (ACE_EventChannel::CONSUMER); + down_->connected (consumer, _env); +} + +void +ACE_ES_Consumer_Module::shutdown_request (ACE_ES_Dispatch_Request *request) +{ + Shutdown_Consumer *sc = (Shutdown_Consumer *) request; + + // Tell everyone else that the consumer is disconnected. This means + // that *nothing* is left in the system for the consumer, so + // everyone can free up any resources. + down_->disconnected (sc->consumer ()); + + ACE_DEBUG ((LM_DEBUG, "Deleting proxy for consumer\n")); + + // Delete the consumer proxy. + delete sc->consumer (); + + ACE_ES_GUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + return; + + // Tell the channel that we may need to shut down. + if (all_consumers_.size () <= 0) + { + ACE_DEBUG ((LM_DEBUG, "(%t) No more consumers connected.\n")); + channel_->report_disconnect (ACE_EventChannel::CONSUMER); + } +} + +void +ACE_ES_Consumer_Module::shutdown (void) +{ + Consumers copy; + + { + ACE_ES_GUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + goto DONE; + + if (all_consumers_.size () == 0) + goto DONE; + + // Make a copy so that the consumers can disconnect without the + // lock being held. + copy = all_consumers_; + } + + // This scope is just to thwart the compiler. It was complaining + // about the above goto's bypassing variable initializations. Yadda + // yadda. + { + Consumer_Iterator iter (copy); + + CORBA::Environment env; + + for (ACE_Push_Consumer_Proxy **proxy = 0; + iter.next (proxy) != 0; + iter.advance ()) + { + (*proxy)->shutdown (); + // @@ Cannnot use CORBA::release (*proxy), since it is a servant. + delete *proxy; + + // Remove the consumer from our list. + { + ACE_ES_GUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + ACE_ERROR ((LM_ERROR, "%p Failed to acquire lock.\n", "ACE_ES_Consumer_Module::shutdown")); + + if (all_consumers_.remove (*proxy) == -1) + ACE_ERROR ((LM_ERROR, "%p Failed to remove consumer.\n", "ACE_ES_Consumer_Module::shutdown")); + } + } + } + +DONE: + channel_->shutdown (); +} + +void +ACE_ES_Consumer_Module::disconnecting (ACE_Push_Consumer_Proxy *consumer, + CORBA::Environment &_env) +{ + { + ACE_ES_GUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + TAO_THROW (RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR); + + if (all_consumers_.remove (consumer) == -1) + return; + } + + // Tell everyone else that the consumer is disconnecting. This + // allows them to remove the consumer from any subscription lists + // etc. However, messages may still be queued in the ReactorEx or + // in the Dispatching Module for this consumer, so no queues or + // proxies can be deleted just yet. + down_->disconnecting (consumer, _env); + + // Send a shutdown message through the system. When this is + // dispatched, the consumer proxy will be deleted. <request> is + // queued in the Priority_Timer at <priority> level. It will be + // scheduled for dispatching in 1 nanosecond. This gives components + // a hook into the first queueing point in the channel. + + // Create a shutdown message. When this is dispatched, it will + // delete the proxy. + Shutdown_Consumer *sc = new Shutdown_Consumer (this, consumer); + if (sc == 0) + TAO_THROW (CORBA::NO_MEMORY (CORBA::COMPLETED_NO)); + + // Create a wrapper around the dispatch request. + Flush_Queue_ACT *act = new Flush_Queue_ACT (sc, channel_->dispatching_module_); + if (act == 0) + TAO_THROW (CORBA::NO_MEMORY (CORBA::COMPLETED_NO)); + + ACE_DEBUG ((LM_DEBUG, "(%t) initiating consumer disconnect.\n")); + + // Set a 100ns timer. + TimeBase::TimeT ns100; + ORBSVCS_Time::hrtime_to_TimeT (ns100, 100); + if (channel_->timer ()->schedule_timer (0, // no rt_info + act, + // ::Preemption_Priority (consumer->qos ().rt_info_), + ACE_Scheduler_MIN_PREEMPTION_PRIORITY, + ns100, + ORBSVCS_Time::zero) == -1) + { + ACE_ERROR ((LM_ERROR, "%p queue_request failed.\n", "ACE_ES_Consumer_Module")); + delete sc; + delete act; + } +} + +// This method executes in the same thread of control that will hand +// the event set to the consumer (or it's proxy). A network proxy may +// copy the event set to the network buffer. An active client may +// copy the event set to be queued. Or a same address-space consumer +// can read the set we allocated off the stack. +void +ACE_ES_Consumer_Module::push (const ACE_ES_Dispatch_Request *request, + CORBA::Environment &_env) +{ + ACE_TIMEPROBE (" enter ES_Consumer_Module::push"); + // We'll create a temporary event set with the size of the incoming + // request. + RtecEventComm::EventSet event_set (request->number_of_events ()); + request->make_copy (event_set); + + // Forward the event set. + ACE_hrtime_t ec_send = ACE_OS::gethrtime (); + for (CORBA::ULong i = 0; i < event_set.length (); ++i) + { + RtecEventComm::Event& ev = + ACE_const_cast(RtecEventComm::Event&,event_set[i]); + ORBSVCS_Time::hrtime_to_TimeT (ev.ec_send_time_, ec_send); + } + request->consumer ()->push (event_set, _env); + ACE_TIMEPROBE (" leave ES_Consumer_Module::push"); +} + +RtecEventChannelAdmin::ProxyPushSupplier_ptr +ACE_ES_Consumer_Module::obtain_push_supplier (CORBA::Environment &_env) +{ + ACE_Push_Consumer_Proxy *new_consumer = new ACE_Push_Consumer_Proxy (this); + + // Get a new supplier proxy object. + if (new_consumer == 0) + { + ACE_ERROR ((LM_ERROR, "ACE_EventChannel" + "::obtain_push_supplier failed.\n")); + TAO_THROW_RETURN (CORBA::NO_MEMORY (CORBA::COMPLETED_NO), 0); + } + + { + ACE_ES_GUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + { + delete new_consumer; + TAO_THROW_RETURN (RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR, 0); + } + + if (all_consumers_.insert (new_consumer) == -1) + ACE_ERROR ((LM_ERROR, "ACE_ES_Consumer_Module insert failed.\n")); + } + + // Return the CORBA object reference to the new supplier proxy. + return new_consumer->get_ref (); +} + +// ************************************************************ + +ACE_ES_Correlation_Module::ACE_ES_Correlation_Module (ACE_EventChannel *channel) + : channel_ (channel), + up_ (0), + subscription_module_ (0) +{ +} + +void +ACE_ES_Correlation_Module::open (ACE_ES_Dispatching_Module *up, + ACE_ES_Subscription_Module *sm) +{ + up_ = up; + subscription_module_ = sm; +} + +void +ACE_ES_Correlation_Module::connected (ACE_Push_Consumer_Proxy *consumer, + CORBA::Environment &_env) +{ + // Initialize the consumer correlation filter. + if (consumer->correlation ().connected (consumer, this) == -1) + TAO_THROW (RtecEventChannelAdmin::EventChannel::CORRELATION_ERROR); +} + +void +ACE_ES_Correlation_Module::disconnecting (ACE_Push_Consumer_Proxy *consumer, + CORBA::Environment &) +{ + if (consumer->correlation ().disconnecting () == -1) + ACE_ERROR ((LM_ERROR, "ACE_ES_Correlation_Module::disconnecting failed.\n")); +} + +int +ACE_ES_Correlation_Module::subscribe (ACE_ES_Consumer_Rep *consumer) +{ + return subscription_module_->subscribe (consumer); +} + +/* +int +ACE_ES_Correlation_Module::unsubscribe (ACE_ES_Consumer_Rep *cr) +{ + return subscription_module_->unsubscribe (cr); +} +*/ + +void +ACE_ES_Correlation_Module::push (ACE_ES_Consumer_Rep *consumer, + ACE_ES_Event_Container *event, + CORBA::Environment &_env) +{ + ACE_TIMEPROBE (" enter ACE_ES_Correlation_Module::push"); + ACE_ES_Dispatch_Request *request = + consumer->correlation ()->push (consumer, event); + ACE_TIMEPROBE (" pushed to Correlation_Module"); + + // If request == 0, then the event was queued for later. Otherwise, + // we need to push the event now. + if (request != 0) + up_->push (request, _env); + + ACE_TIMEPROBE (" push_source_type: Dispatch Module enqueuing"); +} + +// Must check consumer->qos ().use_timeout () before calling this. +// This method is supposed properly schedule a timer with respect to +// the consumer's priority AND the correlation that should receive the +// timeout event. +int +ACE_ES_Correlation_Module::schedule_timeout (ACE_ES_Consumer_Rep_Timeout *consumer) +{ + RtecEventComm::Time &interval = + consumer->dependency ()->event_.creation_time_; + RtecEventComm::Time &delay = + consumer->dependency ()->event_.creation_time_; + + // Store the preemption priority so we can cancel the correct timer. + // The priority values may change during the process lifetime (e.g., + // after the scheduler has been run). + consumer->preemption_priority (::IntervalToPriority (interval)); + + // Register the timer. + int id = channel_->timer ()->schedule_timer (consumer->dependency ()->rt_info, + consumer, + consumer->preemption_priority (), + delay, interval); + + // Store the timer id for canceling. + consumer->timer_id (id); + + if (id == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p schedule timer failed.\n", + "ACE_ES_Correlation_Module::schedule_timeout"), -1); + + return 0; +} + +// Must check consumer->qos ().timeout_ before calling this. +int +ACE_ES_Correlation_Module::cancel_timeout (ACE_ES_Consumer_Rep_Timeout *consumer) +{ + // Cancel the timer from the Priority Timer. + ACE_ES_Timer_ACT *act; + channel_->timer ()->cancel_timer (consumer->preemption_priority (), + consumer->timer_id (), + act); + + ACE_ASSERT (consumer == act); + + // Free up the Timer ACT. + // delete act; + + return 0; +} + + +int +ACE_ES_Correlation_Module::reschedule_timeout (ACE_ES_Consumer_Rep_Timeout *consumer) +{ + if (this->cancel_timeout (consumer) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", "ACE_ES_Disjunction_Group::reschedule_deadline"), -1); + else + { + RtecEventComm::Time &interval = + consumer->dependency ()->event_.creation_time_; + RtecEventComm::Time &delay = + consumer->dependency ()->event_.creation_time_; + + // Store the preemption priority so we can cancel the correct timer. + // The priority values may change during the process lifetime (e.g., + // after the scheduler has been run). + consumer->preemption_priority (::IntervalToPriority (interval)); + + // Register the timer. + int id = channel_->timer ()->schedule_timer (0, // Do not pass an RT_Info. + consumer, + consumer->preemption_priority (), + delay, interval); + + // Store the timer id for canceling. + consumer->timer_id (id); + + if (id == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p schedule timer failed.\n", + "ACE_ES_Correlation_Module::reschedule_timeout"), -1); + + return 0; + } +} + +void +ACE_ES_Correlation_Module::shutdown (void) +{ + // Perhaps this should call disconnecting on all the consumers? + // We'll opt to just forward this message for now. + up_->shutdown (); +} + +// ************************************************************ + +ACE_ES_Consumer_Correlation::ACE_ES_Consumer_Correlation (void) : + correlation_module_ (0), + type_id_index_ (0), + channel_ (0), + qos_ (), + pending_events_ (0), + lock_ (), + consumer_ (0), + pending_flags_ (0), + consumer_reps_ (0), + n_consumer_reps_ (0), + timer_reps_ (0), + n_timer_reps_ (0), + conjunction_groups_ (0), + n_conjunction_groups_ (0), + disjunction_groups_ (0), + n_disjunction_groups_ (0), + connected_ (0) +{ +} + +ACE_ES_Consumer_Correlation::~ACE_ES_Consumer_Correlation (void) +{ + delete [] timer_reps_; + for (int cr = 0; cr < n_consumer_reps_; cr++) + consumer_reps_[cr]->_release (); + delete [] consumer_reps_; + delete [] conjunction_groups_; + delete [] disjunction_groups_; + delete [] pending_events_; +} + +void +ACE_ES_Consumer_Correlation::disconnect_push_supplier (CORBA::Environment &) +{ + connected_ = 0; +} + +int +ACE_ES_Consumer_Correlation::allocate_correlation_resources (ACE_ES_Dependency_Iterator &iter) +{ + n_conjunction_groups_ = iter.n_conjunctions (); + if (n_conjunction_groups_ > 0) + { + conjunction_groups_ = new ACE_ES_Conjunction_Group[n_conjunction_groups_]; + if (conjunction_groups_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", "ACE_ES_Consumer_Correlation::connected"), -1); + for (int n=0; n < n_conjunction_groups_; n++) + conjunction_groups_[n].set_correlation_module (correlation_module_); + } + + n_disjunction_groups_ = iter.n_disjunctions (); + if (n_disjunction_groups_ > 0) + { + disjunction_groups_ = new ACE_ES_Disjunction_Group[n_disjunction_groups_]; + if (disjunction_groups_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", "ACE_ES_Consumer_Correlation::connected"), -1); + for (int n=0; n < n_disjunction_groups_; n++) + disjunction_groups_[n].set_correlation_module (correlation_module_); + } + + n_consumer_reps_ = iter.n_events (); + if (n_consumer_reps_ > 0) + { + // This allocates more than is needed if there are repeats: + // (A+B)|(B+C). We allocate these individually so that they can + // be deleted individually. + + typedef ACE_ES_Consumer_Rep *reparray; + consumer_reps_ = new reparray[n_consumer_reps_]; + + for (int cr = 0; cr < n_consumer_reps_; cr++) + { + consumer_reps_[cr] = new ACE_ES_Consumer_Rep; + if (consumer_reps_[cr] == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", "ACE_ES_Consumer_Correlation::connected"), -1); + } + } + + n_timer_reps_ = iter.n_timeouts (); + if (n_timer_reps_ > 0) + { + timer_reps_ = new ACE_ES_Consumer_Rep_Timeout[n_timer_reps_]; + if (timer_reps_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", "ACE_ES_Consumer_Correlation::connected"), -1); + } + + // This allocates more than is needed. + pending_events_ = new Event_Set[n_consumer_reps_ + n_timer_reps_]; + if (pending_events_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", "ACE_ES_Consumer_Correlation::connected"), -1); + + return 0; +} + +// We don't need synchronization until after we've been connected and +// subscribed to events. +int +ACE_ES_Consumer_Correlation::connected (ACE_Push_Consumer_Proxy *consumer, + ACE_ES_Correlation_Module *correlation_module) +{ + correlation_module_ = correlation_module; + consumer_ = consumer; + + // for (CORBA_Types::ULong index=0; index < consumer->qos ().dependencies_.length (); index++) + // consumer->qos ().dependencies_[index].event_.dump (); + + ACE_ES_Dependency_Iterator iter (consumer->qos ().dependencies); + iter.parse (); + if (this->allocate_correlation_resources (iter) == -1) + return -1; + + + int cgroup_index = -1; + int dgroup_index = -1; + int crep_index = 0; + int trep_index = 0; + RtecEventComm::EventType group_type = 0; + + while (iter.advance_dependency () == 0) + { + // Keep track of how many conjunction and disjunction groups are + // registered. Update the index pointers so that the helper + // functions can update the appropriate group objects. + switch ((*iter).event_.type_) + { + case ACE_ES_CONJUNCTION_DESIGNATOR: + cgroup_index++; + ACE_ASSERT (cgroup_index < n_conjunction_groups_); + group_type = ACE_ES_CONJUNCTION_DESIGNATOR; + continue; + + case ACE_ES_DISJUNCTION_DESIGNATOR: + dgroup_index++; + ACE_ASSERT (dgroup_index < n_disjunction_groups_); + group_type = ACE_ES_DISJUNCTION_DESIGNATOR; + continue; + + case ACE_ES_GLOBAL_DESIGNATOR: + group_type = ACE_ES_GLOBAL_DESIGNATOR; + continue; + + // These Delegate to the appropriate registration method. +#if 0 + // @@ TODO rt_info_ is a handle_t now, does checking against + // 0 still make sense? + // Check for a null rt_info. + if ((*iter).rt_info_ == 0) + { + ACE_ERROR ((LM_ERROR, "Found a ConsumerQOS::dependencies[].rt_info_ == 0.\n")); + continue; + } +#endif /* 0 */ + + case ACE_ES_EVENT_TIMEOUT: + // For backwards compatibility. + case ACE_ES_EVENT_DEADLINE_TIMEOUT: + if (this->register_deadline_timeout (*iter, + group_type, + cgroup_index, + dgroup_index, + trep_index) == -1) + return -1; + break; + + case ACE_ES_EVENT_INTERVAL_TIMEOUT: + if (this->register_interval_timeout (*iter, + group_type, + cgroup_index, + dgroup_index, + trep_index) == -1) + return -1; + break; + + case ACE_ES_EVENT_ACT: + // Store the ACT in the current conjunction or disjunction + // group. + switch (group_type) + { + case ACE_ES_CONJUNCTION_DESIGNATOR: + conjunction_groups_[cgroup_index].set_act ((*iter).event_); + break; + case ACE_ES_DISJUNCTION_DESIGNATOR: + disjunction_groups_[cgroup_index].set_act ((*iter).event_); + break; + case ACE_ES_GLOBAL_DESIGNATOR: + default: + ACE_ERROR ((LM_ERROR, "Warning: ACTs not implemented for Global.\n")); + } + break; + + default: + // Non-timer event subscription. + if (this->register_event (*iter, + group_type, + cgroup_index, + dgroup_index, + crep_index) == -1) + return -1; + break; + } + } + + // We may not use all of the consumer reps if there are repeats: + // (A+B)|(B+C). Must update n_consumer_reps_ so we don't try to + // unsubscribe a blank rep during disconnect. + if (crep_index < n_consumer_reps_) + n_consumer_reps_ = crep_index; + + return 0; +} + +int +ACE_ES_Consumer_Correlation::register_deadline_timeout (RtecEventChannelAdmin::Dependency &dependency, + RtecEventComm::EventType group_type, + int cgindex, + int dgindex, + int &trep_index) +{ + // new_timeout will be returned as an ACT. When executed, it will + // forward *iter.event_ to the consumer. + ACE_ES_Consumer_Rep_Timeout *new_timeout = &timer_reps_[trep_index++]; + new_timeout->init (this, dependency); + new_timeout->correlation_type (ACE_ES_Consumer_Rep::DEADLINE_TIMEOUT); + // Deadline timers do not need type ids. + + switch (group_type) + { + case ACE_ES_CONJUNCTION_DESIGNATOR: + // Reps keep pointers back to the groups that they're deadlines for. + new_timeout->add_disjunction_group (conjunction_groups_[cgindex]); + // Groups keep references to the deadline timers for rescheduling. + if (conjunction_groups_[cgindex].set_deadline_timeout (new_timeout) == -1) + return -1; + break; + + case ACE_ES_DISJUNCTION_DESIGNATOR: + new_timeout->add_disjunction_group (disjunction_groups_[dgindex]); + if (disjunction_groups_[dgindex].set_deadline_timeout (new_timeout) == -1) + return -1; + break; + + case ACE_ES_GLOBAL_DESIGNATOR: + ACE_ERROR_RETURN ((LM_ERROR, "No global deadline timeouts, yet!\n"), -1); + } + + return 0; +} + +int +ACE_ES_Consumer_Correlation::register_interval_timeout (RtecEventChannelAdmin::Dependency &dependency, + RtecEventComm::EventType group_type, + int cgindex, + int /* dgindex */, + int &trep_index) +{ + // new_timeout will be returned as an ACT. When executed, it will + // forward *iter.event_ to the consumer. + ACE_ES_Consumer_Rep_Timeout *new_timeout = &timer_reps_[trep_index++]; + new_timeout->init (this, dependency); + new_timeout->type_id (this->new_type_id ()); + + switch (group_type) + { + case ACE_ES_CONJUNCTION_DESIGNATOR: + // If it's a conjunction, then we need to perform correlations + // on the timeout. + new_timeout->correlation_type (ACE_ES_Consumer_Rep::CORRELATE); + conjunction_groups_[cgindex].add_type (new_timeout->type_id ()); + break; + + case ACE_ES_DISJUNCTION_DESIGNATOR: + case ACE_ES_GLOBAL_DESIGNATOR: + new_timeout->correlation_type (ACE_ES_Consumer_Rep::NO_CORRELATION); + break; + } + + // Schedule the timeout. + if (correlation_module_->schedule_timeout (new_timeout) == -1) + return -1; + else + return 0; +} + +// Search <creps> for a rep matching <dependency>. If one is not +// found, allocate one. All returned reps should have the appropriate +// type_id set. +ACE_ES_Consumer_Rep * +ACE_ES_Consumer_Correlation::get_consumer_rep (RtecEventChannelAdmin::Dependency &dependency, + int &crep_index) +{ + ACE_ES_Consumer_Rep *rep = 0; + + // Step through all existing consumer reps. + for (int x=0; x < crep_index; x++) + { + RtecEventComm::Event& e = consumer_reps_[x]->dependency ()->event_; + // If <dependency> matches any previously subscribed consumer + // reps, we'll reuse it. + if (e.type_ == dependency.event_.type_ + && e.source_ == dependency.event_.source_ ) + { + rep = consumer_reps_[x]; + break; + } + } + + // Check if we didn't find it. + if (rep == 0) + { + if (crep_index >= n_consumer_reps_) + ACE_ERROR_RETURN ((LM_ERROR, "Too many event registrations.\n"), 0); + // Allocate a new rep and set its type id. + rep = consumer_reps_[crep_index]; + crep_index++; + rep->init (this, dependency); + rep->type_id (this->new_type_id ()); + } + + return rep; +} + +int +ACE_ES_Consumer_Correlation::new_type_id (void) +{ + int type_id = type_id_index_; + if (++type_id_index_ >= ACE_ES_MAX_SUBSCRIPTIONS) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_ES_MAX_SUBSCRIPTIONS exceeded.\n"),0); + else + return type_id; +} + +int +ACE_ES_Consumer_Correlation::register_event (RtecEventChannelAdmin::Dependency &dependency, + RtecEventComm::EventType group_type, + int cgindex, + int dgindex, + int &crep_index) +{ + // These are stored in the subscription module data structures. + ACE_ES_Consumer_Rep *consumer_rep = this->get_consumer_rep (dependency, crep_index); + + if (consumer_rep == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", + "ACE_ES_Consumer_Correlation::register_event"), -1); + + switch (group_type) + { + case ACE_ES_CONJUNCTION_DESIGNATOR: + // If it's a conjunction, then we need to perform correlations + // on the object. Otherwise, NO_CORRELATION is set by default. + consumer_rep->correlation_type (ACE_ES_Consumer_Rep::CORRELATE); + conjunction_groups_[cgindex].add_type (consumer_rep->type_id ()); + break; + + case ACE_ES_DISJUNCTION_DESIGNATOR: + consumer_rep->add_disjunction_group (disjunction_groups_[dgindex]); + break; + + case ACE_ES_GLOBAL_DESIGNATOR: + ACE_ERROR ((LM_ERROR, "ACE_ES_Consumer_Correlation::register_event: " + "ACE_ES_GLOBAL_DESIGNATOR not implemented.\n")); + break; + } + + // Subscribe the consumer_rep to the suppliers. + if (correlation_module_->subscribe (consumer_rep) == -1) + return -1; + else + return 0; +} + +int +ACE_ES_Consumer_Correlation::disconnecting (void) +{ + // If we were forwarding events, disconnect as a supplier. + if (connected_) + { + CORBA::Environment env; + channel_->disconnect_push_consumer (env); + if (env.exception () != 0) + ACE_ERROR ((LM_ERROR, "ACE_ES_Consumer_Correlation::disconnecting failed.\n")); + } + + for (int x=0; x < n_timer_reps_; x++) + correlation_module_->cancel_timeout (&timer_reps_[x]); + + for (int y=0; y < n_consumer_reps_; y++) + if (consumer_reps_[y] != 0) + consumer_reps_[y]->disconnect (); + + return 0; +} + +ACE_ES_Dispatch_Request * +ACE_ES_Consumer_Correlation::push (ACE_ES_Consumer_Rep *cr, + ACE_ES_Event_Container *event) +{ + ACE_TIMEPROBE (" ACE_ES_Consumer_Correlation::push, enter"); + + // Check if this event needs any correlating, or if it should just + // be forwarded real fast-like. + switch (cr->correlation_type ()) + { + case ACE_ES_Consumer_Rep::NO_CORRELATION: + { + // Calls reschedule on all disjunction groups it belongs to. + cr->reschedule_deadlines (); + + ACE_TIMEPROBE (" Consumer_Correlation::push, determine NO CORR."); + ACE_ES_Dispatch_Request *request = + new ACE_ES_Dispatch_Request (consumer_, event, cr->dependency ()->rt_info); + ACE_TIMEPROBE (" Consumer_Correlation::push, NO_CORR: alloc"); + + if (request == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", + "ACE_ES_Consumer_Correlation::push"), 0); + + return request; + } + + case ACE_ES_Consumer_Rep::CORRELATE: + return this->correlate (cr, event); + + case ACE_ES_Consumer_Rep::DEADLINE_TIMEOUT: + { + ACE_ES_Dispatch_Request *request = + new ACE_ES_Dispatch_Request (consumer_, cr->dependency ()->rt_info); + + if (request == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", + "ACE_ES_Consumer_Correlation::push"), 0); + + // Add the deadline timeout to the outbox. + request->event_set () += event; + + // Add any pending events to the outbox. + cr->top_group ()->add_events (&(request->event_set ()), + pending_events_, pending_flags_); + + return request; + } + + default: + ACE_ERROR_RETURN ((LM_ERROR, "ACE_ES_Consumer_Correlation::push:" + " unknown correlation type\n"), 0); + } +} + +// @@ If we're just event forwarding, then no pending_events_ need to +// be kept! I'll add this optimization later. +ACE_ES_Dispatch_Request * +ACE_ES_Consumer_Correlation::correlate (ACE_ES_Consumer_Rep *cr, + ACE_ES_Event_Container *event) +{ + // If the consumer has specified correlation criteria, then we must + // first acquire the mutex. + ACE_ES_GUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", + "ACE_ES_Consumer_Correlation::push"), 0); + + // Add the new event to the pending events. + pending_events_[cr->type_id ()] += event; + + // Set the bit corresponding to the arrived event. + // This should be pending_flags_->event_arrived (index); + ACE_SET_BITS (pending_flags_, ACE_INT2BIT[cr->type_id ()]); + + ACE_ES_Dispatch_Request *request = 0; + Event_Set *outbox = 0; + // Since add_events changes pending_flags_, we need to keep this + // for all iterations through the conjunction groups. + u_long freeze_pending_flags = pending_flags_; + + for (int x=0; x < n_conjunction_groups_; x++) + { + if (conjunction_groups_[x].should_forward (freeze_pending_flags)) + { + // If there is a deadline timer for this conjunction group, + // this will reschedule them. + conjunction_groups_[x].reschedule_deadline (); + + // First time in, allocate the new dispatch request. + if (request == 0) + { + request = + new ACE_ES_Dispatch_Request (consumer_, + cr->dependency ()->rt_info); + if (request == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", + "ACE_ES_Consumer_Correlation::correlate"), 0); + outbox = &(request->event_set ()); + } + + // Add each of the pending events for this correlation to + // the outgoing dispatch request. If outbox == 0, then + // this will just clear any pending events. + conjunction_groups_[x].add_events (outbox, + pending_events_, + pending_flags_); + } + } + + return request; +} + + +// ************************************************************ + +ACE_ES_Consumer_Rep::~ACE_ES_Consumer_Rep (void) +{ +} + +void +ACE_ES_Consumer_Rep::execute (void) +{ + ACE_ERROR ((LM_ERROR, "Warning! ACE_ES_Consumer_Rep::execute called.\n")); +} + +// ************************************************************ + +void +ACE_ES_Consumer_Rep_Timeout::execute (void) +{ + ACE_TIMEPROBE (" Consumer_Rep_Timeout::execute"); + if (this->receiving_events ()) + { + CORBA::Environment __env; + ACE_Time_Value tv = ACE_OS::gettimeofday (); + ORBSVCS_Time::Time_Value_to_TimeT + (timeout_event_->creation_time_, tv); + correlation_->correlation_module_->push (this, timeout_event_, __env); + if (__env.exception () != 0) + ACE_ERROR ((LM_ERROR, "ACE_ES_Consumer_Rep_Timeout::execute: unexpected exception.\n")); + } +} + +// ************************************************************ + +ACE_ES_Subscription_Module::ACE_ES_Subscription_Module (ACE_EventChannel *channel) + : channel_ (channel), + up_ (0), + down_ (0) +{ +} + +void +ACE_ES_Subscription_Module::open (ACE_ES_Correlation_Module *up, + ACE_ES_Supplier_Module *down) +{ + // Brilliant. + up_ = up; + down_ = down; +} + +ACE_ES_Subscription_Module::~ACE_ES_Subscription_Module (void) +{ +} + +// When a supplier connects, we step through each of its +// publications. For each event type published, we allocate a set in +// the suppliers type collection. Then we build a subscribers list +// starting with any consumers having a type-based subscription in the +// global type collection. +void +ACE_ES_Subscription_Module::connected (ACE_Push_Supplier_Proxy *supplier, + CORBA::Environment &_env) +{ + RtecEventComm::EventSourceID sid = 0; + // We will record the source_id for later usage. + { + ACE_ES_WGUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + TAO_THROW (RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR); + + if (all_suppliers_.insert (supplier) == -1) + ACE_ERROR ((LM_ERROR, "ACE_ES_Subscription_Module insert failed.\n")); + + // For every type that this supplier generates, bind a new + // Type_Subscribers to the type in the supplier proxy's type + // collection. + RtecEventChannelAdmin::PublicationSet &publications = supplier->qos ().publications_; + + sid = publications[0].event_.source_; + for (CORBA::ULong index=0; index < publications.length (); index++) + { + // Check to make sure an RT_Info was specified. +#if 0 + // @@ TODO: We should check if rt_info is a valid handle_t. + if (publications[index].dependency_info_.rt_info.value() == 0) + { + ACE_ERROR ((LM_ERROR, "Found a SupplierQOS::dependency_info_.rt_info_ == 0\n")); + continue; + } +#endif + + RtecEventComm::EventType &event_type = + publications[index].event_.type_; + + // Check to make sure a type was specified. + if (event_type == ACE_ES_EVENT_ANY) + { + ACE_ERROR ((LM_ERROR, "ACE_ES_Subscription_Module::connected: " + "source is publishing ACE_ES_EVENT_ANY.\n")); + continue; + } + + // Make a new set for the proxy. Include the dependency + // info describing the RT_Method that generates this event. + // This object will hold all the consumers that subscribe to + // this publication. + ACE_ES_Subscription_Info::Type_Subscribers *new_subscribers = + new ACE_ES_Subscription_Info::Type_Subscribers (&(publications[index].dependency_info_)); + + if (new_subscribers == 0) + { + ACE_ERROR ((LM_ERROR, "%p.\n", "ACE_ES_Subscription_Module::connected")); + return; + } + + // Check the global type collection for consumers that register + // before suppliers. + ACE_ES_Subscription_Info::Type_Subscribers *existing_subscribers; + if (type_subscribers_.find (event_type, existing_subscribers) == 0) + { + // Iterate through existing subscribers. + ACE_ES_Subscription_Info::Subscriber_Set_Iterator iter (existing_subscribers->consumers_); + + for (ACE_ES_Consumer_Rep **proxy = 0; + iter.next (proxy) != 0; + iter.advance ()) + { + // Each existing subscriber will get appended to the + // new subscribers list. Dependencies are updated. + + // @@ TODO: Handle exceptions. + ACE_Scheduler_Factory::server()->add_dependency + ((*proxy)->dependency()->rt_info, + new_subscribers->dependency_info_->rt_info, + new_subscribers->dependency_info_->number_of_calls, + _env); + if (_env.exception () != 0) + return; + // @@ TODO use the TAO_TRY macros. + + if (new_subscribers->consumers_.insert (*proxy) == -1) + { + ACE_ERROR ((LM_ERROR, + "%p: add_dependency/insert failed.\n", + "ACE_ES_Subscription_Module::connected")); + continue; + } + } + } + + // Put the new subscribers for this event type in the supplier + // proxy's type map. + if (supplier->subscription_info ().type_subscribers_. + bind (event_type, new_subscribers) != 0) + { + // This may occur with a double bind, I think. + ACE_ERROR ((LM_ERROR, "%p can't initialize type.\n", + "ACE_ES_Subscription_Module::connected")); + delete new_subscribers; + continue; + } + } + } // release lock + + // Reregister any consumers that tried to subscribe before this + // supplier connected. + // NOTE: We used to call back the supplier here (using + // supplier->source_id()), this is ineffective and leads to all kind + // of dead-locks (the supplier is blocked and waiting for us). + // We use the information on the publications to get the source_id. + this->reregister_consumers (sid); +} + +// Step through each of the source_subscribers looking for consumers +// that registered for <source> before <source> connected. +void +ACE_ES_Subscription_Module::reregister_consumers (RtecEventComm::EventSourceID source_id) +{ + ACE_ES_Subscription_Info::Subscriber_Set *subscribers = 0; + if (source_subscribers_.find (source_id, subscribers) == -1) + // Not found. + return; + + ACE_ES_Subscription_Info::Subscriber_Set_Iterator iter (*subscribers); + + // Try to reregister all consumers. + for (ACE_ES_Consumer_Rep **consumer = 0; + iter.next (consumer) != 0; + iter.advance ()) + if (this->subscribe (*consumer) == -1) + ACE_ERROR ((LM_ERROR, "%p.\n" "ACE_ES_Subscription_Module::reregister_consumers")); +} + + +void +ACE_ES_Subscription_Module::disconnecting (ACE_Push_Supplier_Proxy *supplier, + CORBA::Environment &_env) +{ + ACE_ES_WGUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + TAO_THROW (RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR); + + if (all_suppliers_.remove (supplier) == -1) + TAO_THROW (RtecEventChannelAdmin::EventChannel::SUBSCRIPTION_ERROR); + + // Remove all consumers from the supplier's source-based subscription lists. + ACE_ES_Subscription_Info::Subscriber_Set_Iterator source_iterator + (supplier->subscription_info ().source_subscribers_); + + for (ACE_ES_Consumer_Rep **consumer; + source_iterator.next (consumer) != 0; + source_iterator.advance ()) + (*consumer)->_release (); + + // Get the subscriber list for each type. + ACE_ES_Subscription_Info::Subscriber_Map_Iterator type_map_iterator + (supplier->subscription_info ().type_subscribers_); + + for (ACE_ES_Subscription_Info::Subscriber_Map_Entry *entry; + type_map_iterator.next (entry) != 0; + type_map_iterator.advance ()) + { + // Remove all consumers from the supplier's source-based subscription lists. + ACE_ES_Subscription_Info::Subscriber_Set_Iterator type_iterator + (entry->int_id_->consumers_); + + for (ACE_ES_Consumer_Rep **c; + type_iterator.next (c) != 0; + type_iterator.advance ()) + (*c)->_release (); + } +} + +int +ACE_ES_Subscription_Module::subscribe_all (ACE_ES_Consumer_Rep *) +{ + ACE_ERROR_RETURN ((LM_ERROR, "Consumer tried to register for all" + "events! This is not implemented.\n"), -1); +} + +int +ACE_ES_Subscription_Module::subscribe_source (ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventSourceID source) +{ + // Step through all Supplier Proxies looking for a match to + // -supplier-. Add the -consumer- to the correct supplier proxy. + Supplier_Iterator iter (all_suppliers_); + + int success = -1; + + for (ACE_Push_Supplier_Proxy **proxy = 0; + iter.next (proxy) != 0; + iter.advance ()) + { + // Operator == checks if <proxy> is a proxy for <supplier>. + if ((**proxy) == source) + { + ACE_ES_WGUARD mon ((*proxy)->subscription_info ().lock_); + + ACE_ES_Subscription_Info::Subscriber_Set &set = + (*proxy)->subscription_info ().source_subscribers_; + + // Insert the consumer to the supplier's subscription set for + // the type. + int insert_result = set.insert (consumer); + switch (insert_result) + { + case -1: + // Error. + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", + "Subscription Module::subscribe_source"), -1); + case 0: + default: + { + // Increment the consumer rep's reference count. + consumer->_duplicate (); + // Success. + // Add each of the supplier's dependency infos to the + // consumer's dependency list. + ACE_ES_Subscription_Info::Subscriber_Map_Iterator iter2 + ((*proxy)->subscription_info ().type_subscribers_); + + // Delete all type collections. + for (ACE_ES_Subscription_Info::Subscriber_Map_Entry *temp = 0; + iter2.next (temp) != 0; + iter2.advance ()) + { + TAO_TRY + { + ACE_Scheduler_Factory::server()->add_dependency + (consumer->dependency()->rt_info, + temp->int_id_->dependency_info_->rt_info, + temp->int_id_->dependency_info_->number_of_calls, + TAO_TRY_ENV); + TAO_CHECK_ENV; + + } + TAO_CATCHANY + { + TAO_TRY_ENV.print_exception ("error adding dependency"); + return -1; + } + TAO_ENDTRY; + } + } + + case 1: + // Already there. + success = 0; + break; + } + } + } + + // Add the consumer to the global source subscribers list. + if (success == -1) + return ACE_ES_Subscription_Info::insert_or_allocate (source_subscribers_, + consumer, + source); + else + return success; +} + +// Step through all Supplier Proxies. For each proxy, if it generates +// <type>, add <consumer> to its subscription info. +int +ACE_ES_Subscription_Module::subscribe_type (ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventType type) +{ + // First insert <consumer> into the global type collection set + // corresponding to <type>. The type collection will only be used + // when suppliers register late. + if (ACE_ES_Subscription_Info::insert_or_allocate (type_subscribers_, + consumer, type) == -1) + return -1; + + consumer->_duplicate (); + + Supplier_Iterator iter (all_suppliers_); + + for (ACE_Push_Supplier_Proxy **proxy = 0; + iter.next (proxy) != 0; + iter.advance ()) + { + ACE_ES_WGUARD mon ((*proxy)->subscription_info ().lock_); + // Insert the consumer to the supplier's subscription set for + // the type. If the supplier does not publish this type, the + // operation will fail. If this succeeds, dependency_info will + // be added to the consumer. + RtecScheduler::Dependency_Info *dependency_info; + if (ACE_ES_Subscription_Info::insert_or_fail + ((*proxy)->subscription_info ().type_subscribers_, + consumer, type, dependency_info) == 0) + { + consumer->_duplicate (); + // Success. Add the supplier dependency info to the + // consumer's dependency list. + // @@ TODO handle exceptions. + TAO_TRY + { + ACE_Scheduler_Factory::server()->add_dependency + (consumer->dependency ()->rt_info, + dependency_info->rt_info, + dependency_info->number_of_calls, + TAO_TRY_ENV); + TAO_CHECK_ENV; + } + TAO_CATCHANY + { + ACE_ERROR ((LM_ERROR, "Subscription_Module::subscribe_type:" + " add_dependency failed.\n")); + return -1; + } + TAO_ENDTRY; + } + } + + return 0; +} + +int +ACE_ES_Subscription_Module::subscribe_source_type (ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventSourceID source, + RtecEventComm::EventType type) +{ + // Step through all Supplier Proxies looking for a match to + // <supplier>. Once we find one, find the correct set for the + // specified type. Add the <consumer> to that set. + Supplier_Iterator iter (all_suppliers_); + + int success = -1; + + for (ACE_Push_Supplier_Proxy **proxy = 0; + iter.next (proxy) != 0; + iter.advance ()) + { + ACE_ES_WGUARD mon ((*proxy)->subscription_info ().lock_); + + if ((**proxy) == source) + { + // Insert the consumer to the supplier's subscription set for + // the type. + RtecScheduler::Dependency_Info *dependency_info; + int insert_result = ACE_ES_Subscription_Info::insert_or_fail + ((*proxy)->subscription_info().type_subscribers_, + consumer, type, dependency_info); + + switch (insert_result) + { + case -1: + // Error. + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", + "Subscription Module::subscribe_source_type"), -1); + case 0: + default: + { + // Success. + // Add the supplier to the consumer's dependency list. + // @@ TODO handle exceptions. + TAO_TRY + { + ACE_Scheduler_Factory::server()->add_dependency + (consumer->dependency ()->rt_info, + dependency_info->rt_info, + dependency_info->number_of_calls, + TAO_TRY_ENV); + TAO_CHECK_ENV; + } + TAO_CATCHANY + { + ACE_ERROR_RETURN ((LM_ERROR, "Subscription_Module::subscribe_source_type:" + " add_dependency failed.\n"), + -1); + } + TAO_ENDTRY; + consumer->_duplicate (); + } + /* FALLTHROUGH */ + case 1: + success = 0; + + // Already there. + break; + } + + } + } + + if (success == -1) + // If we failed to find a source, insert this consumer in the + // global source subscriber list. + { + if (ACE_ES_Subscription_Info::insert_or_allocate (source_subscribers_, + consumer, + source) == 0) + { + consumer->_duplicate (); + return 0; + } + else + return -1; + } + else + return success; +} + +// <consumer> contains information for one type of subscription. +// Delegate to the appropriate method for subscription. +int +ACE_ES_Subscription_Module::subscribe (ACE_ES_Consumer_Rep *consumer) +{ + // We could have finer granularity by putting RGUARDs in some of the + // subscribe methods. + ACE_ES_WGUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", + "ACE_ES_Subscription_Module::subscribe"), -1); + + int result = 0; + RtecEventComm::Event &event = consumer->dependency ()->event_; + + if (event.source_ == 0) + // Not source-based subscription. + { + if (event.type_ == ACE_ES_EVENT_ANY) + result = this->subscribe_all (consumer); + else + result = this->subscribe_type (consumer, event.type_); + } + else + // Source-based subscription. + { + if (event.type_ == ACE_ES_EVENT_ANY) + result = this->subscribe_source (consumer, event.source_); + else + result = this->subscribe_source_type (consumer, + event.source_, + event.type_); + } + + return result; +} + +int +ACE_ES_Subscription_Module::unsubscribe (ACE_ES_Consumer_Rep *consumer) +{ + // We could have finer granularity by putting RGUARDs in some of the + // unsubscribe methods. + ACE_ES_WGUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", + "ACE_ES_Subscription_Module::unsubscribe"), -1); + + RtecEventComm::Event &event = consumer->dependency ()->event_; + + if (event.type_ != ACE_ES_EVENT_ANY) + { + // Remove the consumer from the global type-based subscription list. + if (ACE_ES_Subscription_Info::remove (type_subscribers_, + consumer, + event.type_) == 0) + consumer->_release (); + } + else + // Remove the consumer from the global source-based subscription list. + if (ACE_ES_Subscription_Info::remove (source_subscribers_, + consumer, + event.source_) == 0) + consumer->_release (); + + return 0; + + /* + + This old code manually removed the consumer from the subscription + lists. Now we do lazy removal. + + int result = 0; + + if (CORBA::is_nil (event.source_)) + { + if (event.type_ == ACE_ES_EVENT_ANY) + result = this->unsubscribe_all (consumer); + else + result = this->unsubscribe_type (consumer, event.type_); + } + else + { + if (event.type_ == ACE_ES_EVENT_ANY) + result = this->unsubscribe_source (consumer, event.source_); + else + result = this->unsubscribe_source_type (consumer, event.source_, event.type_); + } + return result; + */ +} + +int +ACE_ES_Subscription_Module::unsubscribe_all (ACE_ES_Consumer_Rep *) +{ + return 0; +} + +int +ACE_ES_Subscription_Module::unsubscribe_type (ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventType type) +{ + // Step through all Supplier Proxies trying to remove the + // consumer-type pair. ACE_ES_Subscription_Info::remove will fail + // if the supplier does not generate <type>, but that's ok. + Supplier_Iterator iter (all_suppliers_); + + for (ACE_Push_Supplier_Proxy **proxy = 0; + iter.next (proxy) != 0; + iter.advance ()) + { + ACE_ES_WGUARD mon ((*proxy)->subscription_info ().lock_); + + // This remove will be harmless if the supplier does not + // generate <type>. + ACE_ES_Subscription_Info::remove ((*proxy)->subscription_info ().type_subscribers_, + consumer, type); + } + + return 0; +} + +int +ACE_ES_Subscription_Module::unsubscribe_source (ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventSourceID source) +{ + Supplier_Iterator iter (all_suppliers_); + + for (ACE_Push_Supplier_Proxy **proxy = 0; + iter.next (proxy) != 0; + iter.advance ()) + { + ACE_ES_WGUARD mon ((*proxy)->subscription_info ().lock_); + + if ((**proxy) == source) + { + ACE_ES_Subscription_Info::Subscriber_Set &set = + (*proxy)->subscription_info ().source_subscribers_; + if (set.remove (consumer) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", + "Subscription Module::unsubscribe_source"), -1); + } + } + + return 0; +} + +int +ACE_ES_Subscription_Module::unsubscribe_source_type (ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventSourceID source, + RtecEventComm::EventType type) + +{ + Supplier_Iterator iter (all_suppliers_); + + // Step through all supplier proxies looking for a match to the + // consumer's event.source_. This is the same as unsubscribe_type, + // only we can check the source first. + for (ACE_Push_Supplier_Proxy **proxy = 0; + iter.next (proxy) != 0; + iter.advance ()) + // If the proxy matches the source id we're looking for, try to + // remove <consumer> from the proxy's <event.type_> set. + if ((**proxy) == source) + { + ACE_ES_WGUARD mon ((*proxy)->subscription_info ().lock_); + + // Continue in spite of errors. + ACE_ES_Subscription_Info::remove ((*proxy)->subscription_info ().type_subscribers_, + consumer, type); + } + + return 0; +} + +void +ACE_ES_Subscription_Module::push (ACE_Push_Supplier_Proxy *source, + ACE_ES_Event_Container *event, + CORBA::Environment &) +{ + ACE_TIMEPROBE (" deliver to Subscription Module"); + // These are all inline function calls. + if (this->push_source (source, event) == -1) + return; + + ACE_TIMEPROBE (" begin push_source_type"); + + if (this->push_source_type (source, event) == -1) + return; + + ACE_TIMEPROBE (" end push_source_type"); +} + +void +ACE_ES_Subscription_Module::shutdown (void) +{ + ACE_ES_WGUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + ACE_ERROR ((LM_ERROR, "%p.\n", + "ACE_ES_Subscription_Module::unsubscribe")); + + // Remove all type_subscribers_ and source_subscribers_. + + ACE_ES_Subscription_Info::Subscriber_Map_Iterator type_iter (type_subscribers_); + for (ACE_ES_Subscription_Info::Subscriber_Map_Entry *entry; + type_iter.next (entry) != 0; + type_iter.advance ()) + { + ACE_ES_Subscription_Info::Subscriber_Set_Iterator ts_iter (entry->int_id_->consumers_); + + for (ACE_ES_Consumer_Rep **consumer = 0; + ts_iter.next (consumer) != 0; + ts_iter.advance ()) + (*consumer)->_release (); + + delete entry->int_id_; + } + + ACE_ES_Subscription_Info::SourceID_Map_Iterator source_iter (source_subscribers_); + + for (ACE_ES_Subscription_Info::SourceID_Map_Entry *entry2; + source_iter.next (entry2) != 0; + source_iter.advance ()) + { + ACE_ES_Subscription_Info::Subscriber_Set_Iterator ss_iter (*entry2->int_id_); + + for (ACE_ES_Consumer_Rep **consumer = 0; + ss_iter.next (consumer) != 0; + ss_iter.advance ()) + (*consumer)->_release (); + + delete entry2->int_id_; + } + + // We don't need to do anything to all_suppliers_ since the supplier + // module should have disconnected all suppliers. To be more + // independent from the supplier module, this method should iterate + // through all suppliers and call this->disconnecting. + up_->shutdown (); +} + +// ************************************************************ + +ACE_ES_Supplier_Module::ACE_ES_Supplier_Module (ACE_EventChannel *channel) : + all_suppliers_ (), + lock_ (), + up_ (0), + channel_ (channel) +{ +} + +void +ACE_ES_Supplier_Module::open (ACE_ES_Subscription_Module *up) +{ + // There is the theory of the Mobius, a twist, in the fabric of + // space, where time becomes a loop, where time becomes a loop. + up_ = up; +} + +void +ACE_ES_Supplier_Module::connected (ACE_Push_Supplier_Proxy *supplier, + CORBA::Environment &_env) +{ + channel_->report_connect (ACE_EventChannel::SUPPLIER); + up_->connected (supplier, _env); +} + +void +ACE_ES_Supplier_Module::disconnecting (ACE_Push_Supplier_Proxy *supplier, + CORBA::Environment &_env) +{ + ACE_ES_GUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + TAO_THROW (RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR); + + if (all_suppliers_.remove (supplier) == -1) + TAO_THROW (RtecEventChannelAdmin::EventChannel::SUBSCRIPTION_ERROR); + + up_->disconnecting (supplier, _env); + + if (all_suppliers_.size () <= 0) + { + ACE_DEBUG ((LM_DEBUG, "(%t) No more suppliers connected.\n")); + channel_->report_disconnect (ACE_EventChannel::SUPPLIER); + } + + // IMHO this release is broken: supplier is a parameter, we never + // actually increased its reference count, so we shouldn't decrease + // it. + // CORBA::release (supplier); +} + +void +ACE_ES_Supplier_Module::shutdown (void) +{ + Suppliers copy; + + { + ACE_ES_GUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + return; + + copy = all_suppliers_; + } + + if (copy.size () > 0) + { + Supplier_Iterator iter (copy); + + CORBA::Environment env; + + for (ACE_Push_Supplier_Proxy **proxy = 0; + iter.next (proxy) != 0; + iter.advance ()) + { + (*proxy)->shutdown (); + this->disconnecting (*proxy, env); + } + } + + up_->shutdown (); +} + +RtecEventChannelAdmin::ProxyPushConsumer_ptr +ACE_ES_Supplier_Module::obtain_push_consumer (CORBA::Environment &_env) +{ + ACE_Push_Supplier_Proxy *new_supplier = new ACE_Push_Supplier_Proxy (this); + + if (new_supplier == 0) + TAO_THROW_RETURN (CORBA::NO_MEMORY (CORBA::COMPLETED_NO), 0); + + { + ACE_ES_GUARD ace_mon (lock_); + if (ace_mon.locked () == 0) + { + delete new_supplier; + TAO_THROW_RETURN (RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR, 0); + } + + if (all_suppliers_.insert (new_supplier) == -1) + ACE_ERROR ((LM_ERROR, "ACE_ES_Supplier_Module insert failed.\n")); + } + + return new_supplier->get_ref (); +} + +void +ACE_ES_Supplier_Module::push (ACE_Push_Supplier_Proxy *proxy, + const RtecEventComm::EventSet &event, + CORBA::Environment &_env) +{ + TAO_TRY + { + for (CORBA::ULong i = 0; i < event.length(); ++i) + { + ACE_ES_Event_Container *temp = + new ACE_ES_Event_Container (event[i]); + //RtecEventComm::Event *temp = new RtecEventComm::Event (event); + + if (temp == 0) + TAO_THROW (CORBA::NO_MEMORY (CORBA::COMPLETED_NO)); + + // This will guarantee that release gets called when we exit + // the scope. + ACE_ES_Event_Container_var event_copy (temp); + temp->_release (); + ACE_TIMEPROBE (" deliver to Supplier Module (thru Supplier Proxy)"); + up_->push (proxy, event_copy, TAO_TRY_ENV); + TAO_CHECK_ENV; + } + } + TAO_CATCH (RtecEventChannelAdmin::TypeError, t) + { + ACE_ERROR ((LM_ERROR, "%p Type Error.\n", + "ACE_ES_Supplier_Module::push")); + TAO_RETHROW; + } + TAO_CATCH (CORBA::NO_MEMORY, e) + { + ACE_ERROR ((LM_ERROR, "%p No Memory.\n", + "ACE_ES_Supplier_Module::push")); + TAO_RETHROW; + } + TAO_CATCH (CORBA::SystemException, e) + { + ACE_ERROR ((LM_ERROR, "%p CORBA System Exception.\n", + "ACE_ES_Supplier_Module::push")); + TAO_RETHROW; + } + TAO_CATCHANY + { + ACE_ERROR ((LM_ERROR, "ACE_ES_Supplier_Module::push: " + "Unknown exception.\n")); + TAO_RETHROW; + } + TAO_ENDTRY; +} + +// ************************************************************ + +ACE_ES_Priority_Timer::ACE_ES_Priority_Timer (void) +{ +} + +int +ACE_ES_Priority_Timer::connected (RtecScheduler::handle_t rt_info) +{ + RtecScheduler::OS_Priority thread_priority; + RtecScheduler::Sub_Priority subpriority; + RtecScheduler::Preemption_Priority preemption_priority; + + TAO_TRY + { + ACE_TIMEPROBE (" connected - priority requested"); + ACE_Scheduler_Factory::server ()->priority + (rt_info, thread_priority, + subpriority, preemption_priority, TAO_TRY_ENV); + TAO_CHECK_ENV; + ACE_TIMEPROBE (" connected - priority obtained"); +#if 0 + ACE_ERROR_RETURN ((LM_ERROR, "%p RtecScheduler::Scheduler::priority failed.\n", + "ACE_ES_Priority_Timer::connected"), -1); +#endif /* 0 */ + } + TAO_CATCHANY + { + ACE_ERROR_RETURN ((LM_ERROR, + "%p RtecScheduler::Scheduler::priority failed.\n", + "ACE_ES_Priority_Timer::connected"), -1); + } + TAO_ENDTRY; + + // Just make sure the ORB allocates resources for this priority. + if (ACE_Task_Manager::instance()->GetReactorTask (preemption_priority) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", + "ACE_ES_Priority_Timer::connected"), -1); + + return 0; +} + +int +ACE_ES_Priority_Timer::handle_timeout (const ACE_Time_Value &, + const void *vp) +{ + ACE_ES_Timer_ACT *act = (ACE_ES_Timer_ACT *) vp; + + if (act == 0) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_ES_Priority_Timer::handle_timeout: " + "received act == 0!!!.\n"), 0); + + ACE_TIMEPROBE ("ES_Priority_Queue - start execute"); + + act->execute (); + + ACE_TIMEPROBE ("ES_Priority_Queue - end execute"); + + return 0; +} + +// ************************************************************ + +const char * +ACE_ES_Consumer_Name (const RtecEventChannelAdmin::ConsumerQOS &qos) +{ + // The first dependency should designate a correlation group. + + TAO_TRY + { + ACE_TIMEPROBE (" Consumer_Name - priority requested"); + RtecScheduler::RT_Info* rt_info = ACE_Scheduler_Factory::server ()->get + (qos.dependencies[1].rt_info, TAO_TRY_ENV); + TAO_CHECK_ENV; + ACE_TIMEPROBE (" Consumer_Name - priority obtained"); + + return rt_info->entry_point; + } + TAO_CATCHANY + { + return "no-name"; + } + TAO_ENDTRY; + return "no-name"; +} + +// ************************************************************ + +void +dump_event (const RtecEventComm::Event &event) +{ + ACE_DEBUG ((LM_DEBUG, "source_ = %d " + "type_ = %d " + "time_ = %u.\n", + (void*)event.source_, + event.type_, + // The divide-by-1 is for ACE_U_LongLong support. + ORBSVCS_Time::to_hrtime (event.creation_time_) / 1)); +} + +// ************************************************************ + +#if defined(ACE_ES_LACKS_ORB) +void +dump_sequence (const ACE_CORBA_Sequence<ACE_ES_Event> &seq) +{ + for (CORBA::ULong index=0; index < seq.length (); index++) + ::dump_event (seq[index]); +} +#endif /* ACE_ES_LACKS_ORB */ + +// ************************************************************ + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + +template class ACE_Atomic_Op<ACE_ES_MUTEX, int>; +template class ACE_Map_Entry<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT>; +template class ACE_Map_Entry<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT>; +template class ACE_Map_Manager<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT, ACE_ES_Subscription_Info::SYNCH>; +template class ACE_Map_Manager<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT, ACE_ES_Subscription_Info::SYNCH>; +template class ACE_Map_Iterator_Base<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT, ACE_ES_Subscription_Info::SYNCH>; +template class ACE_Map_Iterator_Base<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT, ACE_ES_Subscription_Info::SYNCH>; +template class ACE_Map_Iterator<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT, ACE_ES_Subscription_Info::SYNCH>; +template class ACE_Map_Reverse_Iterator<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT, ACE_ES_Subscription_Info::SYNCH>; +template class ACE_Map_Iterator<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT, ACE_ES_Subscription_Info::SYNCH>; +template class ACE_Map_Reverse_Iterator<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT, ACE_ES_Subscription_Info::SYNCH>; +template class ACE_Node<ACE_ES_Consumer_Rep *>; +template class ACE_Node<ACE_Push_Consumer_Proxy *>; +template class ACE_Node<ACE_Push_Supplier_Proxy *>; +template class ACE_Unbounded_Set<ACE_ES_Consumer_Rep *>; +template class ACE_Unbounded_Set<ACE_Push_Consumer_Proxy *>; +template class ACE_Unbounded_Set<ACE_Push_Supplier_Proxy *>; +template class ACE_Unbounded_Set_Iterator<ACE_ES_Consumer_Rep *>; +template class ACE_Unbounded_Set_Iterator<ACE_Push_Consumer_Proxy *>; +template class ACE_Unbounded_Set_Iterator<ACE_Push_Supplier_Proxy *>; + +// For ACE_ES_Event_Container_Allocator. +template class ACE_Cached_Allocator<ACE_ES_Event_Container_Chunk, ACE_Null_Mutex>; +template class ACE_Cached_Allocator<ACE_ES_Dispatch_Request_Chunk, ACE_Null_Mutex>; +template class ACE_Cached_Mem_Pool_Node<ACE_ES_Event_Container_Chunk>; +template class ACE_Cached_Mem_Pool_Node<ACE_ES_Dispatch_Request_Chunk>; +template class ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<ACE_ES_Event_Container_Chunk>, ACE_Null_Mutex>; +template class ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<ACE_ES_Dispatch_Request_Chunk>, ACE_Null_Mutex>; +template class ACE_Free_List<ACE_Cached_Mem_Pool_Node<ACE_ES_Event_Container_Chunk> >; +template class ACE_Free_List<ACE_Cached_Mem_Pool_Node<ACE_ES_Dispatch_Request_Chunk> >; + +template class ACE_ES_Array_Iterator<ACE_ES_Consumer_Rep *>; +template class ACE_ES_Simple_Array<ACE_ES_Consumer_Rep *, 100>; + +template class ACE_CORBA_var<ACE_ES_Event_Container>; + +#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate ACE_Atomic_Op<ACE_ES_MUTEX, int> +#pragma instantiate ACE_Map_Entry<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT> +#pragma instantiate ACE_Map_Entry<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT> +#pragma instantiate ACE_Map_Manager<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT, ACE_ES_Subscription_Info::SYNCH> +#pragma instantiate ACE_Map_Manager<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT, ACE_ES_Subscription_Info::SYNCH> +#pragma instantiate ACE_Map_Iterator_Base<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT, ACE_ES_Subscription_Info::SYNCH> +#pragma instantiate ACE_Map_Iterator_Base<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT, ACE_ES_Subscription_Info::SYNCH> +#pragma instantiate ACE_Map_Iterator<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT, ACE_ES_Subscription_Info::SYNCH> +#pragma instantiate ACE_Map_Reverse_Iterator<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT, ACE_ES_Subscription_Info::SYNCH> +#pragma instantiate ACE_Map_Iterator<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT, ACE_ES_Subscription_Info::SYNCH> +#pragma instantiate ACE_Map_Reverse_Iterator<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT, ACE_ES_Subscription_Info::SYNCH> +#pragma instantiate ACE_Node<ACE_ES_Consumer_Rep *> +#pragma instantiate ACE_Node<ACE_Push_Consumer_Proxy *> +#pragma instantiate ACE_Node<ACE_Push_Supplier_Proxy *> +#pragma instantiate ACE_Unbounded_Set<ACE_ES_Consumer_Rep *> +#pragma instantiate ACE_Unbounded_Set<ACE_Push_Consumer_Proxy *> +#pragma instantiate ACE_Unbounded_Set<ACE_Push_Supplier_Proxy *> +#pragma instantiate ACE_Unbounded_Set_Iterator<ACE_ES_Consumer_Rep *> +#pragma instantiate ACE_Unbounded_Set_Iterator<ACE_Push_Consumer_Proxy *> +#pragma instantiate ACE_Unbounded_Set_Iterator<ACE_Push_Supplier_Proxy *> +#pragma instantiate ACE_Cached_Allocator<ACE_ES_Event_Container_Chunk, ACE_Null_Mutex> +#pragma instantiate ACE_Cached_Allocator<ACE_ES_Dispatch_Request_Chunk, ACE_Null_Mutex> +#pragma instantiate ACE_Cached_Mem_Pool_Node<ACE_ES_Event_Container_Chunk> +#pragma instantiate ACE_Cached_Mem_Pool_Node<ACE_ES_Dispatch_Request_Chunk> +#pragma instantiate ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<ACE_ES_Event_Container_Chunk>, ACE_Null_Mutex> +#pragma instantiate ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<ACE_ES_Dispatch_Request_Chunk>, ACE_Null_Mutex> +#pragma instantiate ACE_Free_List<ACE_Cached_Mem_Pool_Node<ACE_ES_Event_Container_Chunk> > +#pragma instantiate ACE_Free_List<ACE_Cached_Mem_Pool_Node<ACE_ES_Dispatch_Request_Chunk> > +#pragma instantiate ACE_ES_Array_Iterator<ACE_ES_Consumer_Rep *> +#pragma instantiate ACE_ES_Simple_Array<ACE_ES_Consumer_Rep *, 100> +#pragma instantiate ACE_CORBA_var<ACE_ES_Event_Container> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Event_Channel.h b/TAO/orbsvcs/orbsvcs/Event/Event_Channel.h new file mode 100644 index 00000000000..62656c6f124 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Event_Channel.h @@ -0,0 +1,1300 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ace ORB +// +// = FILENAME +// Event_Channel +// +// = AUTHOR +// Tim Harrison (harrison@cs.wustl.edu) +// +// = DESCRIPTION +// TAO implementation of the Real Time Event Services. For more +// detailed information, see +// http://www.cs.wustl.edu/~schmidt/oopsla.ps.gz +// +// = NAMING CONVENTIONS +// Some of the naming might be confusing. For instance +// ACE_Push_Consumer_Proxy "is-a" ProxyPushSupplier. To the +// channel, ACE_Push_Consumer_Proxy is a proxy to push consumers. +// To a push consumer, ACE_Push_Consumer_Proxy is a proxy to push +// suppliers. I chose to name classes relative to the Event +// Channel. +// +// ============================================================================ + +#ifndef ACE_EVENT_CHANNEL_H +#define ACE_EVENT_CHANNEL_H + +#include "ace/Containers.h" +#include "ace/Map_Manager.h" + +#include "tao/Timeprobe.h" +#include "Local_ESTypes.h" +#include "CORBA_Utils_T.h" +#include "Task_Manager.h" +#include "ReactorTask.h" + +//ACE_INLINE void operator += (ACE_CORBA_Sequence<RtecEventComm::Event_var> &dest, +// RtecEventComm::Event *item); + +ACE_INLINE int operator == (const RtecEventComm::Event &event1, + const RtecEventComm::Event &event2); +// This operation could be part of the classes, but in order to stay +// CORBA compliant, we're adding them as global operators. + +// ************************************************************ + +class ACE_ES_Event_Container : public RtecEventComm_Event +// = TITLE +// Event Container +// +// = DESCRIPTION +// Basically an ACE_ES_Event with reference counting and +// thread-specific memory allocation. +{ +public: + ACE_ES_Event_Container (void); + // Default construction. + + ~ACE_ES_Event_Container (void); + // Destruction. + + ACE_ES_Event_Container (const ACE_ES_Event_Container &); + // Copy construction. + + ACE_ES_Event_Container (const RtecEventComm::Event &); + // Construction with an event. + + ACE_ES_Event_Container *_duplicate (void); + // Increments ref_count_ and returns this. + + void _release (void); + // Decrements ref_count_ and deletes if 0. + + int operator== (const ACE_ES_Event_Container &event); + // Returns 1 if the two are "equal," 0 otherwise. Determines + // equality using source_ and type_ only. A 0 source_ is a wildcard + // (always equal). A type_ of ACE_ES_EVENT_ANY is also a wildcard. + + void *operator new (size_t nbytes); + // Allocates memory from a thread-specific memory pool. + + void operator delete (void *); + // Returns memory to a thread-specific memory pool. + + void dump (void); + +private: + int ref_count_; +}; + +typedef ACE_CORBA_var<ACE_ES_Event_Container> ACE_ES_Event_Container_var; + +ACE_INLINE void operator += (ACE_CORBA_Sequence<ACE_ES_Event_Container_var> &dest, + ACE_ES_Event_Container *item); + +#if defined(ACE_ES_LACKS_ORB) +// Utility for debugging sequences. +ACE_Svc_Export void dump_sequence (const ACE_CORBA_Sequence<RtecEventComm::Event> &seq); +#endif /* ACE_ES_LACKS_ORB */ + +// Utility for debugging events. +void dump_event (const RtecEventComm::Event &event); + +// ************************************************************ + +class ACE_RTU_Manager +// = TITLE +// ACE RTU Manager +// +// = DESCRIPTION +{ +public: + ACE_RTU_Manager (int active); + // If <active> == 0, everything returns 0. If <active> != 0, RTUs + // galore. + + int should_preempt (void); + // Returns 1 if the current task should preempt itself. Otherwise, + // returns 0. Resets should_preempt to zero. + + void should_preempt (int s); + // Called by the dispatching module when the current task should + // preempt itself. + + void not_done (int nd); + // If <nd> != 0, the current running task will be enqueued at the + // head of its dispatch tail. + + int not_done (void); + // Returns 1 if the current task needs to be dispatched again. + // Resets not_done_ to 0; + + // = Get/set the priority of the current running task. + RtecScheduler::OS_Priority priority (void); + void priority (RtecScheduler::OS_Priority priority); + +private: + int active_; + int should_preempt_; + int not_done_; + RtecScheduler::OS_Priority priority_; +}; + +// ************************************************************ + +// Chesire cat. +class ACE_ES_Priority_Timer; +// Forward declarations. +class ACE_ES_Consumer_Module; +class ACE_ES_Correlation_Module; +class ACE_ES_Subscription_Module; +class ACE_ES_Supplier_Module; +// This forward decl and typedef allow us to remove inheritence later +// on without changing any code. +class ACE_ES_Dispatching_Base; +typedef ACE_ES_Dispatching_Base ACE_ES_Dispatching_Module; + +// ec.. +class ACE_EventChannel : public RtecEventChannelAdmin_EventChannelBOAImpl +// = TITLE +// ACE Event Channel. +// +// = DESCRIPTION +// Implementation of COSS Event Channel. For more detailed +// information, see http://www.cs.wustl.edu/~mda/event.html. +{ +public: + enum { INITIAL_STATE = 0, + CONSUMER = 1, SUPPLIER = 2, + SHUTDOWN = CONSUMER | SUPPLIER }; + + ACE_EventChannel (u_long type = ACE_DEFAULT_EVENT_CHANNEL_TYPE); + // Construction of the given <type>. Check the **_CHANNEL + // enumerations defined below. + + virtual ~ACE_EventChannel (void); + // Calls destroy. + + // = Accessor methods to Event Channel objects. The Event Channel + // acts as a sort of service repository of object references. All + // objects in the Event Service come to this interface to obtain + // object references during initialization. + + virtual RtecEventChannelAdmin::ConsumerAdmin_ptr for_consumers (CORBA::Environment &); + // Consumer administration factory method. + + virtual RtecEventChannelAdmin::SupplierAdmin_ptr for_suppliers (CORBA::Environment &); + // Supplier administration factory method. + + virtual void destroy (CORBA::Environment &); + // Explicitly shut down the channel. + + RtecEventChannelAdmin::EventChannel_ptr get_ref (void); + // Allow transformations to RtecEventChannelAdmin::EventChannel. + + ACE_RTU_Manager *rtu_manager (void); + // Returns a reference to the RTU manager. + + ACE_ES_Priority_Timer *timer (void); + // Timer accessor. + + // = These should be private. + ACE_ES_Consumer_Module *consumer_module_; + ACE_ES_Dispatching_Module *dispatching_module_; + ACE_ES_Correlation_Module *correlation_module_; + ACE_ES_Subscription_Module *subscription_module_; + ACE_ES_Supplier_Module *supplier_module_; + + ACE_ES_Priority_Timer *timer_; + + void report_connect (u_long); + // Consumer or supplier connected. + + void report_disconnect (u_long); + // Consumer or supplier disconnected. + + void shutdown (void); + // Do not call this. The last module has shut down. + +private: + ACE_RTU_Manager *rtu_manager_; + // The RTU manager dude! + + u_long type_; + // Can be any **_CHANNEL. (well, except NO_CHANNEL). + + u_long state_; + // Can be INITIAL_STATE, NO_CONSUMERS, NO_SUPPLIERS, or SHUTDOWN. + + ACE_ES_MUTEX lock_; + // Used to lock shared state. + + int destroyed_; + // Ensures this->destory is executed only once. +}; + +// ************************************************************ + +class ACE_ES_Dependency_Iterator +// = TITLE +// ConsumerQOS Iterator +// +// = DESCRIPTION +// This is used by the Event Channel to parse ConsumerDependency objects. +{ +public: + ACE_ES_Dependency_Iterator (RtecEventChannelAdmin::DependencySet &rep); + // Construct and iterator for <rep>. + + int advance_dependency (void); + // Returns 0 if the advance succeeded. Returns -1 if there are no + // more dependencies in the group. + + int parse (void); + // Cache values for n_** methods. + + int n_conjunctions (void); + // Returns the number of conjunction groups in the dependency set. + + int n_disjunctions (void); + // Returns the number of disjunction groups in the dependency set. + + int n_timeouts (void); + // Returns the number of timeouts registered. + + int n_events (void); + // Returns the number of events registered. + + RtecEventChannelAdmin::Dependency &operator *(void); + // Accessor to the current ConsumerDependency pointed to by the + // iterator. + + RtecScheduler::handle_t first_rt_info (void); + // Returns the first RT_Info in the dependencies. + +protected: + RtecScheduler::handle_t rt_info_; + // The first rt_info in the dependencies. + + RtecEventChannelAdmin::DependencySet &rep_; + // Reference to the dependency array. + + int index_; + // Index into rep_. + + RtecEventComm::EventType group_type_; + // The type of the current correlation group. + + int n_conjunctions_; + // Number of conjunction groups. + + int n_disjunctions_; + // Number of disjunction groups. + + int n_timeouts_; + // Number of timeouts registered. + + int n_events_; + // Number of events registered. +}; + +// ************************************************************ + +class ACE_ES_Timer_ACT +// = TITLE +// Timer Asynchronous Completion Token +// +// = DESCRIPTION +// Implements Command pattern with timers. +{ +public: + virtual void execute (void) = 0; +}; + +// ************************************************************ +// Forward decl. +class ACE_ES_Consumer_Rep_Timeout; + +class ACE_ES_Disjunction_Group +// = TITLE +// Disjunction Group +// +// = DESCRIPTION +// Represents a disjunction group, such as (A|B|C). +{ +public: + ACE_ES_Disjunction_Group (void); + // Default construction. + + void set_correlation_module (ACE_ES_Correlation_Module *cm); + // <cm> is needed for rescheduling deadlines. + + void reschedule_deadline (void); + // If deadline_timer_rep_ is set, it is cancelled and rescheduled. + + int set_deadline_timeout (ACE_ES_Consumer_Rep_Timeout *cr); + // Set the group's reference to the deadline timer. Returns 0 on + // success, -1 on failure. + + typedef ACE_CORBA_Sequence<ACE_ES_Event_Container_var> Event_Set; + + virtual void add_events (Event_Set *outbox, + Event_Set *pending_events, + u_long &pending_flags); + // Does nothing. This is the only virtual method in this little + // heirarchy with the conjunction group. + + void set_act (RtecEventComm::Event &act); + // Set the ACT for this group. + +protected: + ACE_ES_Event_Container_var act_; + // To be sent with this group. + +private: + ACE_ES_Consumer_Rep_Timeout *deadline_timer_rep_; + // The disjunction group keeps a reference to the deadline timer. + + ACE_ES_Correlation_Module *correlation_module_; + // Used for cancelling and scheduling deadline_timer_rep_. +}; + +// ************************************************************ + +class ACE_ES_Conjunction_Group : public ACE_ES_Disjunction_Group +// = TITLE +// Conjunction Group +// +// = DESCRIPTION +// Represents a conjunction group, such as (A+B+C). +{ +public: + ACE_ES_Conjunction_Group (void); + // Default construction. + + int add_type (int type_id); + // Set the <type_id>th bit in the forward_value_. + + int should_forward (u_long pending_flags); + // Returns 1 if this conjunction group's dependencies have been + // satisfied. Returns 0 otherwise. + + typedef ACE_CORBA_Sequence<ACE_ES_Event_Container_var> Event_Set; + + virtual void add_events (Event_Set *outbox, + Event_Set *pending_events, + u_long &pending_flags); + // For each bit set in forward_value_, the corresponding events in + // <pending_events> is added to <outbox>. Each bit set in + // <forward_value_> is cleared in <pending_flags>. If <oubox> == 0, + // then add_events just clears the pending events and flags. + +private: + u_long forward_value_; +}; + +// ************************************************************ + +// Forward decl. +class ACE_ES_Consumer_Correlation; + +class ACE_ES_Consumer_Rep : public ACE_ES_Timer_ACT +// = TITLE +// Consumer Representation. +// +// = DESCRIPTION +// These are stored in the subscription module. They store +// information that allows optimized correlations. It represents +// the consumer that will handle *one* type of event. This +// probably shouldn't inherit from ACE_ES_Timer_ACT since it's used +// only by ACE_ES_Consumer_Rep_Timeout. However, this allows me to +// minimize dynamic allocation. +{ +public: + ACE_ES_Consumer_Rep (void); + // Default construction. + + void init (ACE_ES_Consumer_Correlation *correlation, + RtecEventChannelAdmin::Dependency &dep); + // <dep> describes the event subscribed to and the method handling + // the event. <correlation> is the parent correlation object. + + virtual ~ACE_ES_Consumer_Rep (void); + // Virtual destruction. + + RtecEventChannelAdmin::Dependency *dependency (void); + // The event subscribed to and the method that will handle this + // event. + + int type_id (void); + // Get the correlation group index of this consumer rep's event + // type. + + void type_id (int); + // Set the correlation group index of this consumer rep's event + // type. + + enum Correlation_Type + { + NO_CORRELATION, + CORRELATE, + DEADLINE_TIMEOUT, + GLOBAL_DEADLINE + }; + + u_long correlation_type (void); + // If this returns 0, then the event associated with this consumer + // should be forwarded without running any correlations. + + void correlation_type (u_long ct); + // Set whether the event should be correlated. <ct> is a + // Correlation_Type. + + int add_disjunction_group (ACE_ES_Disjunction_Group &); + // Add a disjunction group. + + ACE_ES_Disjunction_Group *top_group (void); + // Returns the first disjunction group added via + // this->add_disjunction_group. + + void reschedule_deadlines (void); + // Calls reschedule_deadline on all disjunction groups added through + // this->add_disjunction_group. + + int receiving_events (void); + // Returns 1 if events should be sent to this consumer. Returns 0 + // if they should not (suspended or disconnected). + + void suspend (void); + // Stop forwarding events to the calling consumer. + + void resume (void); + // Resume forwarding events to the calling consumer. + + ACE_ES_Consumer_Correlation *correlation (void); + // Returns the Consumer_Correlation object for the target consumer. + + void disconnect (void); + // Schedules the consumer rep to be removed from all subscription + // lists. + + int disconnected (void); + // Returns 1 if the consumer rep should be removed from all + // subscription lists. + + void _duplicate (void); + // Increments ref_count_. + + void _release (void); + // Decrements ref_count_ and deletes this if 0. + +protected: + int disconnected_; + // Whether the rep should be removed from all subscription lists. + + virtual void execute (void); + // This is called when timeouts occur. This implementation prints + // out an error message (since it really shouldn't be implemented in + // this class). + + int suspended_; + // Whether events should be dropped or forwarded. + + u_long correlation_type_; + // Whether any correlating should be done for this event. + + RtecEventChannelAdmin::Dependency *dependency_; + // Event subscribed to. + + ACE_ES_Consumer_Correlation *correlation_; + // The target consumer of events. + + int type_id_; + // Correlation group index of event_->type_. + + ACE_ES_Disjunction_Group *disjunction_group_; + // This should be a set. We'll just have room for one now. + + ACE_Atomic_Op<ACE_ES_MUTEX, int> ref_count_; + // Lock for reference count. +}; + +class ACE_ES_Consumer_Rep_Timeout : public ACE_ES_Consumer_Rep +// = TITLE +// Consumer Representation. +// +// = DESCRIPTION +// These are stored in the subscription module. They store +// information that allows optimized correlations. It represents +// the consumer that will handle *one* type of event. +{ +public: + ACE_ES_Consumer_Rep_Timeout (void); + // Default construction. + + void init (ACE_ES_Consumer_Correlation *correlation, + RtecEventChannelAdmin::Dependency &dep); + // <dep> describes the event subscribed to and the method handling + // the event. <correlation> is the parent correlation object. + + // = Get/set timer returned from the reactor. + int timer_id (void); + void timer_id (int); + + // = Get/set preemption priority. + RtecScheduler::OS_Priority preemption_priority (void); + void preemption_priority (RtecScheduler::OS_Priority pp); + +protected: + virtual void execute (void); + // This is called when timeouts occur. Calls correlation_-> + + int timer_id_; + // For cancelling timers. + + RtecScheduler::OS_Priority preemption_priority_; + // Store the preemption priority so we can cancel the correct timer. + // The priority values may change during the life. + + ACE_ES_Event_Container_var timeout_event_; +}; + +// ************************************************************ + +class ACE_ES_Subscription_Info +// = TITLE +// Event Service Subscription Info +// +// = DESCRIPTION +// Contains information on all consumers subscribed to a supplier. +// Each Push_Supplier_Proxy has an instance of this class. This +// should really be defined in Channel_Modules.h, but I want to +// have an instance of it in each ACE_Push_Supplier_Proxy. This +// allows us to reduce the amount of dynamic memory allocation. +{ +public: + ~ACE_ES_Subscription_Info (void); + // Free up dynamic resources. + + typedef ACE_Unbounded_Set_Iterator<ACE_ES_Consumer_Rep *> Subscriber_Set_Iterator; + typedef ACE_Unbounded_Set<ACE_ES_Consumer_Rep *> Subscriber_Set; + + class Type_Subscribers + // = DESCRIPTION + // There is one of these for each event type generated by the + // supplier. It contains the subscribers and the + // dependency_info_ describing the method that generates this + // event type. + { + public: + Type_Subscribers (RtecScheduler::Dependency_Info *d) + : dependency_info_ (d) {} + // Construction requires a dependency info describing the method + // that generates events for the consumers_. We use a pointer so + // that a null can be passed in this->insert_or_allocate. + + // void operator= (const Subscriber_Set &); + // Copy. + + Subscriber_Set consumers_; + // All the consumers that have registered for this event. + + RtecScheduler::Dependency_Info *dependency_info_; + // Description of the method that generates this event. + }; + + typedef RtecEventComm::EventType EXT; + typedef Type_Subscribers *INT; + typedef ACE_Null_Mutex SYNCH; + typedef ACE_Map_Manager<EXT, INT, SYNCH> Subscriber_Map; + typedef ACE_Map_Iterator<EXT, INT, SYNCH> Subscriber_Map_Iterator; + typedef ACE_Map_Entry<EXT, INT> Subscriber_Map_Entry; + + Subscriber_Set source_subscribers_; + // Source-based subscribers. + + Subscriber_Map type_subscribers_; + // Type-based subscribers. + + // = These are just typedefs for source-based subscriptions. + typedef RtecEventComm::EventSourceID sEXT; + typedef Subscriber_Set *sINT; + typedef ACE_Map_Manager<sEXT, sINT, SYNCH> SourceID_Map; + typedef ACE_Map_Iterator<sEXT, sINT, SYNCH> SourceID_Map_Iterator; + typedef ACE_Map_Entry<sEXT, sINT> SourceID_Map_Entry; + + ACE_ES_RW_LOCK lock_; + // Serializes writes to source_subscribers_ and type_subscribers_. + + static int insert_or_allocate (SourceID_Map &source_subscribers, + ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventSourceID sid); + // <source_subscribers> contains a mapping of source id to consumer + // list. Insert <consumer> into the list of consumers subscribed to + // <sid>. Allocate a list for <sid> if necessary. + + static int insert_or_allocate (Subscriber_Map &type_subscribers, + ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventType type); + // Add <consumer> to the set of consumers bound to <type> in + // <type_subscribers>. If there is consumer set for <type>, one is + // allocated. Returns -1 on failure, 0 otherwise. + + static int insert_or_fail (Subscriber_Map &type_subscribers, + ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventType type, + RtecScheduler::Dependency_Info *&dependency); + // Add <consumer> to the set of consumers bound to <type> in + // <type_subscribers>. If there is consumer set for <type>, the + // operation fails. Returns -1 on failure, 0 otherwise. + + static int remove (Subscriber_Map &type_map, + ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventType type); + // Remove <consumer> from the consumer set in <type_map> set + // corresponding to <type>. + + static int remove (SourceID_Map &source_subscribers, + ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventSourceID sid); + // Remove <consumer> from the consumer set in the + // <source_subscribers> set corresponding to <sid>. + + static void append_subscribers (Subscriber_Set &dest, + Subscriber_Set &src); + // Insert all elements of <src> into <dest>. +}; + +// ************************************************************ + +// Forward declarations. +class ACE_ES_Dispatch_Request; +class ACE_Push_Consumer_Proxy; + +class ACE_ES_Consumer_Correlation : public RtecEventComm_PushSupplierBOAImpl +// = TITLE +// Event Service Consumer_Correlation +// +// = DESCRIPTION +// There is one Consumer Correlation object per call to +// connect_push_consumer. It handles all the consumer's +// correlation dependencies including timeouts. This is also a +// PushSupplier to support event forwarding. +{ +public: + ACE_ES_Consumer_Correlation (void); + // Default construction. + + virtual ~ACE_ES_Consumer_Correlation (void); + // Deletes lock_. + + int connected (ACE_Push_Consumer_Proxy *consumer, + ACE_ES_Correlation_Module *correlation_module); + // Initialization. <correlation_module> is stored for delegating + // channel operations. <consumer> is stored to access the consumers + // qos and filterin data. Returns 0 on success, -1 on failure. + + int disconnecting (void); + // Shutdown. + + ACE_ES_Dispatch_Request *push (ACE_ES_Consumer_Rep *consumer, + ACE_ES_Event_Container *event); + // Takes <event> and adds it to the correlation. Returns the + // dispatch request that should be forwarded. + + void suspend (void); + // Stop forwarding events to the calling consumer. + + void resume (void); + // Resume forwarding events to the calling consumer. + + ACE_ES_Correlation_Module *correlation_module_; + // Pointer back to the main correlation module. This is public so + // that ACE_ES_Consumer_Rep_Timeout::execute can access it. + + typedef ACE_CORBA_Sequence<ACE_ES_Event_Container_var> Event_Set; + +private: + virtual void disconnect_push_supplier (CORBA::Environment &); + // Called when the channel disconnects us. + + int allocate_correlation_resources (ACE_ES_Dependency_Iterator &iter); + // Dynamically allocates structures needed for correlations. 0 on + // success, -1 on failure. + + ACE_ES_Dispatch_Request * correlate (ACE_ES_Consumer_Rep *cr, + ACE_ES_Event_Container *event); + // Helper function for this->push. + + // = Registration helper functions. + int register_deadline_timeout (RtecEventChannelAdmin::Dependency &dependency, + RtecEventComm::EventType group_type, + int cgindex, + int dgindex, + int &trep_index); + int register_interval_timeout (RtecEventChannelAdmin::Dependency &dependency, + RtecEventComm::EventType group_type, + int cgindex, + int dgindex, + int &trep_index); + int register_event (RtecEventChannelAdmin::Dependency &dependency, + RtecEventComm::EventType group_type, + int cgindex, + int dgindex, + int &crep_index); + + ACE_ES_Consumer_Rep *get_consumer_rep (RtecEventChannelAdmin::Dependency &dependency, + int &crep_index); + int new_type_id (void); + + int type_id_index_; + + RtecEventChannelAdmin::ProxyPushConsumer_ptr channel_; + // For event forwarding. + + RtecEventChannelAdmin::SupplierQOS qos_; + // Supplier QOS specifications. + + // Events waiting to be forwarded. + Event_Set *pending_events_; + + // Used to synchronize pending_events_ and by the correlation module. + ACE_ES_MUTEX lock_; + // Used to lock shared state. + + ACE_Push_Consumer_Proxy *consumer_; + + u_long pending_flags_; + // A bit is set for each dependency satisfied. + + ACE_ES_Consumer_Rep **consumer_reps_; + // Array of consumer rep pointers. + int n_consumer_reps_; + ACE_ES_Consumer_Rep_Timeout *timer_reps_; + int n_timer_reps_; + + ACE_ES_Conjunction_Group *conjunction_groups_; + int n_conjunction_groups_; + ACE_ES_Disjunction_Group *disjunction_groups_; + int n_disjunction_groups_; + + int connected_; + // True when we're connected to the channel for forwarding. +}; + +// ************************************************************ + +class ACE_ES_ACT +// = TITLE +// Event Service ACT +// +// = DESCRIPTION +// +{ +public: + ACE_ES_ACT (void); + int has_act_; + RtecEventComm::Event act_; +}; + +// ************************************************************ + +// Forward declarations. +class ACE_ES_Dispatch_Request; + +class ACE_ES_Consumer_Module : public RtecEventChannelAdmin_ConsumerAdminBOAImpl +// = TITLE +// Event Service Consumer Module +// +// = DESCRIPTION +// ProxyPushSupplier factory. +{ +public: + ACE_ES_Consumer_Module (ACE_EventChannel *channel); + // Default construction. + + void open (ACE_ES_Dispatching_Module *down); + // Link to the next module. + + virtual RtecEventChannelAdmin::ProxyPushSupplier_ptr obtain_push_supplier (CORBA::Environment &); + // Factory method for push consumer proxies. + + void connected (ACE_Push_Consumer_Proxy *consumer, + CORBA::Environment &); + // Register the consumer with the Event Service. This handles all + // the details regarding Correlation_Module and Subscription_Module. + + void disconnecting (ACE_Push_Consumer_Proxy *consumer, + CORBA::Environment &); + // Unregister the consumer from the Event Service. + + void push (const ACE_ES_Dispatch_Request *request, + CORBA::Environment &); + + RtecEventChannelAdmin::ConsumerAdmin_ptr get_ref (void); + // Allow transformations to RtecEventChannelAdmin::ConsumerAdmin. + + void shutdown_request (ACE_ES_Dispatch_Request *request); + // This is called by Shutdown_Consumer command objects when a + // consumer proxy is ready to be deleted. + + void shutdown (void); + // Actively disconnect from all consumers. + +private: + typedef ACE_Unbounded_Set_Iterator<ACE_Push_Consumer_Proxy *> Consumer_Iterator; + typedef ACE_Unbounded_Set<ACE_Push_Consumer_Proxy *> Consumers; + + ACE_ES_MUTEX lock_; + // Protects access to all_consumers_. + + Consumers all_consumers_; + + ACE_EventChannel *channel_; + // Used to test for shutdown. + + ACE_ES_Dispatching_Module *down_; + // Next module down. +}; + +// ************************************************************ + +// Forward declaration. +class ACE_ES_Subscription_Module; + +class ACE_ES_Correlation_Module +// = TITLE +// Event Service Correlation Module +// +// = DESCRIPTION +// +{ +public: + ACE_ES_Correlation_Module (ACE_EventChannel *channel); + // Default construction. + + void open (ACE_ES_Dispatching_Module *up, + ACE_ES_Subscription_Module *down); + // Link to adjacent modules. + + void connected (ACE_Push_Consumer_Proxy *consumer, + CORBA::Environment &); + // Create the consumers filter object. + + void disconnecting (ACE_Push_Consumer_Proxy *consumer, + CORBA::Environment &); + // Release the consumers filter object. + + void push (ACE_ES_Consumer_Rep *consumer, + ACE_ES_Event_Container *event, + CORBA::Environment &); + // Take in an event and its subscriber. Apply consumer-specific + // filters to each event and forward any dispatch requests to the + // Dispatching Module. + + // = These are called by ACE_ES_Consumer_Reps. + + int subscribe (ACE_ES_Consumer_Rep *consumer); + // Forwards to the subscription module. + + //int unsubscribe (ACE_ES_Consumer_Rep *consumer); + // Forwards to the subscription module. + + int schedule_timeout (ACE_ES_Consumer_Rep_Timeout *consumer); + // Schedule consumer timeout. Return 0 on success, -1 on failure. + + int cancel_timeout (ACE_ES_Consumer_Rep_Timeout *consumer); + // Cancel consumer timeout. Return 0 on success, -1 on failure. + + int reschedule_timeout (ACE_ES_Consumer_Rep_Timeout *consumer); + // Reschedule consumer timeout. Return 0 on success, -1 on failure. + + ACE_EventChannel *channel_; + // The master channel. This is public so that Consumer_Correlation + // objects can access it. + + void shutdown (void); + // Does nothing. + +private: + ACE_ES_Dispatching_Module *up_; + // Next module up. + + ACE_ES_Subscription_Module *subscription_module_; + // Next module down. +}; + +// ************************************************************ + +// Forward declaration. +class ACE_ES_Supplier_Module; +class ACE_Push_Supplier_Proxy; + +class ACE_ES_Subscription_Module +// = TITLE +// Event Service Subscription Module +// +// = DESCRIPTION +// +// = SYNCHRONIZATION +// This is currently implemented with very coarse-grain +// synchronization. Basically, there is a single readers/writer +// lock. All operations acquire the writer lock to change any +// subscription record. All operations acquire a reader lock to +// read any subscription record. This is fine for normal +// operations (which are *all* read operations). However, the +// initialization and shutdown periods might benefit from the +// potential increase in concurrency if we used finer grain locks +// (e.g., lock-per-source). +{ +public: + ACE_ES_Subscription_Module (ACE_EventChannel *channel); + // Default construction. + + void open (ACE_ES_Correlation_Module *up, + ACE_ES_Supplier_Module *down); + // Link to the adjacent modules. + + ~ACE_ES_Subscription_Module (void); + // Deletes the lock_. + + int subscribe (ACE_ES_Consumer_Rep *consumer); + // Register a new consumer. Calls into <consumer> to figure out the + // subscription options. Returns 0 on success, -1 on failure. + + int unsubscribe (ACE_ES_Consumer_Rep *consumer); + // Removes the -consumer- from any subscription lists. + + void connected (ACE_Push_Supplier_Proxy *supplier, + CORBA::Environment &); + void disconnecting (ACE_Push_Supplier_Proxy *supplier, + CORBA::Environment &); + + void push (ACE_Push_Supplier_Proxy *source, + ACE_ES_Event_Container *event, + CORBA::Environment &); + // Takes in a set of events and pushes subscriber sets to the + // Correlation Module. + + // void push (ACE_Push_Supplier_Proxy *source, + // const RtecEventComm::Event event); + // This doesn't need one of these since it will never be called. + + void shutdown (void); + // Unsubscribes all consumers from the suppliers. + +private: + void reregister_consumers (RtecEventComm::EventSourceID source_id); + // Reregister any consumers that registered for <source_id> before + // it actually connected to the channel. + + ACE_EventChannel *channel_; + // The channel of all channels. + + /* + typedef ACE_ES_Subscription_Info::Subscriber_Set INT; + typedef ACE_Null_Mutex SYNCH; + typedef ACE_Map_Manager<EXT, INT, SYNCH> Source_Collection; + typedef ACE_Map_Iterator<EXT, INT, SYNCH> Source_Collection_Iterator; + typedef ACE_Map_Entry<EXT, INT> Source_Collection_Entry; + Source_Collection source_subscription_info_; + // Source-only subscribers. + */ + + // = Subscribe helper methods. Returns 0 on success, -1 on failure. + + int subscribe_all (ACE_ES_Consumer_Rep *consumer); + + int subscribe_type (ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventType type); + + int subscribe_source (ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventSourceID source); + + int subscribe_source_type (ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventSourceID source, + RtecEventComm::EventType type); + + int unsubscribe_all (ACE_ES_Consumer_Rep *consumer); + + int unsubscribe_type (ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventType type); + + int unsubscribe_source (ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventSourceID source); + + int unsubscribe_source_type (ACE_ES_Consumer_Rep *consumer, + RtecEventComm::EventSourceID source, + RtecEventComm::EventType type); + + // = Push helper methods. + + int push_source (ACE_Push_Supplier_Proxy *source, + ACE_ES_Event_Container *event); + // Push <event> to all consumers subscribed to all events from + // <source>. Returns 0 on success, -1 on failure. + + int push_source_type (ACE_Push_Supplier_Proxy *source, + ACE_ES_Event_Container *event); + // Push <event> to all consumers subscribed to <event>.type_ from + // <source>. Returns 0 on success, -1 on failure. + + void push_all (ACE_ES_Event_Container *event, + CORBA::Environment &); + // Push <event> to all_suppliers_. + + ACE_ES_Correlation_Module *up_; + // Next module up stream. + + ACE_ES_Supplier_Module *down_; + // Next module down stream. + + typedef ACE_Unbounded_Set_Iterator<ACE_Push_Supplier_Proxy *> Supplier_Iterator; + typedef ACE_Unbounded_Set<ACE_Push_Supplier_Proxy *> Suppliers; + + Suppliers all_suppliers_; + // All suppliers. + + ACE_ES_Subscription_Info::Subscriber_Map type_subscribers_; + // Type-based subscribers. + + ACE_ES_Subscription_Info::SourceID_Map source_subscribers_; + // Source-based subscribers. + + ACE_ES_RW_LOCK lock_; + // Protects access to all_suppliers_ and type_suppliers_; +}; + +// ************************************************************ + +class ACE_ES_Supplier_Module : public RtecEventChannelAdmin_SupplierAdminBOAImpl +// = TITLE +// Event Service Supplier Proxy Module +// +// = DESCRIPTION +// ProxyPushConsumer factory. +{ +public: + ACE_ES_Supplier_Module (ACE_EventChannel *channel); + // Default construction. + + void open (ACE_ES_Subscription_Module *up); + // Associate the module to a channel. + + virtual RtecEventChannelAdmin::ProxyPushConsumer_ptr obtain_push_consumer (CORBA::Environment &); + // Factory method for push supplier proxies. + + void push (ACE_Push_Supplier_Proxy *proxy, + const RtecEventComm::EventSet &event, + CORBA::Environment &); + // The supplier module acts on behalf of the supplier proxy to + // forward events through the channel. + + void connected (ACE_Push_Supplier_Proxy *supplier, + CORBA::Environment &); + // Register the consumer with the Event Service. This handles all + // the details regarding Correlation_Module and Subscription_Module. + + void disconnecting (ACE_Push_Supplier_Proxy *supplier, + CORBA::Environment &); + // Unregister the consumer from the Event Service. + + RtecEventChannelAdmin::SupplierAdmin_ptr get_ref (void); + // Allow transformations to RtecEventComm::PushConsumer. + + void shutdown (void); + // Actively disconnect from all suppliers. + +private: + typedef ACE_Unbounded_Set_Iterator<ACE_Push_Supplier_Proxy *> Supplier_Iterator; + typedef ACE_Unbounded_Set<ACE_Push_Supplier_Proxy *> Suppliers; + + Suppliers all_suppliers_; + // All suppliers. + + ACE_ES_MUTEX lock_; + // Protects access to all_suppliers_ and type_suppliers_; + + ACE_ES_Subscription_Module *up_; + + ACE_EventChannel *channel_; + // Used to test for shutdown. +}; + +// ************************************************************ + +// Forward declarations. +class ACE_EventChannel; + +// = Event Channel interfaces. + +class ACE_Push_Supplier_Proxy : public RtecEventChannelAdmin_ProxyPushConsumerBOAImpl +// = TITLE +// Push Supplier Proxy. +// +// = DESCRIPTION +// To the channel, this is a proxy to suppliers. To suppliers, it +// exports a PushConsumer interface. It is a +// RtecEventChannelAdmin::ProxyPushConsumer. Suppliers use this +// interface to connect to the channel, push events to consumers, +// and to disconnect from the channel. +{ +public: + ACE_Push_Supplier_Proxy (ACE_ES_Supplier_Module *supplier_module); + // Must be created with an owning supplier admin. + + // = Operations public to suppliers. + + virtual void connect_push_supplier (RtecEventComm::PushSupplier_ptr push_supplier, + const RtecEventChannelAdmin::SupplierQOS& qos, + CORBA::Environment &); + // Suppliers connect via this interface. <push_supplier> is a + // reference to the supplier. <qos> represents the publish types of + // the supplier. + + virtual void push (const RtecEventComm::EventSet &event, + CORBA::Environment &); + // Data arriving from a PushSupplier that must be sent to + // consumers. This is the entry point of all events. + + virtual void disconnect_push_consumer (CORBA::Environment &); + // Disconnect the supplier from the channel. + + // = Operations for the Event Channel. + + RtecEventChannelAdmin::ProxyPushConsumer_ptr get_ref (void); + // Allow transformations to RtecEventChannelAdmin::ProxyPushConsumer. + + int connected (void); + // Returns 1 if the proxy has been connected to a "remote" client. + + void shutdown (void); + // Actively disconnect from the supplier. + + // This is a hook so that the Subscription Module can associate + // state with supplier proxies. + ACE_ES_Subscription_Info &subscription_info (void); + + RtecEventChannelAdmin::SupplierQOS &qos (void); + // Filtering criteria. + + int operator== (const RtecEventComm::EventSourceID rhs); + // Is this object a proxy for -rhs-. Simple pointer comparison for now. + + RtecEventComm::EventSourceID source_id (void); + // Returns underlying supplier object ref. + +private: + RtecEventChannelAdmin::SupplierQOS qos_; + // Reference to the supplier's qos params. + + ACE_ES_Subscription_Info subscription_info_; + + ACE_ES_Supplier_Module *supplier_module_; + + RtecEventComm::EventSourceID source_id_; + // We keep a proxy of the Supplier source_id_; + + RtecEventComm::PushSupplier_ptr push_supplier_; + // CORBA reference to remote push supplier. +}; + +// ************************************************************ + +class ACE_Push_Consumer_Proxy : public RtecEventChannelAdmin_ProxyPushSupplierBOAImpl +// = TITLE +// Push Consumer Proxy. +// +// = DESCRIPTION +// This is the channels proxy to a push consumer. It implements +// the RtecEventChannelAdmin::ProxyPushSupplier IDL interface. +// Consumers use this interface to connect and disconnect from the +// channel. +{ +public: + ACE_Push_Consumer_Proxy (ACE_ES_Consumer_Module *cm); + // Must be created with an consumer admin. + + virtual ~ACE_Push_Consumer_Proxy (void); + // Default destruction + + // = Interfaces exported to consumers. + + virtual void connect_push_consumer (RtecEventComm::PushConsumer_ptr push_consumer, + const RtecEventChannelAdmin::ConsumerQOS& qos, + CORBA::Environment &); + // A push consumer is connecting. <push_consumer> is a reference to + // the consumer. <qos> is the subscription types for the consumer. + + virtual void disconnect_push_supplier (CORBA::Environment &); + // The consumer is disconnecting. + + virtual void suspend (CORBA::Environment &); + // Stop forwarding events to the calling consumer. + + virtual void resume (CORBA::Environment &); + // Resume forwarding events to the calling consumer. + + // = Event Channel operations. + + void push (const RtecEventComm::EventSet &events, + CORBA::Environment &); + // Push <events> to push_consumer_. + + int connected (void); + // Returns 1 if the proxy has been connected to a "remote" client. + + void shutdown (void); + // Actively disconnect from the consumer. + + RtecEventChannelAdmin::ProxyPushSupplier_ptr get_ref (void); + // Allow transformations to RtecEventChannelAdmin::ProxyPushSupplier. + + ACE_ES_Consumer_Correlation &correlation (void); + // Access the consumer-specific Consumer_Correlation. + + RtecEventChannelAdmin::ConsumerQOS &qos (void); + // Filtering criteria. + +private: + RtecEventChannelAdmin::ConsumerQOS qos_; + // A reference to the consumers Quality of Service parameters. + + ACE_ES_Consumer_Correlation correlation_; + // A hook so that the Correlation Module can associate correlation + // information with the consumer. + + RtecEventComm::PushConsumer_ptr push_consumer_; + // Reference to our push consumer. + + ACE_ES_Consumer_Module *consumer_module_; + // TODO: Maybe this should be a _var or _duplicate/_release should + // be used +}; + +// ************************************************************ + +// Helper function that returns +// qos.dependencies_[0].rt_info_->entry_point or "no-name". +const char * +ACE_ES_Consumer_Name (const RtecEventChannelAdmin::ConsumerQOS &qos); + +// ************************************************************ + +typedef ACE_ES_Simple_Array <ACE_ES_Consumer_Rep *, + ACE_ES_MAX_CONSUMERS_PER_SUPPLIER> ACE_ES_CRSet; + +typedef ACE_ES_Array_Iterator <ACE_ES_Consumer_Rep *> ACE_ES_CRSet_Iterator; + +#if defined (__ACE_INLINE__) +#include "Event_Channel.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_EVENT_CHANNEL_H */ + diff --git a/TAO/orbsvcs/orbsvcs/Event/Event_Channel.i b/TAO/orbsvcs/orbsvcs/Event/Event_Channel.i new file mode 100644 index 00000000000..996ca7dc7d4 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Event_Channel.i @@ -0,0 +1,892 @@ +/* -*- C++ -*- */ +// $Id$ + +const unsigned int ACE_INT2BIT[32] = +{ + 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, + 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, + 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, + 268435456, 536870912, 1073741824, 2147483648, +}; + +// ************************************************** + +ACE_INLINE RtecEventChannelAdmin::ProxyPushConsumer_ptr +ACE_Push_Supplier_Proxy::get_ref (void) +{ + CORBA::Environment env; + return this->_this (env); +} + +ACE_INLINE int +ACE_Push_Supplier_Proxy::connected (void) +{ + return !CORBA::is_nil((CORBA::Object*) push_supplier_); +} + +ACE_INLINE ACE_ES_Subscription_Info & +ACE_Push_Supplier_Proxy::subscription_info (void) +{ + return subscription_info_; +} + +ACE_INLINE RtecEventChannelAdmin::SupplierQOS & +ACE_Push_Supplier_Proxy::qos (void) +{ + return qos_; +} + +ACE_INLINE int +ACE_Push_Supplier_Proxy::operator== (const RtecEventComm::EventSourceID rhs) +{ + // Pointer comparison is fine for now. + return (source_id_ == rhs); +} + +ACE_INLINE RtecEventComm::EventSourceID +ACE_Push_Supplier_Proxy::source_id (void) +{ + return source_id_; +} + +// ************************************************** + +ACE_INLINE RtecEventChannelAdmin::ProxyPushSupplier_ptr +ACE_Push_Consumer_Proxy::get_ref (void) +{ + CORBA::Environment env; + return this->_this (env); +} + +ACE_INLINE RtecEventChannelAdmin::ConsumerQOS & +ACE_Push_Consumer_Proxy::qos (void) +{ + return qos_; +} + +ACE_INLINE int +ACE_Push_Consumer_Proxy::connected (void) +{ + return !CORBA::is_nil(push_consumer_); +} + +ACE_INLINE void +ACE_Push_Consumer_Proxy::push (const RtecEventComm::EventSet &events, + CORBA::Environment &_env) +{ + ACE_TIMEPROBE (" deliver event to consumer proxy"); + + if (push_consumer_ == 0) + { + ACE_DEBUG ((LM_DEBUG, "Push to disconnected consumer %s: ", + ::ACE_ES_Consumer_Name (this->qos ()))); + // ACE_ES_DEBUG_ST (::dump_sequence (events)); + return; + } + + TAO_TRY + { + push_consumer_->push (events, TAO_TRY_ENV); + TAO_CHECK_ENV; + } + TAO_CATCH (CORBA::SystemException, se) + { + ACE_ERROR ((LM_ERROR, "system exception.\n")); + TAO_RETHROW; + } + TAO_ENDTRY; +} + +ACE_INLINE ACE_ES_Consumer_Correlation & +ACE_Push_Consumer_Proxy::correlation (void) +{ + return correlation_; +} + +ACE_INLINE RtecEventChannelAdmin::ConsumerAdmin_ptr +ACE_ES_Consumer_Module::get_ref (void) +{ + CORBA::Environment env; + return this->_this (env); +} + +ACE_INLINE RtecEventChannelAdmin::SupplierAdmin_ptr +ACE_ES_Supplier_Module::get_ref (void) +{ + CORBA::Environment env; + return this->_this (env); +} + +// ************************************************** + +ACE_INLINE RtecEventChannelAdmin::EventChannel_ptr +ACE_EventChannel::get_ref (void) +{ + CORBA::Environment env; + return this->_this (env); +} + +ACE_INLINE RtecEventChannelAdmin::SupplierAdmin_ptr +ACE_EventChannel::for_suppliers (CORBA::Environment &) +{ + return supplier_module_->get_ref (); +} + +ACE_INLINE RtecEventChannelAdmin::ConsumerAdmin_ptr +ACE_EventChannel::for_consumers (CORBA::Environment &) +{ + return consumer_module_->get_ref (); +} + +ACE_INLINE ACE_ES_Priority_Timer * +ACE_EventChannel::timer (void) +{ + return timer_; +} + +// ************************************************************ + +// Makes a temporary Event_var and appends it to the <dest>. +ACE_INLINE void +operator += (ACE_CORBA_Sequence<ACE_ES_Event_Container_var> &dest, + ACE_ES_Event_Container *item) +{ + int length = dest.length (); + dest.length (length + 1); + dest[length] = item; +} + +/* +// Makes a temporary Event_var and appends it to the <dest>. +ACE_INLINE void +operator += (ACE_CORBA_Sequence<RtecEventComm::Event_var> &dest, + RtecEventComm::Event *item) +{ + // RtecEventComm::Event_var event (item); + int length = dest.length (); + dest.length (length + 1); + dest[length] = item; +} +*/ + +ACE_INLINE int +operator == (const RtecEventComm::Event &event1, + const RtecEventComm::Event &event2) +{ + // Check if the sources are equal. 0 is a wildcard. + if ((event1.source_ != 0) + && (event2.source_ != 0) + && (event1.source_ != event2.source_)) + return 0; + + // Check if the types are equal. ACE_ES_EVENT_ANY is a wildcard. + if ((event1.type_ != ACE_ES_EVENT_ANY) && + (event2.type_ != ACE_ES_EVENT_ANY) && + (event1.type_ != event2.type_)) + return 0; + + return 1; +} + +// ************************************************************ + +ACE_INLINE +ACE_ES_ACT::ACE_ES_ACT (void) + : has_act_ (0) +{ +} + +// ************************************************************ + +ACE_INLINE +ACE_ES_Disjunction_Group::ACE_ES_Disjunction_Group (void) : + act_ (), + deadline_timer_rep_ (0), + correlation_module_ (0) +{ +} + +ACE_INLINE void +ACE_ES_Disjunction_Group::set_correlation_module (ACE_ES_Correlation_Module *cm) +{ + correlation_module_ = cm; +} + +ACE_INLINE void +ACE_ES_Disjunction_Group::reschedule_deadline (void) +{ + if (deadline_timer_rep_ != 0) + { + if (correlation_module_->reschedule_timeout (deadline_timer_rep_) == -1) + ACE_ERROR ((LM_ERROR, "%p.\n", "ACE_ES_Disjunction_Group::reschedule_deadline")); + } +} + +ACE_INLINE int +ACE_ES_Disjunction_Group::set_deadline_timeout (ACE_ES_Consumer_Rep_Timeout *cr) +{ + deadline_timer_rep_ = cr; + // Schedule the timeout. + if (correlation_module_->schedule_timeout (deadline_timer_rep_) == -1) + return -1; + else + return 0; +} + +ACE_INLINE void +ACE_ES_Disjunction_Group::add_events (Event_Set *outbox, + Event_Set *pending_events, + u_long &pending_flags) +{ + ACE_UNUSED_ARG (pending_events); + ACE_UNUSED_ARG (pending_flags); + + // Append the act. + if (act_ != 0) + *outbox += act_; +} + +ACE_INLINE void +ACE_ES_Disjunction_Group::set_act (RtecEventComm::Event &act) +{ + ACE_ES_Event_Container *temp = new ACE_ES_Event_Container (act); + if (temp == 0) + { + ACE_ERROR ((LM_ERROR, "%p.\n", "ACE_ES_Disjunction_Group::set_act")); + return; + } + + act_ = temp; + temp->_release (); +} + +// ************************************************************ + +ACE_INLINE +ACE_ES_Consumer_Rep::ACE_ES_Consumer_Rep (void) : + disconnected_ (0), + suspended_ (0), + correlation_type_ (ACE_ES_Consumer_Rep::NO_CORRELATION), + dependency_ (0), + correlation_ (0), + type_id_ (0), + disjunction_group_ (0), + ref_count_ (1) +{ +} + +ACE_INLINE void +ACE_ES_Consumer_Rep::init (ACE_ES_Consumer_Correlation *correlation, + RtecEventChannelAdmin::Dependency& dependency) +{ + dependency_ = &dependency; + correlation_ = correlation; +} + +ACE_INLINE RtecEventChannelAdmin::Dependency* +ACE_ES_Consumer_Rep::dependency (void) +{ + return dependency_; +} + +ACE_INLINE int +ACE_ES_Consumer_Rep::type_id (void) +{ + return type_id_; +} + +ACE_INLINE void +ACE_ES_Consumer_Rep::type_id (int id) +{ + type_id_ = id; +} + +ACE_INLINE ACE_ES_Consumer_Correlation * +ACE_ES_Consumer_Rep::correlation (void) +{ + return correlation_; +} + +ACE_INLINE u_long +ACE_ES_Consumer_Rep::correlation_type (void) +{ + return correlation_type_; +} + +ACE_INLINE void +ACE_ES_Consumer_Rep::correlation_type (u_long ct) +{ + correlation_type_ = ct; +} + +ACE_INLINE int +ACE_ES_Consumer_Rep::add_disjunction_group (ACE_ES_Disjunction_Group &dg) +{ + if (disjunction_group_ != 0) + ACE_ERROR ((LM_ERROR, "ACE_ES_Consumer_Rep::add_disjunction_group: " + "disjunction_group already set!\n")); + disjunction_group_ = &dg; + return 0; +} + +ACE_INLINE ACE_ES_Disjunction_Group * +ACE_ES_Consumer_Rep::top_group (void) +{ + return disjunction_group_; +} + +ACE_INLINE void +ACE_ES_Consumer_Rep::reschedule_deadlines (void) +{ + if (disjunction_group_ != 0) + disjunction_group_->reschedule_deadline (); +} + +ACE_INLINE int +ACE_ES_Consumer_Rep::receiving_events (void) +{ + return suspended_ == 0 && disconnected_ == 0; +} + +ACE_INLINE void +ACE_ES_Consumer_Rep::suspend (void) +{ + suspended_ = 1; +} + +ACE_INLINE void +ACE_ES_Consumer_Rep::resume (void) +{ + suspended_ = 0; +} + +ACE_INLINE void +ACE_ES_Consumer_Rep::_duplicate (void) +{ + // This is atomic. + ref_count_++; +} + +ACE_INLINE void +ACE_ES_Consumer_Rep::_release (void) +{ + // This is atomic. rc is because we want to avoid Atomic_Op's + // operator==. Don't change this code unless you think you're more + // studly than ACE_Atomic_Op. + int rc = --ref_count_; + + if (rc == 0) + delete this; +} + +ACE_INLINE int +ACE_ES_Consumer_Rep::disconnected (void) +{ + return disconnected_; +} + +ACE_INLINE void +ACE_ES_Consumer_Rep::disconnect (void) +{ + disconnected_ = 1; +} + +// ************************************************************ + +// Forward <events> to all consumers subscribed to <source> only. +ACE_INLINE int +ACE_ES_Subscription_Module::push_source (ACE_Push_Supplier_Proxy *source, + ACE_ES_Event_Container *event) +{ + ACE_TIMEPROBE (" enter ACE_ES_Subscription_Module::push"); + // If there are now source-based subscribers for this supplier, + // return. + if (source->subscription_info ().source_subscribers_.size () == 0) + return 0; + + ACE_ES_Subscription_Info::Subscriber_Set &set = + source->subscription_info ().source_subscribers_; + + // List of consumers that need to be disconnected. + ACE_ES_CRSet disconnect_list; + + { + // Acquire a read lock. + ACE_ES_RGUARD ace_mon (source->subscription_info ().lock_); + if (ace_mon.locked () == 0) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_ES_Subscription_Module::push_source.\n"), -1); + + ACE_ES_Subscription_Info::Subscriber_Set_Iterator iter (set); + + TAO_TRY + { + // Iterate through all subscribers. + for (ACE_ES_Consumer_Rep **consumer = 0; + iter.next (consumer) != 0; + iter.advance ()) + { + // Only push the event if the consumer is not suspended + // and not disconnected. + if ((*consumer)->receiving_events ()) + { + up_->push (*consumer, event, TAO_TRY_ENV); + TAO_CHECK_ENV; + } + // If the consumer has disconnected, schedule it for + // disconnection. We can not modify our list now. It + // would mess up the iterator. + if ((*consumer)->disconnected ()) + disconnect_list.insert (*consumer); + } + } + TAO_CATCHANY + { + return -1; + } + TAO_ENDTRY; + + // Release the read lock. + } + + // If there are consumers scheduled for disconnect, acquire a write + // lock and disconnect them. + if (disconnect_list.size () != 0) + { + ACE_ES_WGUARD ace_mon (source->subscription_info ().lock_); + if (ace_mon.locked () == 0) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_ES_Subscription_Module::push_source.\n"), -1); + + ACE_ES_CRSet_Iterator iter (disconnect_list.data (), disconnect_list.size ()); + + // Iterate through the disconnecting consumers. + for (ACE_ES_Consumer_Rep **consumer = 0; + iter.next (consumer) != 0; + iter.advance ()) + { + // Remove the consumer from subscriber list. + if (set.remove (*consumer) == -1) + ACE_ERROR ((LM_ERROR, "%p remove failed.\n", + "ACE_ES_Subscription_Module::push_source.\n")); + else + // Decrement the consumer rep's reference count. + (*consumer)->_release (); + } + } + + return 0; +} + +// 1. figure out why we're going through the subscription module, +// instead of just passing through. +// 2. where is lock_? Is there only one per module!? + +ACE_INLINE int +ACE_ES_Subscription_Module::push_source_type (ACE_Push_Supplier_Proxy *source, + ACE_ES_Event_Container *event) +{ + // Step through each event in the set. For each event type, find + // the corresponding set in the type collection. Push the single + // event to each consumer in the set. + + ACE_ES_Subscription_Info::Subscriber_Map &supplier_map = + source->subscription_info ().type_subscribers_; + + ACE_ES_CRSet disconnect_list; + + ACE_ES_Subscription_Info::Subscriber_Set *set; + + { + ACE_ES_RGUARD ace_mon (source->subscription_info ().lock_); + if (ace_mon.locked () == 0) + { + ACE_TIMEPROBE (" push_source_type"); + ACE_ERROR_RETURN ((LM_ERROR, "ACE_ES_Subscription_Module::push_source_type.\n"), -1); + } + + ACE_ES_Subscription_Info::Type_Subscribers *subscribers; + + if (supplier_map.current_size () == 0) + { + ACE_TIMEPROBE (" push_source_type"); + return 0; + } + + if (supplier_map.find (event->type_, subscribers) == -1) + { + ACE_DEBUG ((LM_ERROR, "ACE_ES_Subscription_Module::push_source_type" + " Warning: event type %d not registered.\n", + event->type_)); + ACE_TIMEPROBE (" push_source_type"); + return 0; // continue anyway + } + + if (subscribers->consumers_.size () == 0) + { + ACE_TIMEPROBE (" push_source_type"); + return 0; + } + + set = &subscribers->consumers_; + + // We've found the set of consumers subscribed to this type + // of event from this supplier. Forward the event to each. + ACE_ES_Subscription_Info::Subscriber_Set_Iterator iter (*set); + + TAO_TRY + { + for (ACE_ES_Consumer_Rep **consumer = 0; + iter.next (consumer) != 0; + iter.advance ()) + { + if ((*consumer)->receiving_events ()) + { + up_->push (*consumer, event, TAO_TRY_ENV); + TAO_CHECK_ENV; + } + if ((*consumer)->disconnected ()) + disconnect_list.insert (*consumer); + } + } + TAO_CATCHANY + { + ACE_TIMEPROBE (" push_source_type"); + return -1; + } + TAO_ENDTRY; + } + + if (disconnect_list.size () != 0) + // Acquire a write lock and remove all disconnected consumers. + { + ACE_ES_WGUARD ace_mon (source->subscription_info ().lock_); + if (ace_mon.locked () == 0) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_ES_Subscription_Module::push_source.\n"), -1); + + ACE_ES_CRSet_Iterator iter (disconnect_list.data (), disconnect_list.size ()); + + for (ACE_ES_Consumer_Rep **consumer = 0; + iter.next (consumer) != 0; + iter.advance ()) + { + if (set->remove (*consumer) == -1) + ACE_ERROR ((LM_ERROR, "%p remove failed.\n", + "ACE_ES_Subscription_Module::push_source.\n")); + else + (*consumer)->_release (); + } + } + + ACE_TIMEPROBE (" push_source_type"); + return 0; +} + +// ************************************************************ + +ACE_INLINE ACE_RTU_Manager * +ACE_EventChannel::rtu_manager (void) +{ + return rtu_manager_; +} + +ACE_INLINE +ACE_RTU_Manager::ACE_RTU_Manager (int active) + : active_ (active), + should_preempt_ (0), + not_done_ (0), + priority_ (ACE_Scheduler_MIN_PREEMPTION_PRIORITY) +{ +} + +ACE_INLINE int +ACE_RTU_Manager::should_preempt (void) +{ + if (!active_) + return 0; + else + { + // Expire any timers. Am I evil for putting this here? + ACE_Time_Value tv; + if (ACE_Task_Manager::instance ()-> + GetReactorTask (0)->get_reactor ().handle_events (&tv) == -1) + ACE_ERROR ((LM_ERROR, "%p.\n", + "ACE_RTU_Manager::should_preempt")); + + int should_preempt = should_preempt_; + should_preempt_ = 0; + return should_preempt; + } +} + +ACE_INLINE void +ACE_RTU_Manager::should_preempt (int s) +{ + should_preempt_ = s; +} + +ACE_INLINE int +ACE_RTU_Manager::not_done (void) +{ + int not_done = not_done_; + not_done_ = 0; + return not_done; +} + +ACE_INLINE void +ACE_RTU_Manager::not_done (int nd) +{ + not_done_ = nd; +} + +ACE_INLINE RtecScheduler::OS_Priority +ACE_RTU_Manager::priority (void) +{ + return priority_; +} + +ACE_INLINE void +ACE_RTU_Manager::priority (RtecScheduler::OS_Priority p) +{ + priority_ = p; +} + +// ************************************************************ + +ACE_INLINE +ACE_ES_Consumer_Rep_Timeout::ACE_ES_Consumer_Rep_Timeout (void) : + timer_id_ (0), + preemption_priority_ (ACE_Scheduler_MIN_PREEMPTION_PRIORITY), + timeout_event_ () +{ +} + +ACE_INLINE void +ACE_ES_Consumer_Rep_Timeout::init (ACE_ES_Consumer_Correlation *correlation, + RtecEventChannelAdmin::Dependency &dep) +{ + ACE_ES_Event_Container *temp = new ACE_ES_Event_Container (dep.event_); + if (temp == 0) + { + ACE_ERROR ((LM_ERROR, "%p.\n", "ACE_ES_Consumer_Rep_Timeout::init")); + return; + } + + timeout_event_ = temp; + temp->_release (); + + ACE_ES_Consumer_Rep::init (correlation, dep); +} + +ACE_INLINE int +ACE_ES_Consumer_Rep_Timeout::timer_id (void) +{ + return timer_id_; +} + +ACE_INLINE void +ACE_ES_Consumer_Rep_Timeout::timer_id (int id) +{ + timer_id_ = id; +} + +ACE_INLINE RtecScheduler::OS_Priority +ACE_ES_Consumer_Rep_Timeout::preemption_priority (void) +{ + return preemption_priority_; +} + +ACE_INLINE void +ACE_ES_Consumer_Rep_Timeout::preemption_priority (RtecScheduler::OS_Priority p) +{ + preemption_priority_ = p; +} + +// ************************************************************ + +ACE_INLINE void +ACE_ES_Consumer_Correlation::suspend (void) +{ + for (int x=0; x < n_timer_reps_; x++) + timer_reps_[x].suspend (); + + for (int y=0; y < n_consumer_reps_; y++) + consumer_reps_[y]->suspend (); +} + +ACE_INLINE void +ACE_ES_Consumer_Correlation::resume (void) +{ + for (int x=0; x < n_timer_reps_; x++) + timer_reps_[x].resume (); + + for (int y=0; y < n_consumer_reps_; y++) + consumer_reps_[y]->resume (); +} + +// ************************************************************ + +ACE_INLINE +ACE_ES_Dependency_Iterator::ACE_ES_Dependency_Iterator (RtecEventChannelAdmin::DependencySet &rep) : + rt_info_ (0), + rep_ (rep), + index_ (-1), + n_conjunctions_ (0), + n_disjunctions_ (0), + n_timeouts_ (0), + n_events_ (0) +{ +} + +ACE_INLINE int +ACE_ES_Dependency_Iterator::advance_dependency (void) +{ + index_++; + if ((CORBA::ULong) index_ >= rep_.length ()) + return -1; + else + return 0; +} + +ACE_INLINE RtecEventChannelAdmin::Dependency & +ACE_ES_Dependency_Iterator::operator *(void) +{ + return rep_[index_]; +} + +ACE_INLINE int +ACE_ES_Dependency_Iterator::parse (void) +{ + for (CORBA::ULong x = 0; x < rep_.length (); x++) + { + if (rt_info_ == 0) + rt_info_ = rep_[x].rt_info; + + switch (rep_[x].event_.type_) + { + case ACE_ES_CONJUNCTION_DESIGNATOR: + n_conjunctions_++; + break; + + case ACE_ES_DISJUNCTION_DESIGNATOR: + n_disjunctions_++; + break; + + case ACE_ES_EVENT_TIMEOUT: + case ACE_ES_EVENT_INTERVAL_TIMEOUT: + case ACE_ES_EVENT_DEADLINE_TIMEOUT: + n_timeouts_++; + break; + + default: + n_events_++; + break; + } + } + + return 0; +} + +ACE_INLINE int +ACE_ES_Dependency_Iterator::n_conjunctions (void) +{ + return n_conjunctions_; +} + +ACE_INLINE int +ACE_ES_Dependency_Iterator::n_disjunctions (void) +{ + return n_disjunctions_; +} + +ACE_INLINE int +ACE_ES_Dependency_Iterator::n_timeouts (void) +{ + return n_timeouts_; +} + +ACE_INLINE int +ACE_ES_Dependency_Iterator::n_events (void) +{ + return n_events_; +} + +ACE_INLINE RtecScheduler::handle_t +ACE_ES_Dependency_Iterator::first_rt_info (void) +{ + return rt_info_; +} + +// ************************************************************ + +ACE_INLINE +ACE_ES_Conjunction_Group::ACE_ES_Conjunction_Group (void) : + forward_value_ (0) +{ +} + +ACE_INLINE int +ACE_ES_Conjunction_Group::add_type (int type_id) +{ + ACE_SET_BITS (forward_value_, ACE_INT2BIT[type_id]); + return 0; +} + +/* + // Set length bits. + for (int x=0; x < length; x++) + { + forward_value_ <<= 1; + forward_value_ |= 1; + } + */ + +ACE_INLINE int +ACE_ES_Conjunction_Group::should_forward (u_long pending_flags) +{ + if ((forward_value_ & pending_flags) == forward_value_) + return 1; + else + return 0; +} + +ACE_INLINE void +ACE_ES_Conjunction_Group::add_events (Event_Set *outbox, + Event_Set *pending_events, + u_long &pending_flags) +{ + // Append the act first. + if (act_ != 0) + *outbox += act_; + + u_long fv = forward_value_; + int x = 0; + while (fv > 0) + { + // If this type_id is part of the correlation, then append each + // event pending to the outbox. + if (ACE_BIT_ENABLED (forward_value_, ACE_INT2BIT[x])) + { + // Step through each of the pending events. + Event_Set &pending = pending_events[x]; + for (CORBA::ULong y=0; y < pending.length (); y++) + { + // Add the pending event to the outbox. + if (outbox != 0) + *outbox += pending[y]; + // Remove the event from the pending events array. + pending[y] = 0; + } + + // Reset the array length. + pending.length (0); + // Since we just emptied the events for this type, clear the + // x^th bit in pending flags. + ACE_CLR_BITS (pending_flags, ACE_INT2BIT[x]); + // Clear the x^th bit in fv. + ACE_CLR_BITS (fv, ACE_INT2BIT[x]); + } + + x++; + } +} + +// ************************************************************ diff --git a/TAO/orbsvcs/orbsvcs/Event/Event_Service.cpp b/TAO/orbsvcs/orbsvcs/Event/Event_Service.cpp new file mode 100644 index 00000000000..c352933570e --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Event_Service.cpp @@ -0,0 +1,119 @@ +// +// $Id$ +// + +#include "ace/Get_Opt.h" +#include "tao/corba.h" + +#include "orbsvcs/CosNamingC.h" +#include "orbsvcs/Scheduler_Factory.h" +#include "orbsvcs/Event_Utilities.h" +#include "Event_Channel.h" + + + +const char* service_name = "EventService"; + +int +parse_args (int argc, char *argv []) +{ + ACE_Get_Opt get_opt (argc, argv, "n:"); + int opt; + + while ((opt = get_opt ()) != EOF) + { + switch (opt) + { + case 'n': + service_name = get_opt.optarg; + break; + case '?': + default: + ACE_DEBUG ((LM_DEBUG, + "Usage: %s " + "-n service_name " + "\n", + argv[0])); + return -1; + } + } + + return 0; +} + + +int main (int argc, char *argv[]) +{ + TAO_TRY + { + // Initialize ORB. + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "internet", TAO_TRY_ENV); + TAO_CHECK_ENV; + + if (parse_args (argc, argv) == -1) + return 1; + + CORBA::Object_var poa_object = + orb->resolve_initial_references("RootPOA"); + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n"), + 1); + + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (poa_object.in (), TAO_TRY_ENV); + TAO_CHECK_ENV; + + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (TAO_TRY_ENV); + TAO_CHECK_ENV; + + CORBA::Object_var naming_obj = + orb->resolve_initial_references ("NameService"); + if (CORBA::is_nil (naming_obj.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n"), + 1); + + CosNaming::NamingContext_var naming_context = + CosNaming::NamingContext::_narrow (naming_obj.in (), TAO_TRY_ENV); + TAO_CHECK_ENV; + + ACE_Scheduler_Factory::use_config (naming_context.in ()); + + // Register Event_Service with Naming Service. + ACE_EventChannel ec_impl; + + RtecEventChannelAdmin::EventChannel_var ec = + ec_impl._this (TAO_TRY_ENV); + TAO_CHECK_ENV; + + CORBA::String_var str = + orb->object_to_string (ec.in (), TAO_TRY_ENV); + + ACE_DEBUG ((LM_DEBUG, "The EC IOR is <%s>\n", str.in ())); + + CosNaming::Name channel_name (1); + channel_name.length (1); + channel_name[0].id = CORBA::string_dup (service_name); + naming_context->bind (channel_name, ec.in (), TAO_TRY_ENV); + TAO_CHECK_ENV; + + poa_manager->activate (TAO_TRY_ENV); + TAO_CHECK_ENV; + + ACE_DEBUG ((LM_DEBUG, "running event service\n")); + if (orb->run () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "run"), 1); + + } + TAO_CATCHANY + { + TAO_TRY_ENV.print_exception ("EC"); + } + TAO_ENDTRY; + + + return 0; +} diff --git a/TAO/orbsvcs/orbsvcs/Event/Fast_Reactor.h b/TAO/orbsvcs/orbsvcs/Event/Fast_Reactor.h new file mode 100644 index 00000000000..3759376bd01 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Fast_Reactor.h @@ -0,0 +1,53 @@ +// +// $Id$ +// +#if !defined (FAST_REACTOR_H) +#define FAST_REACTOR_H + +#if defined (ACE_OLD_STYLE_REACTOR) +# if defined (ACE_WIN32) +# include "ace/ReactorEx.h" +# define ACE_ES_FAST_REACTOR_BASE ACE_ReactorEx +# else +# include "ace/Reactor.h" +# define ACE_ES_FAST_REACTOR_BASE ACE_Reactor +# endif /* ACE_WIN32 */ +#else +# if defined (ACE_WIN32) +# include "ace/WFMO_Reactor.h" +# define ACE_ES_FAST_REACTOR_BASE ACE_WFMO_Reactor +# else +# include "ace/Select_Reactor.h" +# define ACE_ES_FAST_REACTOR_BASE ACE_Select_Reactor +# endif /* ACE_WIN32 */ +#endif /* ACE_OLD_STYLE_REACTOR */ +//## end module.includes + +class ACE_ES_Fast_Reactor : public ACE_ES_FAST_REACTOR_BASE +{ +public: + virtual int handle_events (ACE_Time_Value *max_wait_time = 0) + { + ACE_Time_Value timer_buf (0) ; + ACE_Time_Value *this_timeout = &timer_buf ; + + if (this->timer_queue_->calculate_timeout (max_wait_time, + this_timeout) == 0) + { + ACE_Time_Value t (0, 500000); + ACE_OS::select (0, 0, 0, 0, &t); + } + else + { + ACE_OS::select (0, 0, 0, 0, this_timeout); + } + + return this->timer_queue_->expire () == -1 ? -1 : 0; + } + virtual int handle_events (ACE_Time_Value &max_wait_time) + { + return this->handle_events (&max_wait_time); + } +}; + +#endif /* FAST_REACTOR_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/GPlot_File.cpp b/TAO/orbsvcs/orbsvcs/Event/GPlot_File.cpp new file mode 100644 index 00000000000..587d97728f5 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/GPlot_File.cpp @@ -0,0 +1,179 @@ +// $Id$ +// +// ============================================================================ +// +// = FILENAME +// GPlot_File.cpp +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "GPlot_File.h" + +#if !defined (__ACE_INLINE__) +#include "GPlot_File.i" +#endif /* __ACE_INLINE__ */ + +int +ACE_GPlot_File::open (const char *filename) +{ + ACE_OS::strcpy (filename_, filename); + + FILE *read_file = ACE_OS::fopen (filename_, "r"); + + long entry; + char *value; + ACE_NEW_RETURN (value, char [32], -1); + + if (read_file > 0) + { + int result; + do + { + result = fscanf (read_file, + "%ld\t%s\n", + &entry, + value); + + //if ((result == -1) && (ACE_OS::last_error () != 0)) + //ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", "ACE_GPlot_File::open"), -1); + + if (result > 0) + // Success. + map_.bind (entry, value); + else if (result != EOF) + // Error. + { + ACE_OS::fclose (read_file); + ACE_ERROR_RETURN + ((LM_ERROR, "Error reading GPlot file %s.\n", filename_), -1); + } + } while (result != EOF); + + fclose (read_file); + } + + write_file_ = ACE_OS::fopen (filename_, "w"); + if (write_file_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p: can't open\n", filename_), -1); + + closed_ = 0; + + return 0; +} + + +void +ACE_GPlot_File::close (void) +{ + if (closed_ == 0) + { + closed_ = 1; + GPLOT_ITERATOR iterator ((GPLOT_MAP &) map_); + for (GPLOT_ENTRY *entry; iterator.next (entry); iterator.advance ()) + { + ACE_OS::fprintf (write_file_, "%ld\t%s\n", + entry->ext_id_, entry->int_id_); + delete [] entry->int_id_; + } + + ACE_OS::fclose (write_file_); + } +} + + +void +ACE_GPlot_File::dump (void) +{ + GPLOT_ITERATOR iterator ((GPLOT_MAP &) map_); + for (GPLOT_ENTRY *entry; iterator.next (entry); iterator.advance ()) + { + if (entry->int_id_ != 0) + ACE_DEBUG ((LM_DEBUG, "%d\t%s\n", entry->ext_id_, entry->int_id_)); + else + { + ACE_ERROR ((LM_ERROR, "Value for entry %d is null.\n", + entry->ext_id_)); + return; + } + } +} + + +int +ACE_GPlot_File::get (long entry, long &value) +{ + char *val; + + if (map_.find (entry, val) == -1) + return -1; + else + { + ::sscanf (val, "%ld", &value); + return 0; + } +} + + +int +ACE_GPlot_File::get (long entry, float &value) +{ + char *val; + + if (map_.find (entry, val) == -1) + return -1; + else + { + ::sscanf (val, "%f", &value); + return 0; + } +} + + +void +ACE_GPlot_File::set (long entry, long value) +{ + long old_entry; + char *val; + char *old_value; + + ACE_NEW (val, char [32]); + + ::sprintf (val, "%ld", value); + map_.rebind (entry, val, old_entry, old_value); + + delete [] old_value; +} + + +void +ACE_GPlot_File::set (long entry, float value) +{ + long old_entry; + char *val; + char *old_value; + + ACE_NEW (val, char [32]); + + ::sprintf (val, "%f", value); + map_.rebind (entry, val, old_entry, old_value); + + delete [] old_value; +} + + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Map_Entry<long, char *>; +template class ACE_Map_Manager<long, char *, ACE_Null_Mutex>; +template class ACE_Map_Iterator_Base<long, char *, ACE_Null_Mutex>; +template class ACE_Map_Iterator<long, char *, ACE_Null_Mutex>; +template class ACE_Map_Reverse_Iterator<long, char *, ACE_Null_Mutex>; +#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Map_Entry<long, char *> +#pragma instantiate ACE_Map_Manager<long, char *, ACE_Null_Mutex> +#pragma instantiate ACE_Map_Iterator_Base<long, char *, ACE_Null_Mutex> +#pragma instantiate ACE_Map_Iterator<long, char *, ACE_Null_Mutex> +#pragma instantiate ACE_Map_Reverse_Iterator<long, char *, ACE_Null_Mutex> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Event/GPlot_File.h b/TAO/orbsvcs/orbsvcs/Event/GPlot_File.h new file mode 100644 index 00000000000..278641244d2 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/GPlot_File.h @@ -0,0 +1,97 @@ +// $Id$ +// +// ============================================================================ +// +// = FILENAME +// GPlot_File.h +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#if !defined (ACE_GPlot_File_H) +#define ACE_GPlot_File_H + +#include "ace/Map_Manager.h" +#include "ace/Synch.h" + +class ACE_GPlot_File +// = TITLE +// Reads and writes files in GPlot format. +// +// = DESCRIPTION +// Gplot formats are as follows: +// entry value +// entry value +// entry value +// ... +// They represent x,y pairs to be graphed by GPlot. entry's are +// type long. value's are type long or float. +{ +public: + ACE_GPlot_File (void); + // Construction. + + ~ACE_GPlot_File (void); + // Destruction. Calls this->close. + + int open (const char *filename); + // If the file does not exist, create it. If the file exists open + // the file and read all the entries into map_. Returns 0 on + // success, -1 on failure. + + void close (void); + // Close the file and sync all the contents. + + int get (long entry, long &value); + // Get the entry at this value. Returns 0 if a value was found. + // Returns -1 if no value has been set for <entry>. + + int get (long entry, float &value); + // Get the entry at this value. Returns 0 if a value was found. + // Returns -1 if no value has been set for <entry>. + + void set (long entry, long value); + // Set the entry at this value. + + void set (long entry, float value); + // Set the entry at this value. + + void set_greatest (long entry, long value); + // Compare <value> with the value at <entry>. Store the largest. + + void set_greatest (long entry, float value); + // Compare <value> with the value at <entry>. Store the largest. + + void set_least (long entry, long value); + // Compare <value> with the value at <entry>. Store the smallest. + + void set_least (long entry, float value); + // Compare <value> with the value at <entry>. Store the smallest. + + void dump (void); + // Dump state of the object. + +private: + // = map_ stores all values. It is sync'ed to file when this->close + // is called. + typedef ACE_Map_Entry <long, char *> GPLOT_ENTRY; + typedef ACE_Map_Manager<long, char *, ACE_Null_Mutex> GPLOT_MAP; + typedef ACE_Map_Iterator <long, char *, ACE_Null_Mutex> GPLOT_ITERATOR; + + GPLOT_MAP map_; + + char filename_[BUFSIZ]; + FILE *write_file_; + + int closed_; + // Only close once. +}; + +#if defined (__ACE_INLINE__) +#include "GPlot_File.i" +#endif /* __ACE_INLINE__ */ + + +#endif /* ACE_GPlot_File_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/GPlot_File.i b/TAO/orbsvcs/orbsvcs/Event/GPlot_File.i new file mode 100644 index 00000000000..ab9f235dc39 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/GPlot_File.i @@ -0,0 +1,70 @@ +// $Id$ + +ACE_INLINE +ACE_GPlot_File::ACE_GPlot_File (void) + : closed_ (1) +{ +} + + +ACE_INLINE +ACE_GPlot_File::~ACE_GPlot_File (void) +{ + this->close (); +} + + +ACE_INLINE +void +ACE_GPlot_File::set_greatest (long entry, long value) +{ + long old_value; + + // If there was no previous value, or the <value> is greater than + // the previous value, set a new value. + if (this->get (entry, old_value) == -1 || + value > old_value) + this->set (entry, value); +} + + +ACE_INLINE +void +ACE_GPlot_File::set_greatest (long entry, float value) +{ + float old_value; + + // If there was no previous value, or the <value> is greater than + // the previous value, set a new value. + if (this->get (entry, old_value) == -1 || + value > old_value) + this->set (entry, value); +} + + +ACE_INLINE +void +ACE_GPlot_File::set_least (long entry, long value) +{ + long old_value; + + // If there was no previous value, or the <value> is less than + // the previous value, set a new value. + if (this->get (entry, old_value) == -1 || + value < old_value) + this->set (entry, value); +} + + +ACE_INLINE +void +ACE_GPlot_File::set_least (long entry, float value) +{ + float old_value; + + // If there was no previous value, or the <value> is less than + // the previous value, set a new value. + if (this->get (entry, old_value) == -1 || + value < old_value) + this->set (entry, value); +} diff --git a/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.cpp b/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.cpp new file mode 100644 index 00000000000..ebfd367dc9a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.cpp @@ -0,0 +1,9 @@ +// +// $Id$ +// + +#include "Local_ESTypes.h" + +#if !defined (__ACE_INLINE__) +#include "Local_ESTypes.i" +#endif /* __ACE_INLINE__ */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.h b/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.h new file mode 100644 index 00000000000..bf34edee6cc --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.h @@ -0,0 +1,62 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORB Services +// +// = FILENAME +// Local_ESTypes.h +// +// = AUTHOR +// Tim Harrison (harrison@cs.wustl.edu) +// +// = DESCRIPTION +// Manual types that would otherwise be defined/implemented via an +// IDL compiler. +// NOTE: the file is obsolecent, we have TAO now, but we keep it +// to speed up the porting. +// +// ============================================================================ + +#ifndef ACE_LOCAL_ESTYPES_H +#define ACE_LOCAL_ESTYPES_H + +#include "tao/corba.h" + +#include "orbsvcs/Event_Service_Constants.h" + +#include "orbsvcs/CosNamingC.h" +#include "orbsvcs/RtecSchedulerC.h" +#include "orbsvcs/RtecSchedulerS.h" +#include "orbsvcs/RtecEventCommC.h" +#include "orbsvcs/RtecEventCommS.h" +#include "orbsvcs/RtecEventChannelAdminC.h" +#include "orbsvcs/RtecEventChannelAdminS.h" + +#define ACE_DEFAULT_EVENT_CHANNEL_TYPE 0 + +// These are to help MSVC++ 4.2 deal with inheritence of nested types. +// Not needed for Sun C++ or MSVC++ 5.0. + +// @@ NOTE: TAO uses the POA mapping instead of the old BOA, but all the +// code still uses the BOA name for the skeleton classes, to speed up +// porting we keep to old names. + +typedef RtecEventComm::Event RtecEventComm_Event; +typedef POA_RtecScheduler::Scheduler RtecScheduler_SchedulerBOAImpl; +typedef POA_RtecEventChannelAdmin::EventChannel RtecEventChannelAdmin_EventChannelBOAImpl; +typedef POA_RtecEventComm::PushSupplier RtecEventComm_PushSupplierBOAImpl; +typedef POA_RtecEventChannelAdmin::ConsumerAdmin RtecEventChannelAdmin_ConsumerAdminBOAImpl; +typedef POA_RtecEventChannelAdmin::SupplierAdmin RtecEventChannelAdmin_SupplierAdminBOAImpl; +typedef POA_RtecEventChannelAdmin::ProxyPushConsumer RtecEventChannelAdmin_ProxyPushConsumerBOAImpl; +typedef POA_RtecEventChannelAdmin::ProxyPushSupplier RtecEventChannelAdmin_ProxyPushSupplierBOAImpl; +typedef POA_RtecEventComm::PushConsumer RtecEventComm_PushConsumerBOAImpl; +typedef POA_RtecEventComm::PushSupplier RtecEventComm_PushSupplierBOAImpl; + +#if defined (__ACE_INLINE__) +#include "Local_ESTypes.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_LOCAL_ESTYPES_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.i b/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.i new file mode 100644 index 00000000000..8f8ef4cfe2d --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.i @@ -0,0 +1,5 @@ +/* -*- C++ -*- */ +// +// $Id$ +// + diff --git a/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.cpp b/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.cpp new file mode 100644 index 00000000000..a5c21379a2e --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.cpp @@ -0,0 +1,37 @@ +// $Id$ + +#include "Memory_Pools.h" +#include "Event_Channel.h" + +#if !defined (__ACE_INLINE__) +#include "Memory_Pools.i" +#endif /* __ACE_INLINE__ */ + +ACE_TSS<ACE_ES_Dispatch_Request_Allocator> ACE_ES_Memory_Pools::Dispatch_Request_; +ACE_TSS<ACE_ES_Event_Container_Allocator> ACE_ES_Memory_Pools::Event_Container_; +ACE_TSS<ACE_ES_Event_Allocator> ACE_ES_Memory_Pools::Event_; + +// ************************************************************ + +int +ACE_ES_Memory_Pools::thr_init (void) +{ + // Allocate the memory pool for this thread. + Event_Container_.ts_object (); + Dispatch_Request_.ts_object (); + Event_.ts_object (); + return 0; +} + +// ************************************************************ + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +// For ACE_ES_Memory_Pools. +template class ACE_TSS<ACE_ES_Event_Container_Allocator>; +template class ACE_TSS<ACE_ES_Dispatch_Request_Allocator>; +template class ACE_TSS<ACE_Malloc<ACE_Local_Memory_Pool, ACE_Local_Memory_Pool_Options, ACE_MEMORY_POOL_MUTEX> >; +#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_TSS<ACE_ES_Event_Container_Allocator> +#pragma instantiate ACE_TSS<ACE_ES_Dispatch_Request_Allocator> +#pragma instantiate ACE_TSS<ACE_Malloc<ACE_Local_Memory_Pool, ACE_Local_Memory_Pool_Options, ACE_MEMORY_POOL_MUTEX> > +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.h b/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.h new file mode 100644 index 00000000000..3fbb2f7ab0e --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.h @@ -0,0 +1,105 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORB Services +// +// = FILENAME +// Memory_Pools +// +// = AUTHOR +// Tim Harrison (harrison@cs.wustl.edu) +// +// ============================================================================ + +#ifndef ACE_MEMORY_POOLS_H +#define ACE_MEMORY_POOLS_H + +#include "ace/Synch.h" +#include "Event_Channel.h" +#include "Dispatching_Modules.h" + +// ************************************************************ + +#if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION) + typedef ACE_Null_Mutex ACE_MEMORY_POOL_MUTEX; +#else + // Use the same object for each thread. Therefore, we have to use + // real synchronization. + typedef ACE_Thread_Mutex ACE_MEMORY_POOL_MUTEX; +#endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */ + +typedef char ACE_ES_Dispatch_Request_Chunk[sizeof (ACE_ES_Dispatch_Request)]; + +typedef ACE_Cached_Allocator<ACE_ES_Dispatch_Request_Chunk, ACE_MEMORY_POOL_MUTEX> _ACE_Dispatch_Request_Allocator; + +class ACE_ES_Dispatch_Request_Allocator : public _ACE_Dispatch_Request_Allocator +// = TITLE +// Dispatch Request Allocator +// +// = DESCRIPTION +// This just sets the size of the Event Container memory pool. +{ +public: + ACE_ES_Dispatch_Request_Allocator (void) : + _ACE_Dispatch_Request_Allocator (ACE_ES_DISPATCH_REQUEST_MEMORY_POOL) {} +}; + +// ************************************************************ + +typedef char ACE_ES_Event_Container_Chunk[sizeof (ACE_ES_Event_Container)]; + +typedef ACE_Cached_Allocator<ACE_ES_Event_Container_Chunk, ACE_MEMORY_POOL_MUTEX> _ACE_Event_Container_Allocator; + +class ACE_ES_Event_Container_Allocator : public _ACE_Event_Container_Allocator +// = TITLE +// Event Container Allocator +// +// = DESCRIPTION +// This just sets the size of the Event Container memory pool. +{ +public: + ACE_ES_Event_Container_Allocator (void) : + _ACE_Event_Container_Allocator (ACE_ES_EVENT_CONTAINER_MEMORY_POOL) {} +}; + +// ************************************************************ + +typedef char ACE_ES_Event_Chunk[sizeof (RtecEventComm::Event)]; + +typedef ACE_Malloc<ACE_LOCAL_MEMORY_POOL, ACE_MEMORY_POOL_MUTEX> ACE_ES_Event_Allocator; +//typedef ACE_Cached_Allocator<ACE_ES_Event_Chunk, ACE_MEMORY_POOL_MUTEX> _ACE_Event_Allocator; + +class ACE_ES_Memory_Pools +// = TITLE +// Event Service Memory Pools. +// +// = DESCRIPTION +// These have to be static in order to be accessed by operator +// news, right? +{ +public: + static int thr_init (void); + // This can be called by every thread that will access these memory + // pools to preallocate the thread specific allocators. It is not + // mandatory. + + static void *new_Event_Container (void); + static void delete_Event_Container (void *); + static void *new_Dispatch_Request (void); + static void delete_Dispatch_Request (void *); + static void *new_Event (size_t); + static void delete_Event (void *); + + static ACE_TSS<ACE_ES_Dispatch_Request_Allocator> Dispatch_Request_; + static ACE_TSS<ACE_ES_Event_Container_Allocator> Event_Container_; + static ACE_TSS<ACE_ES_Event_Allocator> Event_; +}; + +#if defined (__ACE_INLINE__) +#include "Memory_Pools.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_MEMORY_POOLS_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.i b/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.i new file mode 100644 index 00000000000..3f6e3b26223 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.i @@ -0,0 +1,54 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE void * +ACE_ES_Memory_Pools::new_Event_Container (void) +{ + return Event_Container_->malloc (sizeof (ACE_ES_Event_Container)); +} + +ACE_INLINE void +ACE_ES_Memory_Pools::delete_Event_Container (void *mem) +{ + Event_Container_->free (mem); +} + +ACE_INLINE void * +ACE_ES_Memory_Pools::new_Dispatch_Request (void) +{ + return Dispatch_Request_->malloc (sizeof (ACE_ES_Dispatch_Request)); +} + +ACE_INLINE void +ACE_ES_Memory_Pools::delete_Dispatch_Request (void *mem) +{ + Dispatch_Request_->free (mem); +} + +#define USE_MEM_POOLS 1 + +ACE_INLINE void * +ACE_ES_Memory_Pools::new_Event (size_t len) +{ +#if USE_MEM_POOLS + const u_int ev_size = sizeof (RtecEventComm::Event); + const u_int size = (ev_size % ACE_MALLOC_ALIGN) ? + ((ev_size / ACE_MALLOC_ALIGN) + 1) * ACE_MALLOC_ALIGN : ev_size; + + char *const addr = (char *) Event_->malloc (len * size); +#else + char *const addr = new char[len * sizeof (ACE_ES_Event)]; +#endif + + return addr; +} + +ACE_INLINE void +ACE_ES_Memory_Pools::delete_Event (void *mem) +{ +#if USE_MEM_POOLS + Event_->free (mem); +#else + delete [] mem; +#endif +} diff --git a/TAO/orbsvcs/orbsvcs/Event/RT_Task.cpp b/TAO/orbsvcs/orbsvcs/Event/RT_Task.cpp new file mode 100644 index 00000000000..07e23495662 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/RT_Task.cpp @@ -0,0 +1,408 @@ +// $Id$ + +#include "ace/Sched_Params.h" +#include "orbsvcs/Scheduler_Factory.h" +#include "RT_Task.h" +#include "Debug_Macros.h" +#include "Event_Channel.h" +#include "Memory_Pools.h" + +#if !defined (__ACE_INLINE__) +#include "RT_Task.i" +#endif /* __ACE_INLINE__ */ + +class ACE_RT_Task_Shutdown : public ACE_RT_Task_Command +// = TITLE +// Flush Queue Command. +// +// = DESCRIPTION +// This command object will call close on task_. This is used by +// single-threaded tasks to flush any queued messages. +{ +public: + ACE_RT_Task_Shutdown (ACE_ES_TASK *task) + : task_ (task) {} + + virtual int execute (u_long &command_action); + + ACE_ES_TASK *task_; +}; + +int +ACE_RT_Task_Shutdown::execute (u_long &command_action) +{ + ACE_UNUSED_ARG (command_action); + + if (task_ == 0) + return 1; + else + { + task_->close (0); + return 0; + } +} + +// ************************************************************ +// ************************************************************ + +ACE_RT_Task::ACE_RT_Task (void) + : closed_ (0) +{ +} + +ACE_RT_Task::~ACE_RT_Task (void) +{ + msg_queue_->deactivate (); +} + +int +ACE_RT_Task::svc (void) +{ + int done = 0; + + ACE_hthread_t self; + ACE_OS::thr_self (self); + + int priority; + if (ACE_OS::thr_getprio (self, priority) == 0) + ACE_DEBUG ((LM_DEBUG, "(%t) new thread priority = %d.\n", priority)); + + // Initialize channel thread-specific data. + ACE_ES_Memory_Pools::thr_init (); + + done = this->svc_hook (priority); + + while (!done) + { + done = this->svc_one (); + } + + ACE_DEBUG ((LM_DEBUG, "(%t) thread exiting.\n")); + return 0; +} + +int +ACE_RT_Task::svc_hook (RtecScheduler::OS_Priority) +{ + return 0; +} + +int +ACE_RT_Task::svc_one (void) +{ + // Dequeue the command. + ACE_Message_Block *mb; + + if (this->getq (mb) == -1) + { + if (ACE_OS::last_error () == ESHUTDOWN) + return 1; + else + // We'll continue in spite of this error. + ACE_ERROR ((LM_ERROR, "%p (%t) getq error.\n", "ACE_RT_Task::svc_one")); + } + + // Execute the command. + ACE_RT_Task_Command *command = (ACE_RT_Task_Command *) mb; + + int result; + u_long command_action = ACE_RT_Task_Command::RELEASE; + + ACE_TIMEPROBE (" RT_Task - start execute"); + + // @@ Put exception handling around this! + result = command->execute (command_action); + + ACE_TIMEPROBE (" RT_Task - end execute"); + + switch (command_action) + { + case ACE_RT_Task_Command::RELEASE: + // Free the message block. + if (ACE_RT_Task_Command::release (command) != 0) + ACE_ERROR ((LM_ERROR, "ACE_RT_Task::svc_one: " + "ACE_RT_Task_Command::release returned != 0!\n")); + break; + + case ACE_RT_Task_Command::UNGETQ: + this->ungetq (command); + break; + } + + return result; +} + +// A thread has exited. +int +ACE_RT_Task::close (u_long) +{ + // If we're the last one out, call threads_closed. + if (thr_count_ == 0) + this->threads_closed (); + + return 0; +} + +// All threads have exited. +void +ACE_RT_Task::threads_closed (void) +{ +} + +int +ACE_RT_Task::open_task (const char* name) +{ + const char *tempname = name; + char tempbuffer[64]; + if (tempname == 0) + { + ACE_OS::sprintf (tempbuffer, "unnamed task %d", (long) this); + tempname = tempbuffer; + } + + TAO_TRY + { + rt_info_ = + ACE_Scheduler_Factory::server()->create (tempname, + TAO_TRY_ENV); + TAO_CHECK_ENV; + // @@ TODO: We do no initialization of the new rt_info, the + // caller does, this is (IMnsHO) very error prone. + } + TAO_CATCH (RtecScheduler::DUPLICATE_NAME, dn_ex) + { + // @@ TODO: Its already registered, IMHO this should at least + // report a warning, but I'll stick to the previous code. + // ACE_ERROR_RETURN ((LM_WARNING, + // "RT_Info for %s was already createn", + // tempname), 0); + return 0; + } + TAO_ENDTRY; + + return 0; +} + +int +ACE_RT_Task::try_put (ACE_Message_Block *mb) +{ + if (!closed_) + { + return this->msg_queue ()->enqueue_prio (mb); + } + else + { + errno = EPIPE; + return -1; + } +} + +// The point of this method is to spawn or shutdown threads depending +// on any differences between the task's RT_Info::threads_ and how +// many threads are actually running. +int +ACE_RT_Task::synch_threads (size_t threads) +{ + if (threads > this->thr_count ()) + // Add threads. + { + RtecScheduler::OS_Priority thread_priority; + RtecScheduler::Sub_Priority subpriority; + RtecScheduler::Preemption_Priority preemption_priority; + + TAO_TRY + { + // @@ TODO handle exceptions + ACE_TIMEPROBE (" synch_threads - priority requested"); + ACE_Scheduler_Factory::server ()->priority + (rt_info_, + thread_priority, + subpriority, + preemption_priority, TAO_TRY_ENV); + TAO_CHECK_ENV; + ACE_TIMEPROBE (" synch_threads - priority obtained"); + + ACE_DEBUG ((LM_DEBUG, "(%t) spawning %d threads at os thread" + " priority %d.\n", + threads - this->thr_count (), + thread_priority)); + + // This is here so that the constructor does not call it. The + // ORB has an instance of one of these. + this->thr_mgr (ACE_Task_Manager::instance ()->ThrMgr ()); + + // Add the difference. + // First try real-time scheduling with specified priority. + long flags = THR_BOUND | THR_SCHED_FIFO; + if (this->activate (flags, + threads - this->thr_count (), + 1, // Force it to spawn more threads + thread_priority) == -1) + { + // That didn't work. Try default scheduling class with + // the requested priority. + flags = THR_BOUND; + if (this->activate (flags, + threads - this->thr_count (), + 1, // Force it to spawn more threads + thread_priority) == -1) + { + // That didn't work. Finally, try default + // scheduling class with minimum priority. + + // On Linux, for example, only the superuser can set + // the policy to other than ACE_SCHED_OTHER. But + // with ACE_SCHED_OTHER, there is only one thread + // priority value, for example, 0. So, let the + // superuser run an interesting test, but for other + // users use the minimum ACE_SCHED_OTHER thread + // priority. + + RtecScheduler::OS_Priority fallback_priority = + ACE_Sched_Params::priority_min (ACE_SCHED_OTHER, + ACE_SCOPE_THREAD); + + ACE_DEBUG ((LM_DEBUG, "(%t) task activation at priority %d " + "with flags 0x%X failed; retry at priority %d " + "with flags 0x%X\n", + thread_priority, + flags, + fallback_priority, + THR_BOUND)); + + flags = THR_BOUND; + + if (this->activate (flags, + threads - this->thr_count (), + 1, // Force it to spawn more threads + fallback_priority) == -1) + { + ACE_DEBUG ((LM_ERROR, + "(%t) thread spawn at priority %d FAILED " + "(errno is %d%p)!!!!\n", + fallback_priority, + errno, + "")); + } + } + } + } + TAO_CATCHANY + { + ACE_ERROR_RETURN ((LM_ERROR, "priority failed\n"), -1); + } + TAO_ENDTRY; + + } + else + // Remove threads. + { + // kill_threads has to be off the stack in case the last thread + // deletes this RT_Task. + int kill_threads = this->thr_count () - threads; + + for (int x = kill_threads ; x > 0; x--) + { + // Create a new shutdown command with a task pointer of 0. + ACE_RT_Task_Shutdown *te = new ACE_RT_Task_Shutdown (0); + + if (te == 0) + return -1; + + ACE_DEBUG ((LM_DEBUG, "(%t) enqueueing thread exit.\n")); + if (this->putq (te) == -1) + { + ACE_ERROR ((LM_ERROR, "%p putq failed.\n", + "ACE_RT_Task::synch_threads")); + if (ACE_RT_Task_Shutdown::release (te) != 0) + ACE_ERROR ((LM_ERROR, "ACE_RT_Task::synch_threads: " + "ACE_RT_Task_Shutdown::release returned != 0!\n")); + return -1; + } + } + } + + return 0; +} + + +// If we are not active, we will flush the queue and then call +// this->close. Otherwise, we will send shutdown messages to each +// thread. ~ACE_Task_Exit will call this->close when each thread +// exits. +int +ACE_RT_Task::shutdown_task (void) +{ + // Be sure to only execute this once, and only if we're active. + if (closed_) + return 0; + + // This will keep any messages from entering the queue. + closed_ = 1; + + if (thr_count_ > 0) + return this->synch_threads (0); + else + { + // Create a new flush queue command. We're passive, so pass in + // a reference to the task for which close will be called. + ACE_RT_Task_Shutdown *fq = new ACE_RT_Task_Shutdown (this); + + if (fq == 0) + { + ACE_ERROR ((LM_ERROR, "%p.\n", "ACE_RT_Task::shutdown_threads")); + return -1; + } + + // Enqueue the command. + ACE_DEBUG ((LM_DEBUG, "(%t) enqueueing task shutdown.\n")); + if (this->putq (fq) == -1) + { + ACE_ERROR ((LM_ERROR, "%p putq failed.\n", + "ACE_RT_Task::shutdown_task")); + if (ACE_RT_Task_Shutdown::release (fq) != 0) + ACE_ERROR ((LM_ERROR, "ACE_RT_Task::shutdown_task: " + "ACE_RT_Task_Shutdown::release returned != 0!\n")); + return -1; + } + } + + return 0; +} + +// ************************************************************ + +ACE_RT_Thread_Manager::ACE_RT_Thread_Manager (void) + : flags_ (0) +{ +} + +void +ACE_RT_Thread_Manager::suspend_spawns (void) +{ + flags_ |= THR_SUSPENDED; +} + +void +ACE_RT_Thread_Manager::unsuspend_spawns (void) +{ + flags_ = 0; + this->resume_all (); +} + +int +ACE_RT_Thread_Manager::spawn_i (ACE_THR_FUNC func, + void *args, + long flags, + ACE_thread_t *t_id, + ACE_hthread_t *t_handle, + long priority, + int grp_id, + void *stack, + size_t stack_size, + ACE_Task_Base *task) +{ + flags |= flags_; + return ACE_Thread_Manager::spawn_i (func, args, flags, t_id, t_handle, + priority, grp_id, stack, stack_size, task); +} diff --git a/TAO/orbsvcs/orbsvcs/Event/RT_Task.h b/TAO/orbsvcs/orbsvcs/Event/RT_Task.h new file mode 100644 index 00000000000..1b09ee4ac7a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/RT_Task.h @@ -0,0 +1,179 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// RT_Task +// +// = AUTHOR +// Tim Harrison (harrison@cs.wustl.edu) +// +// = DESCRIPTION +// Wrapper on top of ACE Task that integrates an Active Object with +// the Event Service. +// +// ============================================================================ + +#ifndef ACE_RT_TASK_H +#define ACE_RT_TASK_H + +#include "ace/Task.h" + +#include "orbsvcs/RtecSchedulerC.h" + +class ACE_RT_Thread_Manager : public ACE_Thread_Manager +// = TITLE +// +// = DESCRIPTION +{ +public: + ACE_RT_Thread_Manager (void); + // Default construction. + + void suspend_spawns (void); + // Any threads spawned will be suspended until unsuspend_spawns is + // called. + + void unsuspend_spawns (void); + // Resumes all threads. + +protected: + virtual int spawn_i (ACE_THR_FUNC func, + void *args, + long flags, + ACE_thread_t * = 0, + ACE_hthread_t *t_handle = 0, + long priority = 0, + int grp_id = -1, + void *stack = 0, + size_t stack_size = 0, + ACE_Task_Base *task = 0); + + int flags_; +}; + +// ************************************************************ + +class ACE_RT_Task_Command : public ACE_Message_Block +// = TITLE +// +// = DESCRIPTION +{ +public: + virtual ~ACE_RT_Task_Command (void) {} + // Guarantees that derived destructors get called. + + enum { RELEASE, UNGETQ }; + + virtual int execute (u_long &command_action) = 0; + // Execute the command. Returning 1 will make the calling thread + // exit. Returning 0 will allow the thread to continue dispatching + // commands. If <command_action> returns as RELEASE, the command + // will be released. If <command_action> == UNGETQ, then the + // command will be requeued and dispatched again. +}; + +// ************************************************************ + +// In Synch_T.h: +// #define ACE_MT_SYNCH ACE_Thread_Mutex,ACE_Condition_Thread_Mutex + +typedef ACE_Task<ACE_MT_SYNCH> ACE_ES_TASK; +typedef ACE_Message_Queue<ACE_MT_SYNCH> ACE_ES_QUEUE; + +class ACE_RT_Task : public ACE_ES_TASK +// = TITLE +// ACE Real-Time Task +// +// = DESCRIPTION +// Real-Time Active Object that integrates with a global scheduler +// and Event Service. For now, none of the management methods are +// synchronized. If it turns out that multiple threads will be +// calling the management methods, then we can add +// synchronization. For the most part, RT_Task threads should be +// dequeueing commands from the message queue. Only one thread +// should be calling any management methods. +{ + friend ACE_RT_Thread_Manager; +public: + ACE_RT_Task (void); + // Default construction. + + ~ACE_RT_Task (void); + // Deactivates the queue. + + // = Management methods. + + int open_task (const char* name = 0); + // <name> is used to look up our qos info from the scheduler. If + // <name> == 0, then we create a "unique" name and ask the scheduler + // for a new qos structure. If we find an existing qos structure, + // calls this->synch_threads and returns 1. If a qos structure is not + // found, but created returns 0 and does not call synch_threads. + // Returns -1 on failure. + + int try_put (ACE_Message_Block *mb); + // Enqueue a request. Returns 0 on success, -1 on failure. If the + // task is shutdown, -1 is returned with errno == EPIPE. + + int shutdown_task (void); + // If active, shutdown all running thread. Since this is + // accomplished via queued shutdown messages, this has the effect of + // flushing the queue. Once all threads exit, threads_closed will + // be called. If this is a passive object, then the queue will be + // flushed and threads_closed will be called. + + int synch_threads (size_t threads); + // Compare <threads> with what is actually running. If there are + // any differences, update this RT_Task. This may involve spawning + // more threads or changing thread priorities, etc. This can be + // used to close all threads by sending a 0. + + RtecScheduler::handle_t rt_info (void); + // QOS accessor. The behavior of the task can be changed by setting + // this and then calling this->synch_threads. + + virtual void threads_closed (void); + // Called when every thread has exited. This hook allows + // applications to specify semantics when all threads have exited. + // For instance, the Dispatching Module uses this hook to delete + // itself when an application is shutting down. + + virtual int svc_hook (RtecScheduler::OS_Priority priority); + // This is called the first time the thread is spawned. <priority> + // is the priority of the current thread. If this returns != 1 + // (e.g., 0), the event loop will execute (calling this->svc_one). + // If this returns 1, the event loop will not execute. + + virtual int svc_one (void); + // Call this->getq once and execute the command. Returns the result + // of command->execute (). + +protected: + RtecScheduler::handle_t rt_info_; + // Scheduling characteristics of this active object. + + int closed_; + // Set to 1 when this->shutdown_threads or this->close_queue is + // called. Keeps us from enqueuing more that one shutdown message. + + virtual int svc (void); + // Run by each thread spawned. Each thread dequeues + // ACE_RT_Task_Commands and executes them. + + virtual int close (u_long flags = 0); + // Called each time a thread exits. + + void close_all_threads (void); + // Enqueues shutdown message for every thread in the task. +}; + +#if defined (__ACE_INLINE__) +#include "RT_Task.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_RT_TASK_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/RT_Task.i b/TAO/orbsvcs/orbsvcs/Event/RT_Task.i new file mode 100644 index 00000000000..b6b21d50494 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/RT_Task.i @@ -0,0 +1,8 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE RtecScheduler::handle_t +ACE_RT_Task::rt_info (void) +{ + return rt_info_; +} diff --git a/TAO/orbsvcs/orbsvcs/Event/ReactorTask.cpp b/TAO/orbsvcs/orbsvcs/Event/ReactorTask.cpp new file mode 100644 index 00000000000..389ade8491b --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/ReactorTask.cpp @@ -0,0 +1,113 @@ +// +// $Id$ +// +#include "ace/High_Res_Timer.h" +#include "tao/Timeprobe.h" +#include "orbsvcs/Scheduler_Factory.h" + +#include "ReactorTask.h" + +ACE_ES_Reactor_Task::ACE_ES_Reactor_Task() : + // reactor_ (0, &timer_queue_), + done_ (0) +{ + // Change the timer mechanism used by the reactor and the timer + // queue. +#if defined (VXWORKS) + timer_queue_.gettimeofday (ACE_OS::gettimeofday); +#else + timer_queue_.gettimeofday (ACE_High_Res_Timer::gettimeofday); +#endif /* VXWORKS */ +} + +ACE_ES_Reactor_Task::~ACE_ES_Reactor_Task (void) +{ +} + +int +ACE_ES_Reactor_Task::svc_hook(RtecScheduler::OS_Priority) +{ + // Make ourselves owner of the reactor. + reactor_.owner (ACE_Thread::self()); + return 0; +} + +int +ACE_ES_Reactor_Task::open_reactor (RtecScheduler::Period &period) +{ + // Create a name for ourself using the priority. + char temp[64]; + ACE_OS::sprintf (temp, "Reactor_Task-%u", period); + + // Open the task. This will query the scheduler for our qos + // structure. + int result = this->open_task (temp); + + switch (result) + { + case -1: + // Error. + ACE_ERROR ((LM_ERROR, "(%t) Scheduler could not find operation %s.\n", + temp)); + return -1; + + case 0: + // @@ TODO handle exceptions + { + TAO_TRY + { + ACE_Scheduler_Factory::server()->set(rt_info_, + ORBSVCS_Time::zero, + ORBSVCS_Time::zero, + ORBSVCS_Time::zero, + period, + RtecScheduler::VERY_LOW, + ORBSVCS_Time::zero, + 1, TAO_TRY_ENV); + TAO_CHECK_ENV; + } + TAO_CATCHANY + { + ACE_ERROR_RETURN ((LM_ERROR, "set failed\n"), -1); + } + TAO_ENDTRY; + } + break; + + case 1: + // Found. + break; + } + + return this->synch_threads (1); +} + +int ACE_ES_Reactor_Task::svc_one() +{ + ACE_TIMEPROBE (" Reactor_Task - waiting for events"); + if (reactor_.handle_events() == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p.\n", "ACE_ES_Reactor_Task::svc")); + ACE_TIMEPROBE (" Reactor_Task - events handled"); + + if (done_) + ACE_DEBUG ((LM_DEBUG, "(%t) Timer Task is done.\n")); + + return done_; +} + +void ACE_ES_Reactor_Task::threads_closed() +{ + delete this; +} + +void ACE_ES_Reactor_Task::shutdown_task() +{ + done_ = 1; + reactor_.notify(); +} + +ACE_ES_Reactor_Task::Reactor& +ACE_ES_Reactor_Task::get_reactor() +{ + return reactor_; +} diff --git a/TAO/orbsvcs/orbsvcs/Event/ReactorTask.h b/TAO/orbsvcs/orbsvcs/Event/ReactorTask.h new file mode 100644 index 00000000000..973d6f82f97 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/ReactorTask.h @@ -0,0 +1,76 @@ +// $Id$ + +#if !defined ACE_ReactorTask_H +#define ACE_ReactorTask_H + +// BBM, moved this here from UPSingleProcessorOrb.h +//## begin module.includes preserve=yes +#include "Fast_Reactor.h" +#if defined (ACE_OLD_STYLE_REACTOR) +# define ACE_ORB_REACTOR ACE_ES_Fast_Reactor +#endif /* ACE_OLD_STYLE_REACTOR */ +//## end module.includes + +// Added these. +#include "ace/Timer_Heap.h" +#include "ace/Timer_List.h" + +#include "Local_ESTypes.h" +#include "RT_Task.h" + +class ACE_ES_Reactor_Task : public ACE_RT_Task +// = TITLE +// Event Service Timer Task +// +// = DESCRIPTION +// An active object that dispatches timers from its own ReactorEx. +{ +public: + // BBM, added this. +#if defined (ACE_OLD_STYLE_REACTOR) + typedef ACE_ORB_REACTOR Reactor; +#else + typedef ACE_Reactor Reactor; +#endif /* ACE_OLD_STYLE_REACTOR */ + + ACE_ES_Reactor_Task(); + // Default construction. + + ~ACE_ES_Reactor_Task(); + // Destruction. + + virtual int svc_hook(RtecScheduler::OS_Priority); + // Assume ownership of the reactor_. + + int open_reactor (RtecScheduler::Period &period); + // This is a hack for now. + + virtual int svc_one(); + // Calls reactor_.handle_events until done_ is set. + + void shutdown_task(); + // Sets done_ and notifies the reactor_. + + Reactor &get_reactor(); + // ReactorEx accessor. + + virtual void threads_closed(); + // Deletes this. + +private: + ACE_Timer_List timer_queue_; + // The timer storage mechanism used by reactor_. + +#if !defined (ACE_OLD_STYLE_REACTOR) + ACE_ES_Fast_Reactor fast_reactor_; + // The timer dispatch mechanism. +#endif /* ! ACE_OLD_STYLE_REACTOR */ + + Reactor reactor_; + // "Public" handle to fast_reactor_. + + sig_atomic_t done_; + // When set, end the event loop. +}; + +#endif /* ACE_ReactorTask_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Task_Manager.cpp b/TAO/orbsvcs/orbsvcs/Event/Task_Manager.cpp new file mode 100644 index 00000000000..82bf3c6471c --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Task_Manager.cpp @@ -0,0 +1,43 @@ +// $Id$ + +#include "Task_Manager.h" +#include "ReactorTask.h" + +#if ! defined (__ACE_INLINE__) +#include "Task_Manager.i" +#endif /* __ACE_INLINE__ */ + +ACE_Task_Manager::ACE_Task_Manager() +{ + for (int x=0; x < ACE_Scheduler_MAX_PRIORITIES; x++) + { + reactorTasks[x] = 0; + } +} + +void ACE_Task_Manager::initialize() +{ + for (int x=0; x < ACE_Scheduler_MAX_PRIORITIES; x++) + { + // @@ Apparently Period is measured in a different unit that the + // time, beats me. + ACE_hrtime_t nanosecs; + ORBSVCS_Time::TimeT_to_hrtime (nanosecs, ACE_Scheduler_Rates[x]); + + RtecScheduler::Period period = nanosecs; + reactorTasks[x] = new ReactorTask; + + if (reactorTasks[x] == 0 || + reactorTasks[x]->open_reactor (period) == -1) + { + ACE_ERROR ((LM_ERROR, "%p.\n", "ACE_ORB::initialize_reactors")); + return; + } + } +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Singleton<ACE_Task_Manager,ACE_SYNCH_MUTEX>; +#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Singleton<ACE_Task_Manager,ACE_SYNCH_MUTEX> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Task_Manager.h b/TAO/orbsvcs/orbsvcs/Event/Task_Manager.h new file mode 100644 index 00000000000..8fbd96478d1 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Task_Manager.h @@ -0,0 +1,56 @@ +/* -*- C++ -*- */ +// +// $Id$ +// + +#if !defined(TASK_MANAGER_H) +#define TASK_MANAGER_H + +#include "ace/ACE.h" +#include "ace/Singleton.h" +#include "orbsvcs/Event_Service_Constants.h" +#include "RT_Task.h" + +class ACE_ES_Reactor_Task; + +class ACE_Task_Manager +// = TITLE +// Singleton class for the pool of ACE_ReactorTask. +// +// = DESCRIPTION +// The EventChannel uses a pool of ACE_ReactorTask to handle the +// dispatching of Events. In real-time multi-threaded enviroments +// this maps to a different thread per priority. +// This class offers a centralized access point to those tasks and +// some related services. +// +{ +public: + typedef ACE_ES_Reactor_Task ReactorTask; + + static ACE_Task_Manager* instance(); + // Returns the singleton. + + ReactorTask* GetReactorTask(RtecScheduler::OS_Priority priority); + // Obtain the ReactorTask for the given priority. + // The Task must have been created already. + + ACE_RT_Thread_Manager* ThrMgr(); + // Returns a global ThreadManager for the Task pool. + +private: + friend class ACE_Singleton<ACE_Task_Manager,ACE_SYNCH_MUTEX>; + ACE_Task_Manager(); + + void initialize(); + +private: + ReactorTask *reactorTasks[ACE_Scheduler_MAX_PRIORITIES]; + ACE_RT_Thread_Manager thr_mgr; +}; + +#if defined (__ACE_INLINE__) +#include "Task_Manager.i" +#endif /* __ACE_INLINE__ */ + +#endif /* TASK_MANAGER_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Task_Manager.i b/TAO/orbsvcs/orbsvcs/Event/Task_Manager.i new file mode 100644 index 00000000000..35abcc0268c --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/Task_Manager.i @@ -0,0 +1,30 @@ +// +// $Id$ +// + +ACE_INLINE ACE_Task_Manager::ReactorTask* +ACE_Task_Manager::GetReactorTask(RtecScheduler::OS_Priority priority) +{ + if (reactorTasks[priority] == 0) + { + initialize(); + //ACE_ERROR_RETURN ((LM_ERROR, + //"%p no reactor task for priority %d.\n", + //"ACE_Task_Manager::GetReactor", + //priority), 0); + } + + return reactorTasks[priority]; +} + +ACE_INLINE ACE_RT_Thread_Manager* ACE_Task_Manager::ThrMgr() +{ + return &thr_mgr; +} + +ACE_INLINE ACE_Task_Manager* ACE_Task_Manager::instance() +{ + return ACE_Singleton<ACE_Task_Manager,ACE_SYNCH_MUTEX>::instance(); +} + + diff --git a/TAO/orbsvcs/orbsvcs/Makefile b/TAO/orbsvcs/orbsvcs/Makefile index a37129cbb79..9b690094602 100644 --- a/TAO/orbsvcs/orbsvcs/Makefile +++ b/TAO/orbsvcs/orbsvcs/Makefile @@ -47,12 +47,36 @@ FILES= $(IDL_FILES) \ Runtime_Scheduler \ Scheduler_Utilities \ Time_Utilities \ + \ + Naming/CosNaming_i \ + Naming/Entries \ + \ + Event/BCU \ + Event/CORBA_Utils_T \ + Event/Dispatching_Modules \ + Event/Event_Channel \ + Event/Local_ESTypes \ + Event/Memory_Pools \ + Event/RT_Task \ + Event/ReactorTask \ + Event/Task_Manager \ + \ + Sched/Scheduling_Service \ + Sched/Config_Scheduler \ + Sched/Scheduler \ + Sched/Scheduler_Generic \ + \ tmplinst +VPATH=.:Naming:Event:Sched:AV:Property + # Compile using av=1 to compile the AVStreams stuff. ifdef av ## Add the implementation files -FILES += AVStreams_i CosPropertyService_i CosProperty_Hash +FILES += \ + AV/AVStreams_i \ + Property/CosPropertyService_i \ + Property/CosProperty_Hash endif @@ -2244,6 +2268,720 @@ realclean: clean $(TAO_ROOT)/tao/connect.i \ $(TAO_ROOT)/tao/singletons.h \ orbsvcs_export.h LoggerC.i LoggerS.i +.obj/CosPropertyServiceS.o .obj/CosPropertyServiceS.so .shobj/CosPropertyServiceS.o .shobj/CosPropertyServiceS.so: CosPropertyServiceS.cpp CosPropertyServiceS.h \ + CosPropertyServiceC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + orbsvcs_export.h CosPropertyServiceC.i CosPropertyServiceS.i +.obj/CosPropertyServiceC.o .obj/CosPropertyServiceC.so .shobj/CosPropertyServiceC.o .shobj/CosPropertyServiceC.so: CosPropertyServiceC.cpp CosPropertyServiceC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + orbsvcs_export.h CosPropertyServiceC.i CosPropertyServiceS.h \ + CosPropertyServiceS.i +.obj/AVStreamsS.o .obj/AVStreamsS.so .shobj/AVStreamsS.o .shobj/AVStreamsS.so: AVStreamsS.cpp AVStreamsS.h CosPropertyServiceS.h \ + CosPropertyServiceC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + orbsvcs_export.h CosPropertyServiceC.i CosPropertyServiceS.i \ + AVStreamsC.h AVStreamsC.i AVStreamsS.i +.obj/AVStreamsC.o .obj/AVStreamsC.so .shobj/AVStreamsC.o .shobj/AVStreamsC.so: AVStreamsC.cpp AVStreamsC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + orbsvcs_export.h CosPropertyServiceC.h CosPropertyServiceC.i \ + AVStreamsC.i AVStreamsS.h CosPropertyServiceS.h CosPropertyServiceS.i \ + AVStreamsS.i .obj/Event_Utilities.o .obj/Event_Utilities.so .shobj/Event_Utilities.o .shobj/Event_Utilities.so: Event_Utilities.cpp \ $(TAO_ROOT)/orbsvcs/orbsvcs/Event_Utilities.h \ $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminC.h \ @@ -3178,6 +3916,2834 @@ realclean: clean $(TAO_ROOT)/orbsvcs/orbsvcs/orbsvcs_export.h \ $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.i \ $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.i +.obj/CosNaming_i.o .obj/CosNaming_i.so .shobj/CosNaming_i.o .shobj/CosNaming_i.so: Naming/CosNaming_i.cpp Naming/CosNaming_i.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/orbsvcs_export.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingS.i \ + Naming/Entries.h +.obj/Entries.o .obj/Entries.so .shobj/Entries.o .shobj/Entries.so: Naming/Entries.cpp Naming/Entries.h \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/orbsvcs_export.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.i +.obj/BCU.o .obj/BCU.so .shobj/BCU.o .shobj/BCU.so: Event/BCU.cpp \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + Event/BCU.h +.obj/CORBA_Utils_T.o .obj/CORBA_Utils_T.so .shobj/CORBA_Utils_T.o .shobj/CORBA_Utils_T.so: Event/CORBA_Utils_T.cpp \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + Event/CORBA_Utils_T.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + Event/CORBA_Utils_T.i +.obj/Dispatching_Modules.o .obj/Dispatching_Modules.so .shobj/Dispatching_Modules.o .shobj/Dispatching_Modules.so: Event/Dispatching_Modules.cpp \ + $(ACE_ROOT)/ace/Sched_Params.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Sched_Params.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Scheduler_Factory.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/orbsvcs_export.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Scheduler_Factory.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.i \ + Event/Memory_Pools.h Event/Event_Channel.h \ + $(TAO_ROOT)/tao/Timeprobe.h \ + $(TAO_ROOT)/tao/Timeprobe.i \ + Event/Local_ESTypes.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Event_Service_Constants.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminS.i \ + Event/Local_ESTypes.i Event/CORBA_Utils_T.h Event/CORBA_Utils_T.i \ + Event/Task_Manager.h Event/RT_Task.h Event/RT_Task.i \ + Event/Task_Manager.i Event/ReactorTask.h Event/Fast_Reactor.h \ + $(ACE_ROOT)/ace/Select_Reactor.h \ + $(ACE_ROOT)/ace/Token.h \ + $(ACE_ROOT)/ace/Token.i \ + $(ACE_ROOT)/ace/Pipe.h \ + $(ACE_ROOT)/ace/Pipe.i \ + $(ACE_ROOT)/ace/Select_Reactor.i \ + $(ACE_ROOT)/ace/Timer_Heap.h \ + $(ACE_ROOT)/ace/Timer_Heap_T.h \ + $(ACE_ROOT)/ace/Timer_List.h \ + $(ACE_ROOT)/ace/Timer_List_T.h \ + Event/Event_Channel.i Event/Dispatching_Modules.h \ + Event/Dispatching_Modules.i Event/Memory_Pools.i +.obj/Event_Channel.o .obj/Event_Channel.so .shobj/Event_Channel.o .shobj/Event_Channel.so: Event/Event_Channel.cpp \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Scheduler_Factory.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/orbsvcs_export.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Scheduler_Factory.i \ + Event/Dispatching_Modules.h \ + $(TAO_ROOT)/tao/Timeprobe.h \ + $(TAO_ROOT)/tao/Timeprobe.i \ + Event/ReactorTask.h Event/Fast_Reactor.h \ + $(ACE_ROOT)/ace/Select_Reactor.h \ + $(ACE_ROOT)/ace/Token.h \ + $(ACE_ROOT)/ace/Token.i \ + $(ACE_ROOT)/ace/Pipe.h \ + $(ACE_ROOT)/ace/Pipe.i \ + $(ACE_ROOT)/ace/Select_Reactor.i \ + $(ACE_ROOT)/ace/Timer_Heap.h \ + $(ACE_ROOT)/ace/Timer_Heap_T.h \ + $(ACE_ROOT)/ace/Timer_List.h \ + $(ACE_ROOT)/ace/Timer_List_T.h \ + Event/Local_ESTypes.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Event_Service_Constants.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminS.i \ + Event/Local_ESTypes.i Event/RT_Task.h Event/RT_Task.i \ + Event/Event_Channel.h Event/CORBA_Utils_T.h Event/CORBA_Utils_T.i \ + Event/Task_Manager.h Event/Task_Manager.i Event/Event_Channel.i \ + Event/Dispatching_Modules.i Event/Memory_Pools.h Event/Memory_Pools.i +.obj/Local_ESTypes.o .obj/Local_ESTypes.so .shobj/Local_ESTypes.o .shobj/Local_ESTypes.so: Event/Local_ESTypes.cpp Event/Local_ESTypes.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Event_Service_Constants.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/orbsvcs_export.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminS.i \ + Event/Local_ESTypes.i +.obj/Memory_Pools.o .obj/Memory_Pools.so .shobj/Memory_Pools.o .shobj/Memory_Pools.so: Event/Memory_Pools.cpp Event/Memory_Pools.h \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + Event/Event_Channel.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(TAO_ROOT)/tao/Timeprobe.h \ + $(TAO_ROOT)/tao/Timeprobe.i \ + Event/Local_ESTypes.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Event_Service_Constants.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/orbsvcs_export.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminS.i \ + Event/Local_ESTypes.i Event/CORBA_Utils_T.h Event/CORBA_Utils_T.i \ + Event/Task_Manager.h Event/RT_Task.h Event/RT_Task.i \ + Event/Task_Manager.i Event/ReactorTask.h Event/Fast_Reactor.h \ + $(ACE_ROOT)/ace/Select_Reactor.h \ + $(ACE_ROOT)/ace/Token.h \ + $(ACE_ROOT)/ace/Token.i \ + $(ACE_ROOT)/ace/Pipe.h \ + $(ACE_ROOT)/ace/Pipe.i \ + $(ACE_ROOT)/ace/Select_Reactor.i \ + $(ACE_ROOT)/ace/Timer_Heap.h \ + $(ACE_ROOT)/ace/Timer_Heap_T.h \ + $(ACE_ROOT)/ace/Timer_List.h \ + $(ACE_ROOT)/ace/Timer_List_T.h \ + Event/Event_Channel.i Event/Dispatching_Modules.h \ + Event/Dispatching_Modules.i Event/Memory_Pools.i +.obj/RT_Task.o .obj/RT_Task.so .shobj/RT_Task.o .shobj/RT_Task.so: Event/RT_Task.cpp \ + $(ACE_ROOT)/ace/Sched_Params.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Sched_Params.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Scheduler_Factory.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/orbsvcs_export.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Scheduler_Factory.i \ + Event/RT_Task.h Event/RT_Task.i Event/Debug_Macros.h \ + Event/Event_Channel.h \ + $(TAO_ROOT)/tao/Timeprobe.h \ + $(TAO_ROOT)/tao/Timeprobe.i \ + Event/Local_ESTypes.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Event_Service_Constants.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminS.i \ + Event/Local_ESTypes.i Event/CORBA_Utils_T.h Event/CORBA_Utils_T.i \ + Event/Task_Manager.h Event/Task_Manager.i Event/ReactorTask.h \ + Event/Fast_Reactor.h \ + $(ACE_ROOT)/ace/Select_Reactor.h \ + $(ACE_ROOT)/ace/Token.h \ + $(ACE_ROOT)/ace/Token.i \ + $(ACE_ROOT)/ace/Pipe.h \ + $(ACE_ROOT)/ace/Pipe.i \ + $(ACE_ROOT)/ace/Select_Reactor.i \ + $(ACE_ROOT)/ace/Timer_Heap.h \ + $(ACE_ROOT)/ace/Timer_Heap_T.h \ + $(ACE_ROOT)/ace/Timer_List.h \ + $(ACE_ROOT)/ace/Timer_List_T.h \ + Event/Event_Channel.i Event/Memory_Pools.h \ + Event/Dispatching_Modules.h Event/Dispatching_Modules.i \ + Event/Memory_Pools.i +.obj/ReactorTask.o .obj/ReactorTask.so .shobj/ReactorTask.o .shobj/ReactorTask.so: Event/ReactorTask.cpp \ + $(ACE_ROOT)/ace/High_Res_Timer.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/High_Res_Timer.i \ + $(TAO_ROOT)/tao/Timeprobe.h \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(TAO_ROOT)/tao/Timeprobe.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Scheduler_Factory.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/orbsvcs_export.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Scheduler_Factory.i \ + Event/ReactorTask.h Event/Fast_Reactor.h \ + $(ACE_ROOT)/ace/Select_Reactor.h \ + $(ACE_ROOT)/ace/Token.h \ + $(ACE_ROOT)/ace/Token.i \ + $(ACE_ROOT)/ace/Pipe.h \ + $(ACE_ROOT)/ace/Pipe.i \ + $(ACE_ROOT)/ace/Select_Reactor.i \ + $(ACE_ROOT)/ace/Timer_Heap.h \ + $(ACE_ROOT)/ace/Timer_Heap_T.h \ + $(ACE_ROOT)/ace/Timer_List.h \ + $(ACE_ROOT)/ace/Timer_List_T.h \ + Event/Local_ESTypes.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Event_Service_Constants.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminS.i \ + Event/Local_ESTypes.i Event/RT_Task.h Event/RT_Task.i +.obj/Task_Manager.o .obj/Task_Manager.so .shobj/Task_Manager.o .shobj/Task_Manager.so: Event/Task_Manager.cpp Event/Task_Manager.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Singleton.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Event_Service_Constants.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/orbsvcs_export.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.i \ + Event/RT_Task.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.i \ + Event/RT_Task.i Event/Task_Manager.i Event/ReactorTask.h \ + Event/Fast_Reactor.h \ + $(ACE_ROOT)/ace/Select_Reactor.h \ + $(ACE_ROOT)/ace/Token.h \ + $(ACE_ROOT)/ace/Token.i \ + $(ACE_ROOT)/ace/Pipe.h \ + $(ACE_ROOT)/ace/Pipe.i \ + $(ACE_ROOT)/ace/Select_Reactor.i \ + $(ACE_ROOT)/ace/Timer_Heap.h \ + $(ACE_ROOT)/ace/Timer_Heap_T.h \ + $(ACE_ROOT)/ace/Timer_List.h \ + $(ACE_ROOT)/ace/Timer_List_T.h \ + Event/Local_ESTypes.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventCommS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminS.i \ + Event/Local_ESTypes.i +.obj/Scheduling_Service.o .obj/Scheduling_Service.so .shobj/Scheduling_Service.o .shobj/Scheduling_Service.so: Sched/Scheduling_Service.cpp \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/orbsvcs_export.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.i \ + Sched/Config_Scheduler.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Event_Service_Constants.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.i \ + Sched/Config_Scheduler.i +.obj/Config_Scheduler.o .obj/Config_Scheduler.so .shobj/Config_Scheduler.o .shobj/Config_Scheduler.so: Sched/Config_Scheduler.cpp \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/orbsvcs_export.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Scheduler_Factory.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Scheduler_Factory.i \ + Sched/Scheduler_Generic.h Sched/Scheduler.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Event_Service_Constants.h \ + Sched/Scheduler.i Sched/Scheduler_Generic.i Sched/Config_Scheduler.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerS.i \ + Sched/Config_Scheduler.i +.obj/Scheduler.o .obj/Scheduler.so .shobj/Scheduler.o .shobj/Scheduler.so: Sched/Scheduler.cpp \ + $(ACE_ROOT)/ace/Sched_Params.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Sched_Params.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/orbsvcs_export.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.i \ + Sched/Scheduler.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Event_Service_Constants.h \ + Sched/Scheduler.i +.obj/Scheduler_Generic.o .obj/Scheduler_Generic.so .shobj/Scheduler_Generic.o .shobj/Scheduler_Generic.so: Sched/Scheduler_Generic.cpp \ + $(ACE_ROOT)/ace/Sched_Params.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Sched_Params.i \ + Sched/Scheduler_Generic.h Sched/Scheduler.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/orbsvcs_export.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosTimeBaseC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Event_Service_Constants.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/Time_Utilities.i \ + Sched/Scheduler.i Sched/Scheduler_Generic.i .obj/tmplinst.o .obj/tmplinst.so .shobj/tmplinst.o .shobj/tmplinst.so: tmplinst.cpp \ $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.h \ $(TAO_ROOT)/tao/corba.h \ @@ -3365,5 +6931,553 @@ realclean: clean $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.h \ $(TAO_ROOT)/orbsvcs/orbsvcs/RtecSchedulerC.i \ $(TAO_ROOT)/orbsvcs/orbsvcs/RtecEventChannelAdminC.i +.obj/AVStreams_i.o .obj/AVStreams_i.so .shobj/AVStreams_i.o .shobj/AVStreams_i.so: AV/AVStreams_i.cpp \ + $(TAO_ROOT)/orbsvcs/orbsvcs/AV/AVStreams_i.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/AVStreamsS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosPropertyServiceS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosPropertyServiceC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/orbsvcs_export.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosPropertyServiceC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosPropertyServiceS.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/AVStreamsC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/AVStreamsC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/AVStreamsS.i +.obj/CosPropertyService_i.o .obj/CosPropertyService_i.so .shobj/CosPropertyService_i.o .shobj/CosPropertyService_i.so: Property/CosPropertyService_i.cpp \ + Property/CosPropertyService_i.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosPropertyServiceS.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosPropertyServiceC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/orbsvcs_export.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosPropertyServiceC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosPropertyServiceS.i \ + Property/CosProperty_Hash.h CosPropertyServiceS.h +.obj/CosProperty_Hash.o .obj/CosProperty_Hash.so .shobj/CosProperty_Hash.o .shobj/CosProperty_Hash.so: Property/CosProperty_Hash.cpp \ + Property/CosProperty_Hash.h \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + CosPropertyServiceS.h CosPropertyServiceC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(TAO_ROOT)/tao/compat/objbase.h \ + $(TAO_ROOT)/tao/compat/initguid.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/orb.h \ + $(TAO_ROOT)/tao/align.h \ + $(TAO_ROOT)/tao/corbacom.h \ + $(TAO_ROOT)/tao/sequence.h \ + $(TAO_ROOT)/tao/sequence.i \ + $(TAO_ROOT)/tao/sequence_T.h \ + $(TAO_ROOT)/tao/sequence_T.i \ + $(TAO_ROOT)/tao/objkeyC.h \ + $(TAO_ROOT)/tao/objkeyC.i \ + $(TAO_ROOT)/tao/any.h \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/client_factory.h \ + $(TAO_ROOT)/tao/server_factory.h \ + $(TAO_ROOT)/tao/default_client.h \ + $(TAO_ROOT)/tao/default_server.h \ + $(TAO_ROOT)/tao/strategy_T.h \ + $(TAO_ROOT)/tao/strategy_T.i \ + $(TAO_ROOT)/tao/except.h \ + $(TAO_ROOT)/tao/orbobj.h \ + $(TAO_ROOT)/tao/nvlist.h \ + $(TAO_ROOT)/tao/object.h \ + $(TAO_ROOT)/tao/principa.h \ + $(TAO_ROOT)/tao/request.h \ + $(TAO_ROOT)/tao/svrrqst.h \ + $(TAO_ROOT)/tao/typecode.h \ + $(TAO_ROOT)/tao/marshal.h \ + $(TAO_ROOT)/tao/cdr.h \ + $(TAO_ROOT)/tao/stub.h \ + $(TAO_ROOT)/tao/poa.h \ + $(TAO_ROOT)/tao/poaC.h \ + $(TAO_ROOT)/tao/poaC.i \ + $(TAO_ROOT)/tao/servant_base.h \ + $(TAO_ROOT)/tao/poaS.h \ + $(TAO_ROOT)/tao/poaS.i \ + $(TAO_ROOT)/tao/objtable.h \ + $(TAO_ROOT)/tao/connect.h \ + $(TAO_ROOT)/tao/orb_core.h \ + $(TAO_ROOT)/tao/optable.h \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/iiopobj.h \ + $(TAO_ROOT)/tao/iioporb.h \ + $(TAO_ROOT)/tao/giop.h \ + $(TAO_ROOT)/tao/orb_core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(TAO_ROOT)/tao/corbacom.i \ + $(TAO_ROOT)/tao/typecode.i \ + $(TAO_ROOT)/tao/nvlist.i \ + $(TAO_ROOT)/tao/any.i \ + $(TAO_ROOT)/tao/stub.i \ + $(TAO_ROOT)/tao/object.i \ + $(TAO_ROOT)/tao/orbobj.i \ + $(TAO_ROOT)/tao/marshal.i \ + $(TAO_ROOT)/tao/cdr.i \ + $(TAO_ROOT)/tao/giop.i \ + $(TAO_ROOT)/tao/iioporb.i \ + $(TAO_ROOT)/tao/iiopobj.i \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/server_factory.i \ + $(TAO_ROOT)/tao/default_client.i \ + $(TAO_ROOT)/tao/default_server.i \ + $(TAO_ROOT)/tao/connect.i \ + $(TAO_ROOT)/tao/singletons.h \ + orbsvcs_export.h CosPropertyServiceC.i CosPropertyServiceS.i # IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/TAO/orbsvcs/orbsvcs/Naming/CosNaming_i.cpp b/TAO/orbsvcs/orbsvcs/Naming/CosNaming_i.cpp new file mode 100644 index 00000000000..562668bd920 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Naming/CosNaming_i.cpp @@ -0,0 +1,592 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// cos +// +// = FILENAME +// CosNaming_i.cpp +// +// = AUTHOR +// Marina Spivak <marina@cs.wustl.edu> & +// Sergio Flores-Gaitan <sergio@cs.wustl.edu> +// +// ============================================================================ + +#include "CosNaming_i.h" + +NS_NamingContext::NS_NamingContext (void) +{ + if (context_.open (NS_MAP_SIZE) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "NS_NamingContext")); + // deal with fault +} + +NS_NamingContext::~NS_NamingContext (void) +{ +} + +CosNaming::NamingContext_ptr +NS_NamingContext::get_context (const CosNaming::Name &name) +{ + // create compound name to be resolved + // (<name> - last component) + CORBA::Environment _env; + CORBA::ULong len = name.length (); + CosNaming::Name comp_name (name); + comp_name.length (len - 1); + + // resolve + CORBA::Object_ptr cont_ref; + + cont_ref = resolve (comp_name, _env); + + // Deal with exceptions in resolve: basicly, add the last component + // of the name to <rest_of_name> and rethrow. + if (_env.exception () != 0) + { + _env.print_exception ("NS_NamingContext::get_context"); + return 0; + } + + // Reference to a context from <resolve> cannot be nil because + // cannot <bind> to a nil object. + + // Try narrowing object reference to a context type. + CosNaming::NamingContext_ptr c; + c = CosNaming::NamingContext::_narrow (cont_ref, _env); + if (_env.exception () != 0) + { + _env.print_exception ("NS_NamingContext::get_context - _narrow"); + return 0; + } + + CosNaming::Name rest; + rest.length (2); + rest[0] = name[len - 2]; + rest[1] = name[len - 1]; + + if (CORBA::is_nil (c)) + { + CosNaming::Name rest; + rest.length (2); + rest[0] = name[len - 2]; + rest[1] = name[len - 1]; + } + return c; +} + +void +NS_NamingContext::bind (const CosNaming::Name& n, + CORBA::Object_ptr obj, + CORBA::Environment &_env) +{ + _env.clear (); + + // get the length of the name + CORBA::ULong len = n.length (); + + // Check for invalid name. + if (len == 0) + { + _env.clear (); + _env.exception (new CosNaming::NamingContext::InvalidName); + return; + } + + // If we received compound name, resolve it to get the context in + // which the binding should take place, then perform the binding on + // target context. + if (len > 1) + { + CosNaming::NamingContext_var cont = get_context (n); + CosNaming::Name simple_name; + simple_name.length (1); + simple_name[0] = n[len - 1]; + cont->bind (simple_name, obj, _env); + } + + // If we received a simple name, we need to bind it in this context. + else + { + NS_IntId entry (obj); + NS_ExtId name (n[0].id, n[0].kind); + + // Try binding the name. + if (context_.bind (name, entry) == -1) + { + _env.clear (); + _env.exception (new CosNaming::NamingContext::AlreadyBound); + return; + } + ACE_DEBUG ((LM_DEBUG, "bound: <%s,%s>\n", + n[0].id.in (), n[0].kind.in ())); + } +} + +void +NS_NamingContext::rebind (const CosNaming::Name& n, + CORBA::Object_ptr obj, + CORBA::Environment &_env) +{ + // get the length of the name + CORBA::ULong len = n.length (); + + // check for invalid name. + if (len == 0) + { + _env.clear (); + _env.exception (new CosNaming::NamingContext::InvalidName); + return; + } + + // If we received compound name, resolve it to get the context in + // which the rebinding should take place, then perform the rebinding + // on target context. + if (len > 1) + { + CosNaming::NamingContext_var cont = get_context (n); + CosNaming::Name simple_name; + simple_name.length (1); + simple_name[0] = n[len - 1]; + cont->rebind (simple_name, obj, _env); + } + // If we received a simple name, we need to rebind it in this context. + else + { + NS_IntId entry (obj); + NS_ExtId name (n[0].id, n[0].kind); + NS_IntId oldentry; + NS_ExtId oldname; + + // Try rebinding the name. + if (context_.rebind (name, entry, oldname, oldentry) == -1) + ; + // Deal with consequences. + } +} + +void +NS_NamingContext::bind_context (const CosNaming::Name &n, + CosNaming::NamingContext_ptr nc, + CORBA::Environment &_env) +{ + // Get the length of the name. + CORBA::ULong len = n.length (); + + // Check for invalid name. + if (len == 0) + { + _env.clear (); + _env.exception (new CosNaming::NamingContext::InvalidName); + return; + } + + // If we received compound name, resolve it to get the context in + // which the binding should take place, then perform the binding on + // target context. + if (len > 1) + { + CosNaming::NamingContext_var cont = get_context (n); + CosNaming::Name simple_name; + simple_name.length (1); + simple_name[0] = n[len - 1]; + cont->bind_context (simple_name, nc, _env); + } + + // If we received a simple name, we need to bind it in this context. + else + { + CosNaming::NameComponent comp = n[0]; + NS_IntId entry (nc, CosNaming::ncontext); + NS_ExtId name (n[0].id, n[0].kind); + + // Try binding the name. + if (context_.bind (name, entry) == 1) + { + _env.clear (); + _env.exception (new CosNaming::NamingContext::AlreadyBound); + return; + } + + // May need to add case dealing with -1. @@ + } +} + +void +NS_NamingContext::rebind_context (const CosNaming::Name &n, + CosNaming::NamingContext_ptr nc, + CORBA::Environment &_env) +{ + // Get the length of the name. + CORBA::ULong len = n.length (); + + // Check for invalid name. + if (len == 0) + { + _env.clear (); + _env.exception (new CosNaming::NamingContext::InvalidName); + return; + } + + // If we received compound name, resolve it to get the context in + // which the rebinding should take place, then perform the rebinding + // on target context. + if (len > 1) + { + CosNaming::NamingContext_var cont = get_context (n); + CosNaming::Name simple_name; + simple_name.length (1); + simple_name[0] = n[len - 1]; + cont->rebind_context (simple_name, nc, _env); + } + + // if we received a simple name, we need to rebind it in this context. + else + { + CosNaming::NameComponent comp = n[0]; + NS_IntId entry (nc, CosNaming::ncontext); + NS_ExtId name (n[0].id, n[0].kind); + NS_IntId oldentry; + NS_ExtId oldname; + + // try rebinding the name. + if (context_.rebind (name, entry, oldname, oldentry) < 0); + // deal with consequences + } +} + +CORBA::Object_ptr +NS_NamingContext::resolve (const CosNaming::Name& n, + CORBA::Environment &_env) +{ + // get the length of the name + CORBA::ULong len = n.length (); + + // check for invalid name. + if (len == 0) + { + _env.clear (); + _env.exception (new CosNaming::NamingContext::InvalidName); + return CORBA::Object::_nil (); + } + + ACE_DEBUG ((LM_DEBUG, "Trying to resolve <%s,%s>\n", + n[0].id.in (), n[0].kind.in ())); + + // resolve the first component of the name + NS_ExtId name (n[0].id, n[0].kind); + NS_IntId entry; + if (context_.find (name, entry) == -1) + { + _env.clear (); + _env.exception (new CosNaming::NamingContext::NotFound (CosNaming::NamingContext::not_object, n)); + return CORBA::Object::_nil (); + } + + CORBA::Object_ptr item = entry.ref_; + + // if the name we have to resolve is a compound name + // we need to recursively resolve it. + if (len > 1) + { + CosNaming::NamingContext_var cont; + if (entry.type_ == CosNaming::ncontext) + { + cont = CosNaming::NamingContext::_narrow (item, _env); + if (_env.exception () != 0) + { + _env.print_exception ("NS_NamingContext::resolve"); + return CORBA::Object::_nil (); + } + } + else + { + _env.clear (); + _env.exception (new CosNaming::NamingContext::NotFound (CosNaming::NamingContext::not_context, n)); + return CORBA::Object::_nil (); + } + + CosNaming::Name rest_of_name (len - 1); + rest_of_name.length (len - 1); + for (CORBA::ULong i = 1; i < len; i++) + rest_of_name[i-1] = n[i]; + + return (cont->resolve (rest_of_name, _env)); + } + + ACE_DEBUG ((LM_DEBUG, "Resolved <%s,%s> to %08.8x\n", + n[0].id.in (), n[0].kind.in (), + item)); + + // if the name we had to resolve was simple, we just need + // to return the result. + return CORBA::Object::_duplicate (item); +} + +void +NS_NamingContext::unbind (const CosNaming::Name& n, + CORBA::Environment &_env) +{ + // if (do_operation (n, CORBA::_nil (), NS_NamingContext::unbind) == 0) + + // get the length of the name + CORBA::ULong len = n.length (); + + // check for invalid name. + if (len == 0) + { + _env.clear (); + _env.exception (new CosNaming::NamingContext::InvalidName); + return; + } + + // If we received compound name, resolve it to get the context in + // which the unbinding should take place, then perform the unbinding + // on target context. + if (len > 1) + { + CosNaming::NamingContext_var cont = get_context (n); + CosNaming::Name simple_name; + simple_name.length (1); + simple_name[0] = n[len - 1]; + cont->unbind (simple_name, _env); + } + else + // If we received a simple name, we need to unbind it in this + // context. + { + NS_ExtId name (n[0].id, n[0].kind); + // try unbinding the name. + if (context_.unbind (name) == -1) + { + _env.clear (); + _env.exception (new CosNaming::NamingContext::NotFound (CosNaming::NamingContext::not_object, n)); + return; + } + } +} + +CosNaming::NamingContext_ptr +NS_NamingContext::new_context (CORBA::Environment &_env) +{ + NS_NamingContext *c = new NS_NamingContext; + + return c->_this (_env); +} + +CosNaming::NamingContext_ptr +NS_NamingContext::bind_new_context (const CosNaming::Name& n, + CORBA::Environment &_env) +{ + NS_NamingContext *c = new NS_NamingContext; + + bind_context (n, c->_this (_env), _env); + + // release object if exception occurs. + if (_env.exception () != 0) + { + delete c; + return CosNaming::NamingContext::_nil (); + } + + return c->_this (_env); +} + +void +NS_NamingContext::destroy (CORBA::Environment &_env) +{ + if (context_.current_size () != 0) + { + _env.clear (); + _env.exception (new CosNaming::NamingContext::NotEmpty); + return; + } + + // destroy context + CORBA::release (tie_ref_); +} + +void +NS_NamingContext::list (CORBA::ULong how_many, + CosNaming::BindingList_out bl, + CosNaming::BindingIterator_out bi, + CORBA::Environment &) +{ + // Dynamically allocate hash map iterator. + NS_NamingContext::HASH_MAP::ITERATOR *hash_iter = + new NS_NamingContext::HASH_MAP::ITERATOR (context_); + + // Number of bindings that will go into the BindingList. + CORBA::ULong n; + + if (context_.current_size () > how_many) + // number of bindings in the context is > <how_many> + // so need to return a BindingIterator. + { + NS_BindingIterator *bind_iter = new NS_BindingIterator (hash_iter); + + // @@ ???? + + ACE_UNUSED_ARG (bind_iter); + + // bind_iter->initialize (bi); + CosNaming::BindingIterator::_duplicate (bi); + + n = how_many; + } + else + { + // Number of bindings in the context is <= <how_many>, + // so do not need to return a BindingIterator. + bi = CosNaming::BindingIterator::_nil (); + n = context_.current_size (); + } + + // use hash iterator to populate a BindingList with + // bindings. + CosNaming::BindingList bindings; + bindings.length (n); + NS_NamingContext::HASH_MAP::ENTRY *hash_entry; + + for (CORBA::ULong i = 0; i < n; i++) + { + hash_iter->next (hash_entry); + hash_iter->advance (); + + bindings[i].binding_type = hash_entry->int_id_.type_; + + bindings[i].binding_name.length (1); + bindings[i].binding_name[0].id = + CORBA::string_dup (hash_entry->ext_id_.id_.fast_rep ()); + bindings[i].binding_name[0].kind = + CORBA::string_dup (hash_entry->ext_id_.kind_.fast_rep ()); + } + // Marina, please add check for memory failure. + bl = new CosNaming::BindingList (bindings); + + // If did not allocate BindingIterator, deallocate hash map + // iterator. + if (context_.current_size () <= how_many) + delete hash_iter; +} + +NS_BindingIterator::NS_BindingIterator (NS_NamingContext::HASH_MAP::ITERATOR *hash_iter) +{ + hash_iter_ = hash_iter; +} + +NS_BindingIterator::~NS_BindingIterator (void) +{ + delete hash_iter_; +} + +CORBA::Boolean +NS_BindingIterator::next_one (CosNaming::Binding_out b, + CORBA::Environment &_env) +{ + // Macro to avoid "warning: unused parameter" type warning. + ACE_UNUSED_ARG (_env); + + if (hash_iter_->done ()) { + b = new CosNaming::Binding; + return 0; + } + else + { + b = new CosNaming::Binding; + + NS_NamingContext::HASH_MAP::ENTRY *hash_entry; + hash_iter_->next (hash_entry); + hash_iter_->advance (); + + b->binding_type = hash_entry->int_id_.type_; + + b->binding_name.length (1); + b->binding_name[0].id = + CORBA::string_dup (hash_entry->ext_id_.id_.fast_rep ()); + b->binding_name[0].kind = + CORBA::string_dup (hash_entry->ext_id_.kind_.fast_rep ()); + + return 1; + } +} + +CORBA::Boolean +NS_BindingIterator::next_n (CORBA::ULong how_many, + CosNaming::BindingList_out bl, + CORBA::Environment &_env) +{ + // Macro to avoid "warning: unused parameter" type warning. + ACE_UNUSED_ARG (_env); + + if (hash_iter_->done ()) { + bl = new CosNaming::BindingList; + return 0; + } + else + { + // Statically allocate a BindingList. + CosNaming::BindingList bindings; + + // Initially assume that iterator has the requested number of + // bindings. + bindings.length (how_many); + + // Iterate and populate the BindingList. + NS_NamingContext::HASH_MAP::ENTRY *hash_entry; + for (CORBA::ULong i = 0; i < how_many; i++) + { + hash_iter_->next (hash_entry); + + bindings[i].binding_type = hash_entry->int_id_.type_; + + bindings[i].binding_name.length (1); + bindings[i].binding_name[0].id = + CORBA::string_dup (hash_entry->ext_id_.id_.fast_rep ()); + bindings[i].binding_name[0].kind = + CORBA::string_dup (hash_entry->ext_id_.kind_.fast_rep ()); + + if (hash_iter_->advance () == 0) + { + // If no more bindings left, reset length to the actual + // number of bindings populated and get out of the loop. + bindings.length (i + 1); + break; + } + } + + bl = new CosNaming::BindingList (bindings); + // Marina, please check for failed memory allocation. + return 1; + } +} + +void +NS_BindingIterator::destroy (CORBA::Environment &_env) +{ + // Macro to avoid "warning: unused parameter" type warning. + ACE_UNUSED_ARG (_env); + + // CORBA::release (tie_ref_); +} + +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) +// These templates will specialized in libACE.* if the platforms does +// not define ACE_MT_SAFE. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Hash_Map_Manager<NS_ExtId, NS_IntId, ACE_Null_Mutex>; +template class ACE_Hash_Map_Entry<NS_ExtId, NS_IntId>; +template class ACE_Hash_Map_Iterator_Base<NS_ExtId, NS_IntId, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator<NS_ExtId, NS_IntId, ACE_Null_Mutex>; +template class ACE_Hash_Map_Reverse_Iterator<NS_ExtId, NS_IntId, ACE_Null_Mutex>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Hash_Map_Manager<NS_ExtId, NS_IntId, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Entry<NS_ExtId, NS_IntId> +#pragma instantiate ACE_Hash_Map_Iterator_Base<NS_ExtId, NS_IntId, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator<NS_ExtId, NS_IntId, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Reverse_Iterator<NS_ExtId, NS_IntId, ACE_Null_Mutex> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ +#endif /* ACE_MT_SAFE */ diff --git a/TAO/orbsvcs/orbsvcs/Naming/CosNaming_i.h b/TAO/orbsvcs/orbsvcs/Naming/CosNaming_i.h new file mode 100644 index 00000000000..d380bc5c4b0 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Naming/CosNaming_i.h @@ -0,0 +1,137 @@ +/* -*- C++ -*- */ + +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// cos +// +// = FILENAME +// CosNaming_i.h +// +// = AUTHOR +// Marina Spivak <marina@cs.wustl.edu> & +// Sergio Flores-Gaitan <sergio@cs.wustl.edu> +// +// ============================================================================ + +#if !defined (COSNAMING_I_H) +#define COSNAMING_I_H + +#include "orbsvcs/CosNamingS.h" +#include "Entries.h" + +class NS_NamingContext : public POA_CosNaming::NamingContext + // = TITLE + // This class implements the NamingContext interface that is part of the + // CosNaming idl module. + // + // = DESCRIPTION + // Extensive comments can be found in the idl file. +{ + public: + + enum + { + NS_MAP_SIZE = 23 + // The size of hash map for a NS_NamingContext object. + }; + + typedef ACE_Hash_Map_Manager<NS_ExtId, NS_IntId, ACE_Null_Mutex> HASH_MAP; + + NS_NamingContext (void); + // default constructor. + + ~NS_NamingContext (void); + // destructor. + + virtual void bind (const CosNaming::Name &n, + CORBA::Object_ptr obj, + CORBA::Environment &IT_env); + + virtual void rebind (const CosNaming::Name &n, + CORBA::Object_ptr obj, + CORBA::Environment &IT_env); + + virtual void bind_context (const CosNaming::Name &n, + CosNaming::NamingContext_ptr nc, + CORBA::Environment &IT_env); + + virtual void rebind_context (const CosNaming::Name &n, + CosNaming::NamingContext_ptr nc, + CORBA::Environment &IT_env); + + virtual CORBA::Object_ptr resolve (const CosNaming::Name &n, + CORBA::Environment &IT_env); + + virtual void unbind (const CosNaming::Name &n, + CORBA::Environment &IT_env); + + virtual CosNaming::NamingContext_ptr new_context (CORBA::Environment &IT_env); + + virtual CosNaming::NamingContext_ptr bind_new_context (const CosNaming::Name &n, + CORBA::Environment &IT_env); + + virtual void destroy (CORBA::Environment &IT_env); + + virtual void list (CORBA::ULong how_many, + CosNaming::BindingList_out bl, + CosNaming::BindingIterator_out bi, + CORBA::Environment &IT_env); + + protected: + // = These are the helper methods used by other methods. + + CosNaming::NamingContext_ptr get_context (const CosNaming::Name &name); + // This is used by methods that need to resolve a compound name to + // get the reference to the target context before performing the + // actual operation (e.g. bind, unbind, etc.) Takes a full name + // (including the last component that doesn't need to be resolved) + // Returns a pointer to the target context. + + private: + + HASH_MAP context_; + // This implementation of NamingContext uses ACE thread-safe Hash + // Map for storage and manipulation of name-object bindings. + + CosNaming::NamingContext_ptr tie_ref_; + // Stores CORBA object reference to the TIE object this object + // implements. This is needed to implement the <destroy> method. +}; + +class NS_BindingIterator : public POA_CosNaming::BindingIterator + // = TITLE + // This class implements the BindingIterator interface + // that is part of the CosNaming idl module. + // + // = DESCRIPTION + // NS_BindingIterator constructor expects a pointer to a + // DYNAMICALLY allocated hash map iterator. Destructor + // deallocates hash map iterator. +{ + public: + // = Intialization and termination methods. + NS_BindingIterator (NS_NamingContext::HASH_MAP::ITERATOR *hash_iter); + // constructor. + + ~NS_BindingIterator (void); + // destructor. + + // Marina, please add comments. + CORBA::Boolean next_one (CosNaming::Binding_out b, + CORBA::Environment &IT_env); + + CORBA::Boolean next_n (CORBA::ULong how_many, + CosNaming::BindingList_out bl, + CORBA::Environment &IT_env); + + void destroy (CORBA::Environment &IT_env); + + private: + NS_NamingContext::HASH_MAP::ITERATOR *hash_iter_; + // A pointer to the hash map iterator. +}; + +#endif /* COSNAMING_I_H */ diff --git a/TAO/orbsvcs/orbsvcs/Naming/Entries.cpp b/TAO/orbsvcs/orbsvcs/Naming/Entries.cpp new file mode 100644 index 00000000000..9781095a35d --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Naming/Entries.cpp @@ -0,0 +1,106 @@ +// ============================================================================ +// +// = LIBRARY +// cos +// +// = FILENAME +// NS_CosNaming.C +// +// = AUTHOR +// Marina Spivak <marina@cs.wustl.edu> +// +// ============================================================================ + +#include "Entries.h" + +NS_IntId::NS_IntId (void) + : type_ (CosNaming::nobject) +{ + ref_ = CORBA::Object::_nil (); +} + +NS_IntId::NS_IntId (CORBA::Object_ptr obj, + CosNaming::BindingType type) + : type_ (type) +{ + ref_ = CORBA::Object::_duplicate (obj); +} + +NS_IntId::NS_IntId (const NS_IntId &rhs) +{ + type_ = rhs.type_; + ref_ = CORBA::Object::_duplicate (rhs.ref_); +} + +NS_IntId::~NS_IntId (void) +{ + CORBA::release (ref_); +} + +void +NS_IntId::operator= (const NS_IntId &rhs) +{ + // check for self assignment. + if (&rhs == this) + return; + + type_ = rhs.type_; + + CORBA::release (ref_); + ref_ = CORBA::Object::_duplicate (rhs.ref_); +} + +NS_ExtId::NS_ExtId (void) + : kind_ (), + id_ () +{ +} + +NS_ExtId::NS_ExtId (const char *id, + const char *kind) + : kind_ (kind), + id_ (id) +{ +} + +NS_ExtId::NS_ExtId (const NS_ExtId &rhs) +{ + id_ = rhs.id_; + kind_ = rhs.kind_; +} + +NS_ExtId::~NS_ExtId (void) +{ +} + +void +NS_ExtId::operator= (const NS_ExtId &rhs) +{ + // Check for self assignment. + if (&rhs == this) + return; + + id_ = rhs.id_; + kind_ = rhs.kind_; +} + +int +NS_ExtId::operator== (const NS_ExtId &rhs) const +{ + return id_ == rhs.id_ && kind_ == rhs.kind_; +} + +int +NS_ExtId::operator!= (const NS_ExtId &rhs) const +{ + return id_ != rhs.id_ || kind_ != rhs.kind_; +} + +u_long +NS_ExtId::hash (void) const +{ + ACE_CString temp (id_); + temp += kind_; + + return temp.hash (); +} diff --git a/TAO/orbsvcs/orbsvcs/Naming/Entries.h b/TAO/orbsvcs/orbsvcs/Naming/Entries.h new file mode 100644 index 00000000000..c6bd0e59771 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Naming/Entries.h @@ -0,0 +1,108 @@ +/* -*- C++ -*- */ + +// ============================================================================ +// +// = LIBRARY +// cos +// +// = FILENAME +// NS_CosNaming.h +// +// = AUTHOR +// Marina Spivak <marina@cs.wustl.edu> +// +// ============================================================================ + +#if !defined (NS_COSNAMING_H) +#define NS_COSNAMING_H + +#include "ace/Hash_Map_Manager.h" +#include "ace/Synch.h" +#include "ace/SString.h" + +#include "tao/corba.h" +#include "orbsvcs/CosNamingC.h" + +class NS_IntId + // = TITLE + // Stores information a context keeps for each bound name + // (object reference and the type of binding). + // + // = DESCRIPTION + // + // + // + // +{ +public: + // = Initialization and termination methods. + NS_IntId (void); + // default constructor. + + NS_IntId (CORBA::Object_ptr obj, + CosNaming::BindingType type = CosNaming::nobject); + // constructor. + + NS_IntId (const NS_IntId & rhs); + // copy constructor + + ~NS_IntId (void); + // destructor + + void operator= (const NS_IntId & rhs); + // Assignment operator (does copy memory). + + CORBA::Object_ptr ref_; + // CORBA object reference of the bound object. + + CosNaming::BindingType type_; + // Indicator of whether the object is a NamingContext that should + // participate in name resolution when compound names are used. +}; + +class NS_ExtId + // = TITLE + // Stores the name to which an object is bound. + // + // = DESCRIPTION + // + // + // + // +{ +public: + // = Initialization and termination methods. + NS_ExtId (void); + // default constructor. + + NS_ExtId (const char *id, + const char *kind); + // constructor. + + NS_ExtId (const NS_ExtId & rhs); + // copy constructor + + ~NS_ExtId (void); + // destructor + + void operator= (const NS_ExtId & rhs); + // Assignment operator (does copy memory). + + int operator== (const NS_ExtId &rhs) const; + // Equality comparison operator (must match both id_ and kind_). + + int operator!= (const NS_ExtId &rhs) const; + // Inequality comparison operator. + + u_long hash (void) const; + // This class has to have a hash for use with ACE_Hash_Map_Manager. + + ACE_CString kind_; + // any information user wants to store (not used by Naming Service). + + ACE_CString id_; + // any information user wants to store (not used by Naming Service). +}; + + +#endif /* NS_COSNAMING_H */ diff --git a/TAO/orbsvcs/orbsvcs/CosPropertyService_i.cpp b/TAO/orbsvcs/orbsvcs/Property/CosPropertyService_i.cpp index 6aed9907285..6aed9907285 100644 --- a/TAO/orbsvcs/orbsvcs/CosPropertyService_i.cpp +++ b/TAO/orbsvcs/orbsvcs/Property/CosPropertyService_i.cpp diff --git a/TAO/orbsvcs/orbsvcs/CosPropertyService_i.h b/TAO/orbsvcs/orbsvcs/Property/CosPropertyService_i.h index cb69ffd9d47..c8d53a587f9 100644 --- a/TAO/orbsvcs/orbsvcs/CosPropertyService_i.h +++ b/TAO/orbsvcs/orbsvcs/Property/CosPropertyService_i.h @@ -20,7 +20,7 @@ #include "ace/OS.h" #include "orbsvcs/CosPropertyServiceS.h" -#include "orbsvcs/CosProperty_Hash.h" +#include "CosProperty_Hash.h" class TAO_PropertySetFactory : public virtual POA_CosPropertyService::PropertySetFactory { @@ -75,7 +75,7 @@ class TAO_PropertySet : public virtual POA_CosPropertyService::PropertySet // = DESCRIPTION // Uses a HashTable to manage the properties. public: - typdef Hash_Property_Map<EXT_ID, INT_ID, ACE_Null_Mutex> CosProperty_Hash_Map; + typedef ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_Null_Mutex> CosProperty_Hash_Map; TAO_PropertySet (void); // Default constructor diff --git a/TAO/orbsvcs/orbsvcs/CosProperty_Hash.cpp b/TAO/orbsvcs/orbsvcs/Property/CosProperty_Hash.cpp index b725e05a421..b725e05a421 100644 --- a/TAO/orbsvcs/orbsvcs/CosProperty_Hash.cpp +++ b/TAO/orbsvcs/orbsvcs/Property/CosProperty_Hash.cpp diff --git a/TAO/orbsvcs/orbsvcs/CosProperty_Hash.h b/TAO/orbsvcs/orbsvcs/Property/CosProperty_Hash.h index 883e7a2a8e1..aebd0430da1 100644 --- a/TAO/orbsvcs/orbsvcs/CosProperty_Hash.h +++ b/TAO/orbsvcs/orbsvcs/Property/CosProperty_Hash.h @@ -22,7 +22,6 @@ #include "ace/Hash_Map_Manager.h" #include "ace/Synch.h" #include "CosPropertyServiceS.h" -#include "tao/any.h" class EXT_ID { diff --git a/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.cpp b/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.cpp new file mode 100644 index 00000000000..7ac4fff3bc2 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.cpp @@ -0,0 +1,267 @@ +// ============================================================================ +// +// $Id$ +// +// ============================================================================ + +#include "orbsvcs/Time_Utilities.h" +#include "orbsvcs/Scheduler_Factory.h" + +#include "Scheduler_Generic.h" +#include "Config_Scheduler.h" + +#if defined (__ACE_INLINE__) +#include "Config_Scheduler.i" +#endif /* __ACE_INLINE__ */ + +ACE_Config_Scheduler::ACE_Config_Scheduler (void) + : impl(new Scheduler_Generic) +{ + // impl->output_level (10); +} + +ACE_Config_Scheduler::~ACE_Config_Scheduler (void) +{ + delete impl; +} + +RtecScheduler::handle_t +ACE_Config_Scheduler::create (const char * entry_point, + CORBA::Environment &) + TAO_THROW_SPEC ((CORBA::SystemException, + RtecScheduler::DUPLICATE_NAME)) +{ + typedef RtecScheduler::RT_Info* RT_Info_ptr; + + RtecScheduler::RT_Info** rt_info; + ACE_NEW_RETURN (rt_info, RT_Info_ptr[1], -1); + + ACE_NEW_RETURN (rt_info[0], RtecScheduler::RT_Info, -1); + + rt_info[0]->entry_point = CORBA::string_dup(entry_point); + rt_info[0]->handle = -1; + rt_info[0]->worst_case_execution_time = ORBSVCS_Time::zero; + rt_info[0]->typical_execution_time = ORBSVCS_Time::zero; + rt_info[0]->cached_execution_time = ORBSVCS_Time::zero; + rt_info[0]->period = 0; + rt_info[0]->importance = RtecScheduler::VERY_LOW; + rt_info[0]->quantum = ORBSVCS_Time::zero; + rt_info[0]->threads = 0; + rt_info[0]->priority = 0; + rt_info[0]->subpriority = 0; + rt_info[0]->preemption_priority = 0; + + RtecScheduler::handle_t handle = -1; + switch (impl->register_task (rt_info, 1, handle)) + { + case ACE_Scheduler::SUCCEEDED: + break; + case ACE_Scheduler::ST_VIRTUAL_MEMORY_EXHAUSTED: + case ACE_Scheduler::ST_TASK_ALREADY_REGISTERED: + default: + delete rt_info[0]; + delete[] rt_info; + ACE_ERROR ((LM_ERROR, + "Config_Scheduler::create - register_task failed\n")); + // @@ TODO: throw something. + break; + } + return handle; +} + +RtecScheduler::handle_t +ACE_Config_Scheduler::lookup (const char * entry_point, + CORBA::Environment &) + TAO_THROW_SPEC ((CORBA::SystemException)) +{ + RtecScheduler::RT_Info* rt_info = 0; + switch (impl->get_rt_info (entry_point, rt_info)) + { + case ACE_Scheduler::SUCCEEDED: + return rt_info->handle; + break; + case ACE_Scheduler::FAILED: + case ACE_Scheduler::ST_UNKNOWN_TASK: + default: + ACE_ERROR ((LM_ERROR, + "Config_Scheduler::lookup - get_rt_info failed\n")); + // @@ TODO: throw something. + break; + } + return -1; +} + +RtecScheduler::RT_Info* +ACE_Config_Scheduler::get (RtecScheduler::handle_t handle, + CORBA::Environment &) + TAO_THROW_SPEC((CORBA::SystemException, + RtecScheduler::UNKNOWN_TASK)) +{ + RtecScheduler::RT_Info* rt_info = 0; + switch (impl->lookup_rt_info (handle, rt_info)) + { + case ACE_Scheduler::SUCCEEDED: + { + // IDL memory managment semantics require the we return a copy + RtecScheduler::RT_Info* copy; + ACE_NEW_RETURN (copy, RtecScheduler::RT_Info (*rt_info), 0); + return copy; + } + break; + case ACE_Scheduler::FAILED: + case ACE_Scheduler::ST_UNKNOWN_TASK: + default: + ACE_ERROR ((LM_ERROR, + "Config_Scheduler::get - lookup_rt_info failed\n")); + // @@ TODO: throw something. + break; + } + return 0; +} + +void ACE_Config_Scheduler::set (RtecScheduler::handle_t handle, + const RtecScheduler::Time &time, + const RtecScheduler::Time &typical_time, + const RtecScheduler::Time &cached_time, + RtecScheduler::Period period, + RtecScheduler::Importance importance, + const RtecScheduler::Quantum &quantum, + CORBA::Long threads, + CORBA::Environment &) + TAO_THROW_SPEC ((CORBA::SystemException, + RtecScheduler::UNKNOWN_TASK)) +{ + RtecScheduler::RT_Info* rt_info = 0; + switch (impl->lookup_rt_info (handle, rt_info)) + { + case ACE_Scheduler::SUCCEEDED: + rt_info->worst_case_execution_time = time; + rt_info->typical_execution_time = typical_time; + rt_info->cached_execution_time = cached_time; + rt_info->period = period; + rt_info->importance = importance; + rt_info->quantum = quantum; + rt_info->threads = threads; + break; + case ACE_Scheduler::FAILED: + case ACE_Scheduler::ST_UNKNOWN_TASK: + default: + ACE_ERROR ((LM_ERROR, + "Config_Scheduler::set - lookup_rt_info failed\n")); + // @@ TODO: throw something. + break; + } +} + +void ACE_Config_Scheduler::priority (RtecScheduler::handle_t handle, + RtecScheduler::OS_Priority& priority, + RtecScheduler::Sub_Priority& subpriority, + RtecScheduler::Preemption_Priority& p_priority, + CORBA::Environment &_env) + TAO_THROW_SPEC ((CORBA::SystemException, + RtecScheduler::UNKNOWN_TASK, + RtecScheduler::NOT_SCHEDULED)) +{ + ACE_UNUSED_ARG (_env); + + if (impl->priority (handle, priority, subpriority, p_priority) == -1) + { + ACE_ERROR ((LM_ERROR, + "Config_Scheduler::priority - priority failed\n")); + // TODO: throw something. + } +} + +void ACE_Config_Scheduler::entry_point_priority (const char * entry_point, + RtecScheduler::OS_Priority& priority, + RtecScheduler::Sub_Priority& subpriority, + RtecScheduler::Preemption_Priority& p_priority, + CORBA::Environment &_env) + TAO_THROW_SPEC((CORBA::SystemException, + RtecScheduler::UNKNOWN_TASK, + RtecScheduler::NOT_SCHEDULED)) +{ + this->priority (lookup (entry_point, _env), + priority, subpriority, p_priority, + _env); +} + +void ACE_Config_Scheduler::add_dependency (RtecScheduler::handle_t handle, + RtecScheduler::handle_t dependency, + CORBA::Long number_of_calls, + CORBA::Environment &_env) + TAO_THROW_SPEC ((CORBA::SystemException, + RtecScheduler::UNKNOWN_TASK)) +{ + ACE_UNUSED_ARG (_env); + + RtecScheduler::RT_Info* rt_info = 0; + switch (impl->lookup_rt_info (handle, rt_info)) + { + case ACE_Scheduler::SUCCEEDED: + { + RtecScheduler::Dependency_Info dep; + dep.rt_info = dependency; + dep.number_of_calls = number_of_calls; + ACE_Scheduler::add_dependency(rt_info, dep); + } + break; + case ACE_Scheduler::FAILED: + case ACE_Scheduler::ST_UNKNOWN_TASK: + default: + ACE_ERROR ((LM_ERROR, + "cannot find %d to add dependency", handle)); + // TODO: throw something. + break; + } +} + +void ACE_Config_Scheduler::compute_scheduling (CORBA::Long minimum_priority, + CORBA::Long maximum_priority, + RtecScheduler::RT_Info_Set_out infos, + CORBA::Environment &_env) + TAO_THROW_SPEC ((CORBA::SystemException, + RtecScheduler::UTILIZATION_BOUND_EXCEEDED, + RtecScheduler::INSUFFICIENT_THREAD_PRIORITY_LEVELS, + RtecScheduler::TASK_COUNT_MISMATCH)) +{ + ACE_UNUSED_ARG (_env); + + impl->init (minimum_priority, maximum_priority); + if (impl->schedule () != ACE_Scheduler::SUCCEEDED) + { + // TODO: throw something. + ACE_ERROR ((LM_ERROR, "schedule failed\n")); + return; + } + if (infos == 0) + { + infos = new RtecScheduler::RT_Info_Set(impl->tasks ()); + } + infos->length (impl->tasks ()); + for (RtecScheduler::handle_t handle = 1; + handle <= (RtecScheduler::handle_t) impl->tasks (); + ++handle) + { + RtecScheduler::RT_Info* rt_info = 0; + switch (impl->lookup_rt_info (handle, rt_info)) + { + case ACE_Scheduler::SUCCEEDED: + // We know that handles start at 1. + infos[CORBA::ULong(handle - 1)] = *rt_info; + break; + case ACE_Scheduler::FAILED: + case ACE_Scheduler::ST_UNKNOWN_TASK: + default: + ACE_ERROR ((LM_ERROR, + "Config_Scheduler::schedule - lookup_rt_info failed\n")); + // TODO: throw something. + break; + } + } + ACE_DEBUG ((LM_DEBUG, "schedule prepared\n")); + + ACE_DEBUG ((LM_DEBUG, "dumping to stdout\n")); + ACE_Scheduler_Factory::dump_schedule (*(infos.ptr()), 0); + ACE_DEBUG ((LM_DEBUG, "dump done\n")); +} diff --git a/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.h b/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.h new file mode 100644 index 00000000000..1f8fda26735 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.h @@ -0,0 +1,94 @@ +// ============================================================================ +// +// $Id$ +// +// ============================================================================ + +#ifndef ACE_CONFIG_SCHEDULER_H +#define ACE_CONFIG_SCHEDULER_H + +#include "ace/OS.h" + +#include "orbsvcs/RtecSchedulerS.h" +#include "orbsvcs/Event_Service_Constants.h" + +class ACE_Config_Scheduler +: public POA_RtecScheduler::Scheduler + // = TITLE + // A (local) implementation for the RtecScheduler::Scheduler service. + // + // = DESCRIPTION + // This class implements a servant for the + // RtecScheduler::Scheduler service, using the Scheduler classes + // distributed with the EC. +{ +public: + ACE_Config_Scheduler (void); + virtual ~ACE_Config_Scheduler (void); + + virtual RtecScheduler::handle_t create (const char * entry_point, + CORBA::Environment &_env) + TAO_THROW_SPEC ((CORBA::SystemException, RtecScheduler::DUPLICATE_NAME)); + + virtual RtecScheduler::handle_t lookup (const char * entry_point, + CORBA::Environment &_env) + TAO_THROW_SPEC((CORBA::SystemException)); + + virtual RtecScheduler::RT_Info* get (RtecScheduler::handle_t handle, + CORBA::Environment &_env) + TAO_THROW_SPEC ((CORBA::SystemException, RtecScheduler::UNKNOWN_TASK)); + + virtual void set (RtecScheduler::handle_t handle, + const RtecScheduler::Time &time, + const RtecScheduler::Time &typical_time, + const RtecScheduler::Time &cached_time, + RtecScheduler::Period period, + RtecScheduler::Importance importance, + const RtecScheduler::Quantum &quantum, + CORBA::Long threads, + CORBA::Environment &_env) + TAO_THROW_SPEC ((CORBA::SystemException, RtecScheduler::UNKNOWN_TASK)); + + virtual void priority (RtecScheduler::handle_t handle, + RtecScheduler::OS_Priority& priority, + RtecScheduler::Sub_Priority& subpriority, + RtecScheduler::Preemption_Priority& p_priority, + CORBA::Environment &_env) + TAO_THROW_SPEC ((CORBA::SystemException, + RtecScheduler::UNKNOWN_TASK, + RtecScheduler::NOT_SCHEDULED)); + + virtual void entry_point_priority (const char * entry_point, + RtecScheduler::OS_Priority& priority, + RtecScheduler::Sub_Priority& subpriority, + RtecScheduler::Preemption_Priority& p_priority, + CORBA::Environment &_env) + TAO_THROW_SPEC ((CORBA::SystemException, + RtecScheduler::UNKNOWN_TASK, + RtecScheduler::NOT_SCHEDULED)); + + virtual void add_dependency (RtecScheduler::handle_t handle, + RtecScheduler::handle_t dependency, + CORBA::Long number_of_calls, + CORBA::Environment &_env) + TAO_THROW_SPEC ((CORBA::SystemException, + RtecScheduler::UNKNOWN_TASK)); + + virtual void compute_scheduling (CORBA::Long minimum_priority, + CORBA::Long maximum_priority, + RtecScheduler::RT_Info_Set_out infos, + CORBA::Environment &_env) + TAO_THROW_SPEC((CORBA::SystemException, + RtecScheduler::UTILIZATION_BOUND_EXCEEDED, + RtecScheduler::INSUFFICIENT_THREAD_PRIORITY_LEVELS, + RtecScheduler::TASK_COUNT_MISMATCH)); + +private: + class ACE_Scheduler* impl; +}; + +#if defined (__ACE_INLINE__) +#include "Config_Scheduler.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_CONFIG_SCHEDULER_H */ diff --git a/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.i b/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.i new file mode 100644 index 00000000000..a21ea7f9897 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/Config_Scheduler.i @@ -0,0 +1,5 @@ +// ============================================================================ +// +// $Id$ +// +// ============================================================================ diff --git a/TAO/orbsvcs/orbsvcs/Sched/DynSched.cpp b/TAO/orbsvcs/orbsvcs/Sched/DynSched.cpp new file mode 100644 index 00000000000..20a30804b33 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/DynSched.cpp @@ -0,0 +1,1410 @@ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// DynSched.cpp +// +// = CREATION DATE +// 23 January 1997 +// +// = AUTHOR +// Chris Gill +// +// ============================================================================ + +#include <math.h> +#include <float.h> + +#include "ace/Sched_Params.h" +#include "DynSched.h" + +#if ! defined (__ACE_INLINE__) +#include "DynSched.i" +#endif /* __ACE_INLINE__ */ + +////////////////////// +// Helper functions // +////////////////////// + +// compare the DFS finish times of two task entries, order higher time *first* +extern "C" int compare_entry_finish_times (const void *first, const void *second) +{ + // sort blank entries to the end + if (! first) + { + return (second) ? 1 : 0; + } + else if (! second) + { + return -1; + } + + Task_Entry *first_entry = + * ACE_static_cast (Task_Entry **, first); + Task_Entry *second_entry = + * ACE_static_cast (Task_Entry **, second); + + // sort blank entries to the end + if (! first_entry) + { + return (second_entry) ? 1 : 0; + } + else if (! second_entry) + { + return -1; + } + + if (first_entry->finished () > second_entry->finished ()) + { + return -1; + } + else if (first_entry->finished () < second_entry->finished ()) + { + return 1; + } + + return 0; +} + +////////////////////////////////////////// +// class ACE_Scheduler member functions // +////////////////////////////////////////// + +const char * +ACE_Scheduler::status_message (ACE_Scheduler::status_t status) +{ + switch (status) + { + case NOT_SCHEDULED : + return "NOT_SCHEDULED"; + case SUCCEEDED : + return "SUCCEEDED"; + case ST_TASK_ALREADY_REGISTERED : + return "TASK_ALREADY_REGISTERED"; + case ST_BAD_DEPENDENCIES_ON_TASK : + return "BAD_DEPENDENCIES_ON_TASK"; + case ST_BAD_INTERNAL_POINTER : + return "BAD_INTERNAL_POINTER"; + case ST_VIRTUAL_MEMORY_EXHAUSTED : + return "VIRTUAL_MEMORY_EXHAUSTED"; + case ST_UNKNOWN_TASK : + return "UNKNOWN_TASK"; + case TASK_COUNT_MISMATCH : + return "TASK_COUNT_MISMATCH"; + case INVALID_PRIORITY : + return "INVALID_PRIORITY"; + + // The following are only used during scheduling (in the case of + // off-line scheduling, they are only used prior to runtime). + // To save a little code space (280 bytes on g++ 2.7.2/Solaris 2.5.1), + // we could conditionally compile them so that they're not in the + // runtime version. + case ST_UTILIZATION_BOUND_EXCEEDED : + return "UTILIZATION_BOUND_EXCEEDED"; + case ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS : + return "INSUFFICIENT_THREAD_PRIORITY_LEVELS"; + case ST_CYCLE_IN_DEPENDENCIES : + return "CYCLE_IN_DEPENDENCIES"; + case ST_INVALID_PRIORITY_ORDERING : + return "INVALID_PRIORITY_ORDERING"; + case UNABLE_TO_OPEN_SCHEDULE_FILE : + return "UNABLE_TO_OPEN_SCHEDULE_FILE"; + case UNABLE_TO_WRITE_SCHEDULE_FILE : + return "UNABLE_TO_WRITE_SCHEDULE_FILE"; + // End of config-only status values. + + default: + break; + } + + return "UNKNOWN STATUS"; +} + + +ACE_Scheduler::ACE_Scheduler () + // Set the minimum and maximum priority to those for the current platform. + // This shouldn't be necessary, but UPSingleProcessorOrb::initialize_reactors + // creates threads before the Event Channel calls Scheduler::init (). + : minimum_priority_ (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, + ACE_SCOPE_PROCESS)) + , maximum_priority_ (ACE_Sched_Params::priority_max (ACE_SCHED_FIFO, + ACE_SCOPE_PROCESS)) + , task_entries_ (0) + , ordered_task_entries_ (0) + , thread_delineators_ (0) + , ordered_thread_dispatch_entries_ (0) + , dispatch_entries_ (0) + , ordered_dispatch_entries_ (0) + , dispatch_entry_count_ (0) + , threads_ (0) + , rt_info_entries_ () + , lock_ () + , handles_ (0) + , runtime_filename_ (0) + , rt_info_filename_ (0) + , timeline_filename_ (0) + , tasks_ (0) + , status_ (NOT_SCHEDULED) + , output_level_ (0) + , frame_size_ (1) + , critical_set_frame_size_ (0) + , utilization_ (0.0) + , critical_set_utilization_ (0.0) + , minimum_priority_queue_ (0) + , minimum_guaranteed_priority_queue_ (-1) + , timeline_ (0) + , up_to_date_ (0) + +{ +} + + +ACE_Scheduler::~ACE_Scheduler () +{ + // release all resources used for the most recent schedule + reset (); +} + + +void +ACE_Scheduler::init (const OS_Priority minimum_priority, + const OS_Priority maximum_priority, + const char *runtime_filename, + const char *rt_info_filename, + const char *timeline_filename) +{ + minimum_priority_ = minimum_priority; + maximum_priority_ = maximum_priority; + runtime_filename_ = runtime_filename; + rt_info_filename_ = rt_info_filename; + timeline_filename_ = timeline_filename; +} + // = initializes the scheduler. + +ACE_Scheduler::status_t +ACE_Scheduler::register_task (RT_Info *rt_info, handle_t &handle) +{ + ACE_Scheduler::status_t ret; + + // try to store the new task's information . . . + switch (rt_info_entries_.insert (rt_info)) + { + case 0 : // successfully inserted + { + rt_info->handle = (handle = ++handles_); + + ret = SUCCEEDED; + + // zero out the task entry ACT used by the scheduler + rt_info->volatile_token = 0; + + // make sure the schedule is reset when a new task is registered + reset (); + + if (output_level () >= 5) + { + ACE_OS::printf ("registered task \"%s\" with RT_Info at %X\n", + (const char*)rt_info->entry_point, + (void *) rt_info); + } + } + break; + + case 1 : // the entry had already been inserted + handle = 0; + ret = ST_TASK_ALREADY_REGISTERED; + break; + + default : + // case -1 : insert failed, probably because virtual memory exhaused + handle = 0; + ret = ST_VIRTUAL_MEMORY_EXHAUSTED; + break; + } + + return ret; +} + // = registers a task. + + + +ACE_Scheduler::status_t +ACE_Scheduler::get_rt_info (Object_Name name, + RT_Info* &rtinfo) +{ + handle_t handle; + + // This makes a copy. We can optimize this with our own string + // class. + ACE_CString lookup (name); + // Search the map for the <name>. If found, return the RT_Info. + if (info_collection_.find (lookup, rtinfo) >= 0) + { + // If we find it, return. + return SUCCEEDED; + } + else + // Otherwise, make one, bind it, and register it. + { + rtinfo = new RT_Info; + rtinfo->info_type = RtecScheduler::OPERATION; + rtinfo->entry_point = name; + // Bind the rtinfo to the name. + if (info_collection_.bind (lookup, rtinfo) != 0) + { + delete rtinfo; + rtinfo = 0; + return FAILED; // Error! + } + else + { + // Register the task + status_t result = this->register_task (rtinfo, handle); + if (result == SUCCEEDED) + { + rtinfo->handle = handle; + return ST_UNKNOWN_TASK; // Didn't find it, but made one! + } + else + { + rtinfo->handle = 0; + return FAILED; + } + } + } +} + + + +int ACE_Scheduler::number_of_dependencies(RT_Info* rt_info) +{ + return rt_info->dependencies.length(); +} + +int ACE_Scheduler::number_of_dependencies(RT_Info& rt_info) +{ + return rt_info.dependencies.length(); +} + +int ACE_Scheduler::add_dependency(RT_Info* rt_info, + Dependency_Info& d) +{ + RT_Info *temp_info = 0; // temporary pointer to the caller's RT_Info + + switch (d.dependency_type) + { + case RtecScheduler::TWO_WAY_CALL: + + temp_info = rt_info; + break; + + case RtecScheduler::ONE_WAY_CALL: + + // swap the handles and point to the caller instead of the called operation + if (lookup_rt_info (d.rt_info, temp_info) != SUCCEEDED) + { + ACE_ERROR ((LM_ERROR, "cannot find %d to add dependency\n", d.rt_info)); + return -1; + } + + d.rt_info = temp_info->handle; + + default: + + ACE_ERROR ((LM_ERROR, "unrecognized dependency type %d for %s\n", + d.dependency_type, rt_info->entry_point)); + return -1; + break; + } + + ACE_DEBUG ((LM_DEBUG, "adding dependecy to: %s\n", + (const char*)temp_info->entry_point)); + + RtecScheduler::Dependency_Set& set = temp_info->dependencies; + int l = set.length(); + set.length(l + 1); + set[l] = d; + return 0; +} + +void ACE_Scheduler::export(RT_Info* info, FILE* file) +{ + export(*info, file); +} + +void ACE_Scheduler::export(RT_Info& info, FILE* file) +{ + // The divide-by-1 is for ACE_U_LongLong support. + (void) ACE_OS::fprintf (file, + "%s\n%d\n%ld\n%ld\n%ld\n%ld\n%d\n%d\n%ld\n%u\n" + "# begin calls\n%d\n", + (const char*)info.entry_point, + info.handle, + info.worst_case_execution_time / 1, + info.typical_execution_time / 1, + info.cached_execution_time / 1, + info.period, + info.criticality, + info.importance, + info.quantum / 1, + info.threads, + number_of_dependencies(info)); + + for (int i = 0; i < number_of_dependencies(info); ++i) + { + RT_Info tmp; + (void) ACE_OS::fprintf (file, "%s, %d\n", + (const char*)tmp.entry_point, + info.dependencies[i].number_of_calls); + + } + +// TBD - we'll need to update this to use the information aggregated +// within the task entry pointed to by the RT_Info's volatile_token +// ACT (in fact, there is now more than one +// priority assignment per RT_Info, w/ disjunction on multiple +// priority levels, rates, etc. - iterate through and show each dispatch) + + (void) ACE_OS::fprintf (file, "# end calls\n%d\n%d\n%d\n\n", + info.priority, + info.dynamic_subpriority, + info.static_subpriority); + + +} + + +ACE_Scheduler::status_t +ACE_Scheduler::lookup_rt_info (handle_t handle, + RT_Info*& rtinfo) +{ + if (handle < 0 || (size_t) handle > rt_info_entries_.size ()) + { + return ST_UNKNOWN_TASK; + } + + RT_Info** entry; + ACE_Unbounded_Set_Iterator <RT_Info *> i (rt_info_entries_); + while (i.next (entry) != 0) + { + i.advance (); + RT_Info* info_ptr = *entry; + if (info_ptr->handle == handle) + { + rtinfo = info_ptr; + return SUCCEEDED; + } + } + + return ST_UNKNOWN_TASK; +} + // obtains an RT_Info based on its "handle". + + +void +ACE_Scheduler::reset () +{ + // if the schedule is up to date, free resources + // and mark schedule as not being up to date + if (up_to_date_) + { + delete [] task_entries_; + task_entries_ = 0; + + delete [] ordered_task_entries_; + ordered_task_entries_ = 0; + + delete thread_delineators_; + thread_delineators_ = 0; + + delete [] ordered_thread_dispatch_entries_; + ordered_thread_dispatch_entries_ = 0; + + if (dispatch_entries_) + { + // free all the dispatch entries in the list, then the list itself + ACE_Unbounded_Set_Iterator <Dispatch_Entry *> iter (*dispatch_entries_); + Dispatch_Entry **entry = 0; + for (iter.first (); ! iter.done (); iter.advance (), entry = 0) + { + if ((iter.next (entry) != 0) && (entry) && (*entry)) + { + delete (*entry); + } + } + delete dispatch_entries_; + dispatch_entries_ = 0; + } + + delete [] ordered_dispatch_entries_; + ordered_dispatch_entries_ = 0; + + dispatch_entry_count_ = 0; + threads_ = 0; + + status_ = NOT_SCHEDULED; + + frame_size_ = 1; + critical_set_frame_size_ = 0; + utilization_ = 0.0; + critical_set_utilization_ = 0.0; + minimum_priority_queue_ = 0; + minimum_guaranteed_priority_queue_ = -1; + + if (timeline_) + { + // iterate over and delete the set of timeline entries + ACE_Ordered_MultiSet_Iterator <TimeLine_Entry_Link> t_iter (*timeline_); + TimeLine_Entry_Link *t_entry = 0; + for (t_iter.first (); ! t_iter.done (); t_iter.advance (), t_entry = 0) + { + if ((t_iter.next (t_entry) != 0) && (t_entry)) + { + delete &(t_entry->entry ()); + } + } + delete timeline_; + timeline_ = 0; + } + + up_to_date_ = 0; + } +} + +ACE_Scheduler::status_t +ACE_Scheduler::schedule (void) +{ + ACE_Guard<LOCK> ace_mon (lock_); + + if (up_to_date_) + { + // do nothing if the RT_Infos have not changed + // since the last valid schedule was generated + return SUCCEEDED; + } + else + { + // save the total number of registered RT_Infos + tasks (rt_info_entries_.size ()); + } + + // set up the task entry data structures, check for call cycles + status_ = setup_task_entries (); + + if (status_ == SUCCEEDED) + { + // check for cycles in the dependency graph: as a side effect, leaves + // the ordered_task_entries_ pointer array sorted in topological order, + // which is used by propagate_dispatches () to ensure that dispatches + // are propagated top down in the call graph. + status_ = check_dependency_cycles (); + } + + if (status_ == SUCCEEDED) + { + // task entries are related, now threads can be found + status_ = identify_threads (); + } + + if (status_ == SUCCEEDED) + { + // invokes the internal thread scheduling method of the strategy + status_ = schedule_threads (); + } + + if (status_ == SUCCEEDED) + { + // propagate the dispatch information from the + // threads throughout the call graph + status_ = propagate_dispatches (); + } + + if (status_ == SUCCEEDED) + { + // invokes the internal dispatch scheduling method of the strategy + status_ = schedule_dispatches (); + } + + // calculate utilization, total frame size, critical set + if (status_ == SUCCEEDED) + { + status_ = calculate_utilization_params (); + } + + // generate the scheduling timeline over the total frame size + if ((status_ == SUCCEEDED) || (status_ == ST_UTILIZATION_BOUND_EXCEEDED)) + { + status_ = create_timeline (); + } + + // store the timeline to a file if one was given + if ((timeline_filename_ != 0) && + ((status_ == SUCCEEDED) || (status_ == ST_UTILIZATION_BOUND_EXCEEDED))) + { + status_ = output_timeline (timeline_filename_, 0); + } + + + // if a valid schedule was not generated, clean up from the attempt + switch (status_) + { + // these are statuses that indicate a reasonable schedule was generated + case SUCCEEDED: + case ST_UTILIZATION_BOUND_EXCEEDED: + + // if we made it here, the schedule is done + up_to_date_ = 1; + + + break; + + default: + + // (try to) remove the output files + if (timeline_filename_ && unlink ((char *) timeline_filename_) && + errno != ENOENT) + { + ACE_OS::perror ("ACE_Scheduler::schedule (); " + "unable to remove timeline file"); + } + if (runtime_filename_ && unlink ((char *) runtime_filename_) && + errno != ENOENT) + { + ACE_OS::perror ("ACE_Scheduler::schedule (); " + "unable to remove schedule file"); + } + if (rt_info_filename_ && unlink ((char *) rt_info_filename_) && + errno != ENOENT) + { + ACE_OS::perror ("ACE_Scheduler::schedule (); " + "unable to remove rt_info file"); + } + + // free resources and remove "up_to_date" mark + reset (); + + break; + } + + + return status_; +} + +ACE_Scheduler::status_t +ACE_Scheduler::propagate_dispatches () +{ + // iterate through the ordered_task_entries_ array in order + // from highest DFS finishing time to lowest, so that every + // calling dispatch is accessed before those it calls: + // the dispatches propagate top down through the call DAG + for (u_int i = 0; i < tasks (); ++i) + { + if (ordered_task_entries_ [i]->merge_dispatches (*dispatch_entries_) < 0) + { + return ST_UNKNOWN_TASK; + } + } + + return SUCCEEDED; +} +// propagate the dispatch information from the +// threads throughout the call graph + + + +ACE_Scheduler::status_t +ACE_Scheduler::calculate_utilization_params (void) +{ + status_t status = SUCCEEDED; + + frame_size_ = + ordered_dispatch_entries_ [0]->task_entry ().effective_period (); + + critical_set_frame_size_ = 0; + utilization_ = 0.0; + critical_set_utilization_ = 0.0; + + minimum_priority_queue_ = + ordered_dispatch_entries_ [0]->priority (); + + minimum_guaranteed_priority_queue_ = -1; + + // iterate through ordered task entries, calculating frame size, utilization + for (u_int i = 1; i < dispatch_entry_count_; ++i) + { + // hold the effective period of the task entry to which the dispatch refers + Period period = + ordered_dispatch_entries_ [i]->task_entry ().effective_period (); + + // if we've just finished examining another priority level + if (minimum_priority_queue_ != ordered_dispatch_entries_ [i]->priority ()) + { + // update parameters for the previous priority level + update_priority_level_params (); + + // update the minimum priority queue + minimum_priority_queue_ = ordered_dispatch_entries_ [i]->priority (); + } + + // only consider computation times of dispatches on OPERATION descriptors + if (ordered_dispatch_entries_ [i]->task_entry ().info_type () == + RtecScheduler::OPERATION) + { + utilization_ += + ACE_static_cast(double, + ordered_dispatch_entries_ [i]-> + task_entry ().rt_info ()-> + worst_case_execution_time) / + ACE_static_cast(double, period); + + } + + if (period) + { + // grow frame size by new factors that are not in gcd of the + // frame size and the newly considered entry's effective period + frame_size_ = + minimum_frame_size (frame_size_, period); + } + } + + // update parameters for the lowest priority level + update_priority_level_params (); + + return status; +} + + +void +ACE_Scheduler::update_priority_level_params () +{ + // if we've just finished examining the lowest critical priority level + if (minimum_priority_queue_ == minimum_critical_priority ()) + { + // update the information about the critical set + critical_set_frame_size_ = frame_size_; + critical_set_utilization_ = utilization_; + } + + // if the lowest priority level considered is schedulable + if (1.0 - utilization_ > DBL_EPSILON) + { + // the minimum guaranteed priority queue is the minimum considered so far + minimum_guaranteed_priority_queue_ = minimum_priority_queue_; + } +} + +ACE_Scheduler::status_t +ACE_Scheduler::setup_task_entries (void) +{ + // store number of tasks, based on registrations + tasks (rt_info_entries_.size ()); + + // clear the decks of any previous scheduling information + reset (); + + // allocate new table of task entries (wrappers for rt_infos) + ACE_NEW_RETURN (task_entries_, Task_Entry [tasks ()], + ST_VIRTUAL_MEMORY_EXHAUSTED); + + // allocate new table of pointers to task entries (for sorting) + ACE_NEW_RETURN (ordered_task_entries_, Task_Entry *[tasks ()], + ST_VIRTUAL_MEMORY_EXHAUSTED); + ACE_OS::memset (ordered_task_entries_, 0, + sizeof (Task_Entry *) * tasks ()); + + // allocate new unbounded set for pointers to + // task entries that delineate threads + ACE_NEW_RETURN (thread_delineators_, ACE_Unbounded_Set <Dispatch_Entry *>, + ST_VIRTUAL_MEMORY_EXHAUSTED); + + // allocate new unbounded set for pointers to dispatch entries + ACE_NEW_RETURN (dispatch_entries_, + ACE_Unbounded_Set <Dispatch_Entry *>, + ST_VIRTUAL_MEMORY_EXHAUSTED); + + + // set up links between rt_info_entries_, task_entries_, + // and ordered_task_entries_ tables + ACE_Unbounded_Set_Iterator <RT_Info *> iter (rt_info_entries_); + for (u_int i = 0; i < tasks (); ++i, iter.advance ()) + { + RT_Info** info_entry; + + // tie task entry to corresponding rt_info + if (! iter.next (info_entry)) + { + return ST_UNKNOWN_TASK; + } + task_entries_ [i].rt_info (*info_entry); + + // tie rt_info to corresponding task entry + task_entries_ [i].rt_info ()->volatile_token = (u_long) &(task_entries_ [i]); + + // tie ordered task entry pointer to corresponding task entry + ordered_task_entries_ [i] = &(task_entries_ [i]); + } + + // set up bidirectional links between task entries + return relate_task_entries (); +} + +ACE_Scheduler::status_t +ACE_Scheduler::relate_task_entries (void) +{ + status_t status = SUCCEEDED; + + // do DFS traversal of the entire RT_Info handle dependency DAG, replicating + // the handle dependency DAG as a calls DAG of pointers between task + // entries (and creating its transpose, the callers DAG). This is done + // to avoid the O(n) cost of handle lookups in the RT_Infos for further + // traversal of the graph during schedule sorting. One useful side effect + // of this traversal is that is produces a topological ordering of dependencies + // in the traversal finishing times, which can be used to detect call cycles. + long time = 0; + + for (u_int i = 0; i < tasks (); ++i) + { + if ((status = relate_task_entries_recurse (time, task_entries_[i])) + != SUCCEEDED) + { + break; + } + } + + return status; +} + +ACE_Scheduler::status_t +ACE_Scheduler::relate_task_entries_recurse (long &time, Task_Entry &entry) +{ + + // may have entered at a non-root node previously, so this does + // not necessarily indicate a cycle in the dependency graph + if (entry.dfs_status () != Task_Entry::NOT_VISITED) + { + return SUCCEEDED; + } + + // when a node is discovered, mark it as visited, increment "time" and + // store as the entry's discovery time. This is not currently used in + // the scheduling algorithms, but is left in for possible future use + // as it shows full parenthetization of entry discovery/finishing. + entry.dfs_status (Task_Entry::VISITED); + entry.discovered (++time); + + u_int dependency_count = number_of_dependencies (*entry.rt_info ()); + if (dependency_count > 0) + { + // traverse dependencies of underlying RT_Info + for (u_int i = 0; i < dependency_count; ++i) + { + // obtain a pointer to the corresponding Task_Entry for each dependency + + RT_Info* dependency_info = 0; + lookup_rt_info(entry.rt_info ()->dependencies[i].rt_info, dependency_info); + + if (! dependency_info) + { + return ST_UNKNOWN_TASK; + } + + // obtain a pointer to the Task_Entry from the dependency RT_Info + Task_Entry *dependency_entry_ptr = + (Task_Entry *) dependency_info->volatile_token; + + if (! dependency_entry_ptr) + { + return ST_UNKNOWN_TASK; + } + + // relate the entries according to the direction of the dependency + Task_Entry_Link *link; + ACE_NEW_RETURN (link, + Task_Entry_Link (entry, + *dependency_entry_ptr, + entry.rt_info ()->dependencies[i].number_of_calls, + entry.rt_info ()->dependencies[i].dependency_type), + ST_VIRTUAL_MEMORY_EXHAUSTED); + + dependency_entry_ptr->callers ().insert (link); + entry.calls ().insert (link); + + // depth first recursion on the newly identified entry + relate_task_entries_recurse (time, *dependency_entry_ptr); + } + } + + // when a node is finished, mark it as finished, increment "time" and + // store as the entry's finish time. This produces a topological ordering + // based on dependencies, which is used to check for call cycles. + entry.dfs_status (Task_Entry::FINISHED); + entry.finished (++time); + + return SUCCEEDED; +} + +ACE_Scheduler::status_t +ACE_Scheduler::identify_threads (void) +{ + u_int i, j; + + // walk array of task entries, picking out thread delineators + for (i = 0; i < tasks_; i++) + { + // if entry has exposed threads or no callers, it may be a thread + if ((task_entries_ [i].rt_info ()->threads > 0) || + (task_entries_ [i].callers ().is_empty ())) + { + // if its period is valued, it's a thread delineator + if (task_entries_ [i].rt_info ()->period > 0) + { + task_entries_ [i].effective_period (task_entries_ [i].rt_info ()->period); + task_entries_ [i].is_thread_delineator (1); + + // create a Dispatch_Entry for each thread of the delimiting Task_Entry + u_int thread_count = (task_entries_ [i].rt_info ()->threads > 0) + ? task_entries_ [i].rt_info ()->threads : 1; + for (j = 0; j < thread_count; j++) + { + Dispatch_Entry *dispatch_ptr; + ACE_NEW_RETURN(dispatch_ptr, + Dispatch_Entry (0, task_entries_ [i].effective_period (), + task_entries_ [i].rt_info ()->preemption_priority, + task_entries_ [i]), + ST_VIRTUAL_MEMORY_EXHAUSTED); + + if ((task_entries_ [i].dispatches ().insert (Dispatch_Entry_Link (*dispatch_ptr)) < 0) || + (dispatch_entries_->insert (dispatch_ptr) < 0) || + (thread_delineators_->insert (dispatch_ptr) < 0)) + { + return ST_VIRTUAL_MEMORY_EXHAUSTED; + } + + // increase the count of thread dispatches + ++ threads_; + } + } + else + { + // node that no one calls and has neither rate nor threads is suspect + ACE_ERROR_RETURN ( + (LM_ERROR, + "An operation identified by \"%s\" does not specify a period or\n" + "visible threads, and is not called by any other operation. " + "Are there backwards dependencies?\n", + (const char*) task_entries_ [i].rt_info ()->entry_point), + ST_BAD_DEPENDENCIES_ON_TASK); + } + } + } + + return SUCCEEDED; +} + +ACE_Scheduler::status_t +ACE_Scheduler::check_dependency_cycles (void) +{ + status_t return_status = SUCCEEDED; + + // sort the pointers to entries in order of descending finish time + ::qsort ((void *) ordered_task_entries_, + tasks (), + sizeof (Task_Entry *), + compare_entry_finish_times); + + // set all the dfs_status indicators to NOT_VISITED + u_int i; + for (i = 0; i < tasks (); ++i) + { + ordered_task_entries_ [i]->dfs_status (Task_Entry::NOT_VISITED); + } + + // recurse on each entry, saving most recent status if it is not SUCCEEDED + for (i = 0; i < tasks (); ++i) + { + status_t status = + check_dependency_cycles_recurse (*ordered_task_entries_ [i]); + + if (status != SUCCEEDED) + { + return_status = status; + } + } + + return return_status; +} + // uses strongly connected components algorithm: consider entries + // in order of finishing time from dependency DAG traversal, + // but traverse transpose graph: any entry that has a dependant + // that was not previously visited in this traversal is part + // of a dependency cycle + + +ACE_Scheduler::status_t +ACE_Scheduler::check_dependency_cycles_recurse (Task_Entry &entry) +{ + status_t return_status = SUCCEEDED; + + // halt DFS recursion on callers graph if entry has already been visited + if (entry.dfs_status () != Task_Entry::NOT_VISITED) + { + return return_status; + } + + // mark the entry as visited + entry.dfs_status (Task_Entry::VISITED); + + // check all the calling operations: if there is one that has not already been + // visited, mark the return status indicating there is a cycle, print + // an error message to that effect, and recurse on that dependant + Task_Entry_Link **calling_entry_link; + ACE_Unbounded_Set_Iterator <Task_Entry_Link *> i (entry.callers ()); + while (i.next (calling_entry_link) != 0) + { + i.advance (); + if ((*calling_entry_link)->caller ().dfs_status () == Task_Entry::NOT_VISITED) + { + // indicate the two tasks are in (the same) dependency cycle + ACE_ERROR ((LM_ERROR, + "Tasks \"%s\" and \"%s\" are part of a call cycle.\n", + (*calling_entry_link)->caller ().rt_info ()->entry_point, + entry.rt_info ()->entry_point)); + + // set return status, ignore status returned by recursive call: + // we already know there are cycles in the dependencies + return_status = ST_CYCLE_IN_DEPENDENCIES; + check_dependency_cycles_recurse ((*calling_entry_link)->caller ()); + } + } + + // mark the entry as finished + entry.dfs_status (Task_Entry::FINISHED); + + return return_status; +} + + +ACE_Scheduler::status_t +ACE_Scheduler::schedule_threads (void) +{ + // make sure there are as many thread delineator + // entries in the set as the counter indicates + if (threads_ != thread_delineators_->size ()) + { + return THREAD_COUNT_MISMATCH; + } + + // allocate an array of pointers to the thread delineators + ACE_NEW_RETURN (ordered_thread_dispatch_entries_, + Dispatch_Entry * [threads_], + ST_VIRTUAL_MEMORY_EXHAUSTED); + ACE_OS::memset (ordered_thread_dispatch_entries_, 0, + sizeof (Dispatch_Entry *) * threads_); + + + // copy pointers to the thread delineators from the set to the array + ACE_Unbounded_Set_Iterator <Dispatch_Entry *> iter (*thread_delineators_); + for (u_int i = 0; i < threads_; ++i, iter.advance ()) + { + Dispatch_Entry** dispatch_entry; + + if (! iter.next (dispatch_entry)) + { + return ST_UNKNOWN_TASK; + } + + ordered_thread_dispatch_entries_ [i] = *dispatch_entry; + } + + // sort the thread dispatch entries into priority order + status_t status = sort_dispatches (ordered_thread_dispatch_entries_, threads_); + + if (status == SUCCEEDED) + { + // assign priorities to the thread dispatch entries + status == assign_priorities (ordered_thread_dispatch_entries_, threads_); + } + + return status; +} + // thread scheduling method: sets up array of pointers to task + // entries that are threads, calls internal thread scheduling method + +ACE_Scheduler::status_t +ACE_Scheduler::schedule_dispatches (void) +{ + dispatch_entry_count_ = dispatch_entries_->size (); + + ACE_NEW_RETURN (ordered_dispatch_entries_, + Dispatch_Entry * [dispatch_entry_count_], + ST_VIRTUAL_MEMORY_EXHAUSTED); + ACE_OS::memset (ordered_dispatch_entries_, 0, + sizeof (Dispatch_Entry *) * dispatch_entry_count_); + + + + ACE_Unbounded_Set_Iterator <Dispatch_Entry *> iter (*dispatch_entries_); + for (u_int i = 0; i < dispatch_entry_count_; ++i, iter.advance ()) + { + Dispatch_Entry** dispatch_entry; + + if (! iter.next (dispatch_entry)) + { + return ST_UNKNOWN_TASK; + } + + ordered_dispatch_entries_ [i] = *dispatch_entry; + } + + // sort the entries in order of priority and subpriority + sort_dispatches (ordered_dispatch_entries_, dispatch_entry_count_); + + // assign dynamic and static subpriorities to the thread dispatch entries + return assign_subpriorities (ordered_dispatch_entries_, dispatch_entry_count_); +} + // dispatch scheduling method: sets up an array of dispatch entries, + // calls internal dispatch scheduling method. + +ACE_Scheduler::status_t +ACE_Scheduler::create_timeline () +{ + + ACE_NEW_RETURN(timeline_, ACE_Ordered_MultiSet <TimeLine_Entry_Link>, + ST_VIRTUAL_MEMORY_EXHAUSTED); + + for (u_int i = 0; i < dispatch_entry_count_; ++i) + { + // only put OPERATION dispatches into the timeline. + if (ordered_dispatch_entries_[i]->task_entry().info_type () != + RtecScheduler::OPERATION) + { + continue; + } + + + // timeline entries cover the execution time of the dispatch + u_long remaining_time = + ordered_dispatch_entries_[i]->task_entry().rt_info ()-> + worst_case_execution_time; + + // initialize last stop time to beginning of frame + u_long last_stop = 0; + + TimeLine_Entry *last_entry = 0; + TimeLine_Entry *current_entry = 0; + ACE_Ordered_MultiSet_Iterator <TimeLine_Entry_Link> iter (*timeline_); + for (iter.first (); (remaining_time > 0) && (iter.done () == 0); + iter.advance ()) + { + TimeLine_Entry_Link *link; + if ((iter.next (link) == 0) || (! link)) + { + return ST_BAD_INTERNAL_POINTER; + } + + // if there's room, schedule a new timeline entry for the dispatch + if (link->entry ().start() > last_stop) + { + ACE_NEW_RETURN ( + current_entry, + TimeLine_Entry ( + *(ordered_dispatch_entries_[i]), + last_stop, + (((remaining_time + last_stop) < link->entry ().start()) + ? (remaining_time + last_stop) : link->entry ().start()), + 0, last_entry), + ST_VIRTUAL_MEMORY_EXHAUSTED); + + // patch up the pointers within the list of entries for this dispatch + if (last_entry) + { + last_entry->next (current_entry); + } + last_entry = current_entry; + + timeline_->insert(TimeLine_Entry_Link(*current_entry)); + + // update the remaining time and last stop values + remaining_time -= ((remaining_time < (link->entry ().start() - last_stop)) + ? remaining_time : (link->entry ().start() - last_stop)); + } + + // update the last stop time + last_stop = link->entry ().stop (); + } + + // if there is still dispatch time remaining, and we've + // reached the end of the list, insert what's left + if (remaining_time > 0) + { + ACE_NEW_RETURN ( + current_entry, + TimeLine_Entry ( + *(ordered_dispatch_entries_[i]), + last_stop, + remaining_time + last_stop, + 0, last_entry), + ST_VIRTUAL_MEMORY_EXHAUSTED); + + // patch up the pointers within the list of entries for this dispatch + if (last_entry) + { + last_entry->next (current_entry); + } + + timeline_->insert(TimeLine_Entry_Link(*current_entry)); + } + + } + + return SUCCEEDED; +} + // Create a timeline. + +ACE_Scheduler::status_t +ACE_Scheduler::output_dispatch_timeline (const char *filename) +{ + status_t status = UNABLE_TO_OPEN_SCHEDULE_FILE; + + // open the file + FILE *file = ACE_OS::fopen (filename, "w"); + if (file) + { + status = output_dispatch_timeline (file); + fclose (file); + } + + return status; +} + +ACE_Scheduler::status_t +ACE_Scheduler::output_dispatch_timeline (FILE *file) +{ + if (ACE_OS::fprintf ( + file, "\n\nSCHEDULING RESULTS:\n\n" + "Number of dispatches: %u\n" + "Number of threads: %u\n" + "Number of tasks: %u\n" + "Scheduler Status: [%d] %s\n" + "Total Frame Size: %lu nsec (%lf Hz)\n" + "Critical Set Frame Size: %lu nsec (%lf Hz)\n" + "Utilization: %lf\n" + "Critical Set Utilization: %lf\n" + "Minimum Priority Queue: %ld\n" + "Minimum Guaranteed Priority Queue: %ld\n\n\n" + "DISPATCH TIMELINE:\n\n" + " dispatch dynamic static arrival deadline start stop execution\n" + "operation ID priority subpriority subpriority (nsec) (nsec) (nsec) (nsec) time (nsec)\n" + "--------- -------- -------- ----------- ----------- ------- -------- ----- ------ -----------\n\n", + dispatch_entry_count_, threads_, tasks_, status_, + status_message(status_), frame_size_, (double) (10000000.0 / ((double) frame_size_)), + critical_set_frame_size_, (double) (10000000.0 / ((double) critical_set_frame_size_)), + utilization_, critical_set_utilization_, minimum_priority_queue_, + minimum_guaranteed_priority_queue_) < 0) + { + return UNABLE_TO_WRITE_SCHEDULE_FILE; + } + + // iterate through timeline, picking out entries whose prev_ pointer + // is null (i.e. those representing the start of a dispatch), find end + // of dispatch, output the operation, dispatch, priority, and time info + ACE_Ordered_MultiSet_Iterator <TimeLine_Entry_Link> iter (*timeline_); + for (iter.first (); iter.done () == 0; iter.advance ()) + { + TimeLine_Entry_Link *link; + if ((iter.next (link) == 0) || (! link)) + { + return ST_BAD_INTERNAL_POINTER; + } + + // for each timeline entry that starts a new dispatch + if (link->entry ().prev () == 0) + { + // find the last time slice for the dispatch + TimeLine_Entry *last_entry = &(link->entry ()); + while (last_entry->next ()) + { + last_entry = last_entry->next (); + } + + if (ACE_OS::fprintf ( + file, "%-9s %8lu %8lu %11lu %11lu %7lu %8lu %8lu %8lu %10lu\n", + link->entry ().dispatch_entry ().task_entry ().rt_info ()-> + entry_point, + link->entry ().dispatch_entry ().dispatch_id (), + link->entry ().dispatch_entry ().priority (), + link->entry ().dispatch_entry ().dynamic_subpriority (), + link->entry ().dispatch_entry ().static_subpriority (), + link->entry ().dispatch_entry ().arrival (), + link->entry ().dispatch_entry ().deadline (), + link->entry ().start (), last_entry->stop (), + link->entry ().dispatch_entry ().task_entry ().rt_info ()-> + worst_case_execution_time) < 0) + + { + return UNABLE_TO_WRITE_SCHEDULE_FILE; + } + } + } + + return SUCCEEDED; +} + // this prints the entire set of timeline outputs to the specified file + +ACE_Scheduler::status_t +ACE_Scheduler::output_preemption_timeline (const char *filename) +{ + status_t status = UNABLE_TO_OPEN_SCHEDULE_FILE; + + // open the file + FILE *file = ACE_OS::fopen (filename, "w"); + if (file) + { + status = output_preemption_timeline (file); + fclose (file); + } + + return status; +} + +ACE_Scheduler::status_t +ACE_Scheduler::output_preemption_timeline (FILE *file) +{ + if (ACE_OS::fprintf ( + file, "\n\nPREEMPTION TIMELINE:\n\n" + " start stop\n" + "operation dispatch id (nsec) (nsec)\n" + "--------- ----------- ------ ------\n\n") < 0) + { + return UNABLE_TO_WRITE_SCHEDULE_FILE; + } + + ACE_Ordered_MultiSet_Iterator <TimeLine_Entry_Link> iter (*timeline_); + + TimeLine_Entry_Link *link; + for (iter.first (); iter.done () == 0; iter.advance ()) + { + if ((iter.next (link) == 0) || (! link)) + { + return ST_BAD_INTERNAL_POINTER; + } + + if (ACE_OS::fprintf ( + file, "%-9s %11lu %8lu %8lu\n", + link->entry ().dispatch_entry ().task_entry ().rt_info ()-> + entry_point, + link->entry ().dispatch_entry ().dispatch_id (), + link->entry ().start (), + link->entry ().stop ()) < 0) + { + return UNABLE_TO_WRITE_SCHEDULE_FILE; + } + } + + return SUCCEEDED; +} + // this prints the entire set of timeline outputs to the specified file + +ACE_Scheduler::status_t +ACE_Scheduler::output_timeline (const char *filename, const char *heading) +{ + status_t status = SUCCEEDED; + FILE *file; + + // bail out if we're not up to date or there is no timeline + if ((! up_to_date_) || (! timeline_)) + { + status = NOT_SCHEDULED; + } + + if (status == SUCCEEDED) + { + // open the file + file = ACE_OS::fopen (filename, "w"); + if (! file) + { + status = UNABLE_TO_OPEN_SCHEDULE_FILE; + } + } + + if ((status == SUCCEEDED) && (heading)) + { + if (ACE_OS::fprintf (file, "%s\n\n", heading) < 0) + { + status = UNABLE_TO_WRITE_SCHEDULE_FILE; + } + } + + if (status == SUCCEEDED) + { + status = output_dispatch_timeline (file); + } + + if (status == SUCCEEDED) + { + status = output_preemption_timeline (file); + } + + if (file) + { + fclose (file); + } + + return status; +} + // this prints the entire set of timeline outputs to the specified file + + + +// CDG - TBD - need to compile on Sun OS5 and make sure +// the correct template instantiations are present + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Lock_Adapter<ACE_SYNCH_NULL_MUTEX>; +template class ACE_Map_Entry<ACE_CString, ACE_Scheduler::RT_Info **>; + + template class ACE_Lock_Adapter<ACE_SYNCH_RW_MUTEX>; + template class ACE_Lock_Adapter<ACE_SYNCH_MUTEX>; + template class ACE_Map_Manager<ACE_CString, + ACE_Scheduler::RT_Info **, + ACE_SYNCH_MUTEX>; + template class ACE_Map_Iterator_Base<ACE_CString, ACE_Scheduler::RT_Info **, + ACE_SYNCH_MUTEX>; + template class ACE_Map_Iterator<ACE_CString, ACE_Scheduler::RT_Info **, + ACE_SYNCH_MUTEX>; + template class ACE_Map_Reverse_Iterator<ACE_CString, ACE_Scheduler::RT_Info **, + ACE_SYNCH_MUTEX>; + template class ACE_Read_Guard<ACE_SYNCH_MUTEX>; + template class ACE_Write_Guard<ACE_SYNCH_MUTEX>; + + template class ACE_Ordered_MultiSet<Dispatch_Entry_Link>; + template class ACE_Ordered_MultiSet_Iterator<Dispatch_Entry_Link>; + template class ACE_DNode<Dispatch_Entry_Link>; + +#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate ACE_Lock_Adapter<ACE_SYNCH_NULL_MUTEX> +#pragma instantiate ACE_Map_Entry<ACE_CString, ACE_Scheduler::RT_Info **> + +#pragma instantiate ACE_Lock_Adapter<ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Lock_Adapter<ACE_SYNCH_MUTEX> +#pragma instantiate ACE_Map_Manager<ACE_CString, ACE_Scheduler::RT_Info **, ACE_SYNCH_MUTEX> +#pragma instantiate ACE_Map_Iterator_Base<ACE_CString, ACE_Scheduler::RT_Info **, ACE_SYNCH_MUTEX> +#pragma instantiate ACE_Map_Iterator<ACE_CString, ACE_Scheduler::RT_Info **, ACE_SYNCH_MUTEX> +#pragma instantiate ACE_Map_Reverse_Iterator<ACE_CString, ACE_Scheduler::RT_Info **, ACE_SYNCH_MUTEX> +#pragma instantiate ACE_Read_Guard<ACE_SYNCH_MUTEX> +#pragma instantiate ACE_Write_Guard<ACE_SYNCH_MUTEX> + +#pragma instantiate ACE_Ordered_MultiSet<Dispatch_Entry_Link>; +#pragma instantiate ACE_Ordered_MultiSet_Iterator<Dispatch_Entry_Link>; +#pragma instantiate ACE_DNode<Dispatch_Entry_Link>; + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + +// EOF + diff --git a/TAO/orbsvcs/orbsvcs/Sched/DynSched.h b/TAO/orbsvcs/orbsvcs/Sched/DynSched.h new file mode 100644 index 00000000000..41fdbe11f1e --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/DynSched.h @@ -0,0 +1,464 @@ +/* -*- C++ -*- */ +// +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// DynSched.h +// +// = CREATION DATE +// 23 January 1997 +// +// = AUTHOR +// Chris Gill +// +// ============================================================================ + +#if ! defined (SCHEDULER_H) +#define SCHEDULER_H + +#include "ace/ACE.h" +#include "ace/Map_Manager.h" +#include "ace/Message_Block.h" +#include "ace/Synch.h" +#include "ace/SString.h" +#include "SchedEntry.h" + +class ACE_Scheduler + // = TITLE + // Thread scheduler interface. + // + // = DESCRIPTION + // This abstract base class provides the majority of the + // implementation of either an off-line scheduler, or the + // necessary on-line component of the Scheduler. +{ +public: + + ////////////////////////////// + // public type declarations // + ////////////////////////////// + + typedef RtecScheduler::handle_t handle_t; + typedef RtecScheduler::Dependency_Info Dependency_Info; + typedef RtecScheduler::Preemption_Priority Preemption_Priority; + typedef RtecScheduler::OS_Priority OS_Priority; + typedef RtecScheduler::Sub_Priority Sub_Priority; + typedef RtecScheduler::RT_Info RT_Info; + typedef RtecScheduler::Time Time; + typedef RtecScheduler::Period Period; + typedef RtecScheduler::Info_Type Info_Type; + typedef RtecScheduler::Dependency_Type Dependency_Type; + + typedef ACE_Map_Entry <ACE_CString, RT_Info *> Thread_Map_Entry; + typedef ACE_Map_Manager <ACE_CString, RT_Info *, ACE_Null_Mutex> + Thread_Map; + typedef ACE_Map_Iterator <ACE_CString, RT_Info *, ACE_Null_Mutex> + Thread_Map_Iterator; + + typedef const char *Object_Name; + // Objects are named by unique strings. + + enum status_t { + // The following are used both by the runtime Scheduler and during + // scheduling. + NOT_SCHEDULED = -1 // the schedule () method has not been called yet + , FAILED = -1 + , SUCCEEDED + , ST_UNKNOWN_TASK + , ST_TASK_ALREADY_REGISTERED + , ST_BAD_DEPENDENCIES_ON_TASK + , ST_BAD_INTERNAL_POINTER + , ST_VIRTUAL_MEMORY_EXHAUSTED + + // The following are only used by the runtime Scheduler. + , TASK_COUNT_MISMATCH // only used by schedule () + , THREAD_COUNT_MISMATCH // only used by schedule () + , INVALID_PRIORITY // only used by schedule (): mismatch of + // (off-line, maybe) Scheduler output to + // the runtime Scheduler component. + + // The following are only used during scheduling (in the case of + // off-line scheduling, they are only used prior to runtime). + , ST_UTILIZATION_BOUND_EXCEEDED + , ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS + , ST_CYCLE_IN_DEPENDENCIES + , ST_INVALID_PRIORITY_ORDERING + , UNABLE_TO_OPEN_SCHEDULE_FILE + , UNABLE_TO_WRITE_SCHEDULE_FILE + }; + + + + ///////////////////////////// + // public member functions // + ///////////////////////////// + + virtual ~ACE_Scheduler (); + // public dtor + + // = Utility function for outputting the textual + // representation of a status_t value. + static const char * status_message (status_t status); + + // = Initialize the scheduler. + void init (const OS_Priority minimum_priority, + const OS_Priority maximum_priority, + const char *runtime_filename = 0, + const char *rt_info_filename = 0, + const char *timeline_filename = 0); + // The minimum and maximum priority are the OS-specific priorities that + // are used when creating the schedule (assigning priorities). The + // minimum_priority is the priority value of the lowest priority. + // It may be numerically higher than the maximum_priority, on OS's such + // as VxWorks that use lower values to indicate higher priorities. + // + // When Scheduler::schedule is called, the schedule is output to the + // file named by "runtime_filename" if it is non-zero. + // This file is compilable; it is linked into the runtime executable + // to provide priorities to the runtime scheduling component. + // If the "rt_info_filename" is non-zero, the RT_Info for + // every task is exported to it. It is not used at runtime. + // If the "timeline_filename" is non-zero, the timeline output + // file is created. It is not used at runtime. + // + // The runtime scheduling component ignores these filenames. It just + // uses the priorities that were linked in to the executable, after + // converting them to platform-specific values. + + void reset (); + // Prepare for another schedule computation: once a reasonable schedule + // has been generated, a new schedule will not be computed unless an + // RT_Info is added, or this method is invoked to clear the previous + // schedule (allows fault correcting alteration of RT_Infos outside the + // scheduler implementation, followed by generation of a new schedule). + + // = Registers a task. + status_t register_task (RT_Info *, handle_t &handle); + // If the Task registration succeeds, this function returns SUCCEEDED + // and sets "handle" to a unique identifier for the task. + // Otherwise, it returns either VIRTUAL_MEMORY_EXHAUSTED or + // TASK_ALREADY_REGISTERED sets the handle to 0. (A task may + // only be registered once.) + + status_t get_rt_info (Object_Name name, RT_Info* &rtinfo); + // Tries to find the RT_Info corresponding to <name> in the RT_Info + // database. Returns SUCCEEDED if <name> was found and <rtinfo> was + // set. Returns UNKNOWN_TASK if <name> was not found, but <rtinfo> + // was set to a newly allocated RT_Info. In this UNKNOWN_TASK case, + // the task must call RT_Info::set to fill in execution properties. + // In the SUCCEEDED and UNKNOWN_TASK cases, this->register_task + // (rtinfo, 0, handle) is called. Returns FAILED if an error + // occurs. + // + // One motivation for allocating RT_Info's from within the Scheduler + // is to allow RT_Infos to persist after the tasks that use them. + // For instance, we may want to call this->schedule right before the + // application exits a configuration run. If the tasks have been + // deleted (deleting their RT_Infos with them), this->schedule will + // fail. + + status_t lookup_rt_info (handle_t handle, RT_Info* &rtinfo); + // Obtains an RT_Info based on its "handle". + + status_t schedule (void); + // This sets up the data structures, invokes the internal scheduling method. + + status_t output_timeline (const char *filename, const char *heading); + // this prints the entire set of timeline outputs to the specified file + + // = Access a thread priority. +// TBD - put this back in, but with dynamic subpriority as well as static +// int priority (const handle_t handle, +// OS_Priority &OS_priority, +// Preemption_Priority &preemption_priority, +// Sub_Priority &dynamic_subpriority, +// Sub_Priority &static_subpriority); + // Defines "priority" as the priority that was assigned to the Task that + // was assigned "handle". Defines "dynamic subpriority" as the strategy + // specific assignment of dynamic subpriority within a priority level, and + // "static subpriority" as the minimal importance and topological ordering. + // Returns 0 on success, or -1 if an invalid handle was supplied. + // Queue numbers are platform-independent priority values, ranging from + // a highest priority value of 0 to the lowest priority value, which is + // returned by "minimum_priority_queue ()". + + // = Access the platform-independent priority value of the lowest-priority + // thread. + + Preemption_Priority minimum_priority_queue () const; + // This is intended for use by the Event Channel, so it can determine the + // number of priority dispatch queues to create. + + // = Access the number of tasks. + u_int tasks () const; + + // = Access the number of threads. + u_int threads () const; + + // = Access the current scheduler status. + status_t status () const; + + // = Access the current output (debugging) level. + u_int output_level () const; + // Default is 0; set to 1 to print out schedule, by task. Set + // to higher than one for debugging info. + + // = Set the scheduler output (debugging) level. + void output_level (const u_int level); + // the only supported levels are 0 (quiet), 1 (verbose) and 2 (debug) + + int add_dependency(RT_Info* rt_info, + Dependency_Info& d); + + static int number_of_dependencies(RT_Info* rt_info); + static int number_of_dependencies(RT_Info& rt_info); + + // TBD - modify these to take a Task_Entry and show all its dispatches + static void export(RT_Info*, FILE* file); + static void export(RT_Info&, FILE* file); + +protected: + + //////////////////////////////// + // protected member functions // + //////////////////////////////// + + ACE_Scheduler (); + + + status_t schedule_threads (void); + // thread scheduling method: sets up array of pointers to task + // entries that are threads, calls internal thread scheduling method + + status_t schedule_dispatches (void); + // dispatch scheduling method: sets up an array of dispatch entries, + // calls internal dispatch scheduling method. + + // = Set the minimum priority value. + void minimum_priority_queue (const Preemption_Priority minimum_priority_queue_number); + + // = Set the number of tasks. + void tasks (const u_int tasks); + + // = Set the number of threads. + void threads (const u_int threads); + + // = Set the current scheduler status. + void status (const status_t new_status); + + ///////////////////////////////////////////// + // protected pure virtual member functions // + ///////////////////////////////////////////// + + virtual Preemption_Priority minimum_critical_priority () = 0; + // = determine the minimum critical priority number + + virtual status_t sort_dispatches (Dispatch_Entry **, u_int) = 0; + // internal sorting method: this orders the dispatches by + // static priority and dynamic and static subpriority. + + virtual status_t assign_priorities (Dispatch_Entry **dispatches, + u_int count) = 0; + // = assign priorities to the sorted dispatches + + virtual status_t assign_subpriorities (Dispatch_Entry **dispatches, + u_int count) = 0; + // = assign dynamic and static sub-priorities to the sorted dispatches + + + //////////////////////////// + // protected data members // + //////////////////////////// + + OS_Priority minimum_priority_; + // The minimum OS thread priority value that the application specified (in + // its call to init ()). + + OS_Priority maximum_priority_; + // The maximum OS thread priority value that the application specified (in + // its call to init ()). + + Task_Entry *task_entries_; + // Collection of known tasks. + + Task_Entry **ordered_task_entries_; + // An array of pointers to task entries which wrap RT_Infos. It is + // sorted by the DFS finishing time and then the resulting topological + // over the call graph is used both to check for call chain cycles and + // to correctly propagate scheduling information away from the threads. + + ACE_Unbounded_Set <Dispatch_Entry *> *thread_delineators_; + // identifies dispatch entries whose underlying + // Task Entries delineate threads + + Dispatch_Entry **ordered_thread_dispatch_entries_; + // An array of pointers to task entries which initiate call chains. + // It is sorted by the schedule_threads method defined in the derived class. + + ACE_Unbounded_Set <Dispatch_Entry *> *dispatch_entries_; + // the set of dispatch entries + + Dispatch_Entry **ordered_dispatch_entries_; + // An array of pointers to dispatch entries. It is + // sorted by the schedule_dispatches method. + + u_int dispatch_entry_count_; + // the number of dispatch entries in the schedule + + u_int threads_; + // the number of dispatch entries in the schedule + +private: + + /////////////////////////////// + // private type declarations // + /////////////////////////////// + + typedef ACE_CString EXT; + typedef RT_Info *INT; + +#if defined (ACE_HAS_THREADS) + typedef ACE_Thread_Mutex SYNCH; + typedef ACE_Recursive_Thread_Mutex LOCK; +#else + typedef ACE_Null_Mutex SYNCH; + typedef ACE_Null_Mutex LOCK; +#endif /* ACE_HAS_THREADS */ + + typedef ACE_Map_Manager<EXT, INT, ACE_SYNCH_MUTEX> Info_Collection; + typedef ACE_Map_Iterator<EXT, INT, ACE_SYNCH_MUTEX> Info_Collection_Iterator; + typedef ACE_Map_Entry<EXT, INT> Info_Collection_Entry; + + ////////////////////////////// + // private member functions // + ////////////////////////////// + + status_t create_timeline (); + // Create a timeline. + + status_t output_dispatch_timeline (const char *filename); + status_t output_dispatch_timeline (FILE *file); + // this prints the entire set of timeline outputs to the specified file + + status_t output_preemption_timeline (const char *filename); + status_t output_preemption_timeline (FILE *file); + // this prints the entire set of timeline outputs to the specified file + + // = Set up the task entry data structures + status_t setup_task_entries (void); + + // = Relate the task entries according to the + // dependencies of the underlying RT_Infos + status_t relate_task_entries (void); + + // recursively traverse dependency graph, relating + // task entries and performing DFS start/end marking + status_t relate_task_entries_recurse (long &time, Task_Entry &entry); + + // identify thread delimiters + status_t identify_threads (void); + + // checks for cycles in the dependency graph + status_t check_dependency_cycles (void); + + // recursion used to check for cycles in the dependency graph + status_t check_dependency_cycles_recurse (Task_Entry &entry); + + // = Aggregate the scheduling parameters of the threads + status_t aggregate_thread_parameters (void); + + // = recursion over oneway dependencies used to aggregate thread parameters + status_t aggregate_oneways_recurse (Task_Entry &entry); + + // = recursion over twoway dependencies used to aggregate thread parameters + status_t aggregate_twoways_recurse (Task_Entry &entry); + + // update the scheduling parameters for the previous priority level + void update_priority_level_params (); + + status_t propagate_dispatches (); + // propagate the dispatch information from the + // threads throughout the call graph + + status_t calculate_utilization_params (void); + // calculate utilization, frame size, etc. + + // the following functions are not implememented + ACE_UNIMPLEMENTED_FUNC(ACE_Scheduler (const ACE_Scheduler &)) + ACE_UNIMPLEMENTED_FUNC(ACE_Scheduler &operator= (const ACE_Scheduler &)) + + ////////////////////////// + // private data members // + ////////////////////////// + + LOCK lock_; + // This protects access to the scheduler during configuration runs. + + ACE_Unbounded_Set <RT_Info *> rt_info_entries_; + // Collection of known tasks. + + u_int handles_; + // The number of task handles dispensed so far. + + const char *runtime_filename_; + // Destination file of Scheduler output from the configuration run. + + const char *rt_info_filename_; + // Destination file of all rt_info data from the configuration run. + + const char *timeline_filename_; + // The destination of the timeline. + + Info_Collection info_collection_; + // A binding of name to rt_info. This is the mapping for every + // rt_info in the process. + + u_int tasks_; + + status_t status_; + + u_int output_level_; + + u_long frame_size_; /* 100 nanosec */ + // minimum frame size for all tasks + + u_long critical_set_frame_size_; /* 100 nanosec */ + // minimum frame size for guaranteed schedulable tasks + + double utilization_; + // total utilization for all tasks + + double critical_set_utilization_; + // minimum frame size for guaranteed schedulable tasks + + Preemption_Priority minimum_priority_queue_; + // The platform-independent priority value of the Event Channel's + // minimum priority dispatch queue. The value of the maximum priority + // dispatch queue is always 0. + + Preemption_Priority minimum_guaranteed_priority_queue_; + // The platform-independent priority value of the minimum priority dispatch + // queue whose operations are guaranteed to be schedulable. The value of + // the maximum priority dispatch queue is always 0, -1 indicates none can + // be guaranteed. + + ACE_Ordered_MultiSet <TimeLine_Entry_Link> *timeline_; + // Ordered MultiSet of timeline entries. + + u_int up_to_date_; + // indicates whether the a valid schedule has been generated since the last + // relevant change (addition, alteration or removal of an RT_Info, etc.) +}; + +#if defined (__ACE_INLINE__) +#include "DynSched.i" +#endif /* __ACE_INLINE__ */ + +#endif /* SCHEDULER_H */ + +// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/DynSched.i b/TAO/orbsvcs/orbsvcs/Sched/DynSched.i new file mode 100644 index 00000000000..0ff202db2c0 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/DynSched.i @@ -0,0 +1,100 @@ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// DynSched.i +// +// = CREATION DATE +// 23 January 1997 +// +// = AUTHOR +// Chris Gill +// +// ============================================================================ + + + +///////////////////////// +// Class ACE_Scheduler // +///////////////////////// + +ACE_INLINE ACE_Scheduler::Preemption_Priority +ACE_Scheduler::minimum_priority_queue () const +{ + return minimum_priority_queue_; +} + // This is intended for use by the Event Channel, so it can determine the + // number of priority dispatch queues to create. + +// = Access the number of tasks. +ACE_INLINE u_int +ACE_Scheduler::tasks () const +{ + return tasks_; +} + + // = Access the number of threads. +ACE_INLINE u_int +ACE_Scheduler::threads () const +{ + return threads_; +} + + // = Access the current scheduler status. +ACE_INLINE ACE_Scheduler::status_t +ACE_Scheduler::status () const +{ + return status_; +} + + // = Access the current output (debugging) level. +ACE_INLINE u_int +ACE_Scheduler::output_level () const { + return output_level_; +} + // Default is 0; set to 1 to print out schedule, by task. Set + // to higher than one for debugging info. + + // = Set the scheduler output (debugging) level. +ACE_INLINE void +ACE_Scheduler::output_level (const u_int level) +{ + output_level_ = level; +} + // the only supported levels are 0 (quiet), 1 (verbose) and 2 + // (debug) + +ACE_INLINE void +ACE_Scheduler::minimum_priority_queue (const Preemption_Priority minimum_priority_queue_number) +{ + minimum_priority_queue_ = minimum_priority_queue_number; +} + + // = Set the number of tasks. +ACE_INLINE void +ACE_Scheduler::tasks (const u_int tasks) +{ + tasks_ = tasks; +} + + // = Set the number of threads. +// TBD - remove this - allowing the application to modify this is *not* good +ACE_INLINE void +ACE_Scheduler::threads (const u_int threads) +{ + threads_ = threads; +} + + // = Set the current scheduler status. +ACE_INLINE void +ACE_Scheduler::status (const status_t new_status) +{ + status_ = new_status; +} + + +// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp b/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp new file mode 100644 index 00000000000..d0ee3222ce3 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp @@ -0,0 +1,858 @@ +/* -*- C++ -*- */ +// +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// SchedEntry.cpp +// +// = CREATION DATE +// 7 February 1998 +// +// = AUTHOR +// Chris Gill +// +// ============================================================================ + +#include "SchedEntry.h" + +#if ! defined (__ACE_INLINE__) +#include "SchedEntry.i" +#endif /* __ACE_INLINE__ */ + +////////////////////// +// Helper Functions // +////////////////////// + +// TBD - move this to the ACE class +// Euclid's greatest common divisor algorithm +u_long gcd (u_long x, u_long y) +{ + if (y == 0) + { + return x; + } + else + { + return gcd (y, x % y); + } +} + + +// TBD - move this to the ACE class +// calculate the minimum frame size that +u_long minimum_frame_size (u_long period1, u_long period2) +{ + // first, find the greatest common divisor of the two periods + u_long greatest_common_divisor = gcd (period1, period2); + + // explicitly consider cases to reduce risk of possible overflow errors + if (greatest_common_divisor == 1) + { + // periods are relative primes: just multiply them together + return period1 * period2; + } + else if (greatest_common_divisor == period1) + { + // the first period divides the second: return the second + return period2; + } + else if (greatest_common_divisor == period2) + { + // the second period divides the first: return the first + return period1; + } + else + { + // the current frame size and the entry's effective period + // have a non-trivial greatest common divisor: return the + // product of factors divided by those in their gcd. + return (period1 * period2) / greatest_common_divisor; + } +} + + +////////////////////// +// Class Task_Entry // +////////////////////// + +Task_Entry::Task_Entry () + : rt_info_ (0) + , effective_period_(0) + , dfs_status_ (NOT_VISITED) + , discovered_ (-1) + , finished_ (-1) + , is_thread_delineator_ (0) + , calls_ () + , callers_ () +{ +} + +Task_Entry::~Task_Entry () +{ + // zero out the task entry ACT in the corresponding rt_info + rt_info_->volatile_token = 0; + + // iterate through the "calls" set of Task Entry Links and free each one + ACE_Unbounded_Set_Iterator <Task_Entry_Link *> iter(calls_); + Task_Entry_Link **link = 0; + for (iter.first (); ! iter.done (); iter.advance (), link = 0) + { + if ((iter.next (link) != 0) && (link) && (*link)) + { + // remove the link object pointer from the calling + // entry's "callers" set and destroy the link object + (*link)->called ().callers_.remove (*link); + delete (*link); + } + } +} + +// merge dispatches according to info type and type of call, +// update relevant scheduling characteristics for this entry +int +Task_Entry::merge_dispatches (ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries) +{ + int result = 0; + switch (info_type ()) + { + case RtecScheduler::DISJUNCTION: + + // prohibit two-way dispatches of a disjunction group, + // and disjunctively merge its one-way dispatches. + // NOTE: one interpretation of disjunction for two-way calls + // is that the caller calls one OR the other, but this + // is problematic: how do we map the dispatches for this ? + result = prohibit_dispatches (RtecScheduler::TWO_WAY_CALL); + if (result == 0) + { + result = disjunctive_merge (RtecScheduler::ONE_WAY_CALL, dispatch_entries); + } + + break; + + case RtecScheduler::CONJUNCTION: + + // prohibit two-way dispatches of a conjunction group, + // and conjunctively merge its one-way dispatches. + // NOTE: one interpretation of disjunction for two-way calls + // is that the caller calls BOTH, so that there is a + // disjunctive merge of each two-way, as for the OPERATION + // (prohibit for now, as the additional complexity of allowing + // conjunctions of two-ways, but not disjunctions does not + // buy us anything, anyway). + result = prohibit_dispatches (RtecScheduler::TWO_WAY_CALL); + if (result == 0) + { + result = conjunctive_merge (RtecScheduler::ONE_WAY_CALL, dispatch_entries); + } + + break; + + case RtecScheduler::OPERATION: + + // disjunctively merge the operation's two-way dispatches, + // and conjunctively merge its one-way dispatches. + result = disjunctive_merge (RtecScheduler::TWO_WAY_CALL, dispatch_entries); + if (result == 0) + { + result = conjunctive_merge (RtecScheduler::ONE_WAY_CALL, dispatch_entries); + } + + break; + + + default: + + // there should not be any other kind of RT_Info, or if + // there is, the above switch logic is in need of repair. + result -1; + break; + } + + return result; +} + + +// prohibit calls of the given type: currently used to enforce +// the notion that two-way calls to disjunctive or conjunctive +// RT_Infos do not have any defined meaning, and thus should be +// considered dependency specification errors: if these constraints +// are removed in the future, this method should be removed as well +// Returns 0 if all is well, or -1 if an error has occurred. +int +Task_Entry::prohibit_dispatches (Dependency_Type dt) +{ + // iterate over the set of dependencies, ensuring + // none of them has the given dependency type + ACE_Unbounded_Set_Iterator <Task_Entry_Link *> iter (callers_); + while (! iter.done ()) + { + Task_Entry_Link **link; + if ((iter.next (link) == 0) || (! link) || (! (*link)) || + ((*link)->dependency_type () == dt)) + { + return -1; + } + + iter.advance (); + } + + return 0; +} + + +// perform disjunctive merge of arrival times of oneway calls: +// all arrival times of all dependencies are duplicated by the +// multiplier and repetition over the new frame size and merged +int +Task_Entry::disjunctive_merge ( + Dependency_Type dt, + ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries) +{ + // iterate over the set of dependencies, ensuring + // none of them has the given dependency type + ACE_Unbounded_Set_Iterator <Task_Entry_Link *> iter (callers_); + while (! iter.done ()) + { + Task_Entry_Link **link; + if ((iter.next (link) == 0) || (! link) || (! (*link))) + { + return -1; + } + + // the link matches the dependency type given + if ((*link)->dependency_type () == dt) + { + // merge the caller's dispatches into the current set + if (merge_frames (dispatch_entries, *this, dispatches_, + (*link)->caller ().dispatches_, effective_period_, + (*link)->caller ().effective_period_, + (*link)->number_of_calls ()) < 0) + { + return -1; + } + } + + iter.advance (); + } + + return 0; +} + +// perform conjunctive merge of arrival times of calls: +// all arrival times of all dependencies are duplicated by the +// multiplier and repetition over the new frame size and then +// iteratively merged by choosing the maximal arrival time at +// the current position in each queue (iteration is in lockstep +// over all queues, and ends when any queue ends). +int +Task_Entry::conjunctive_merge ( + Dependency_Type dt, + ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries) +{ + int result = 0; + + // iterate over the dependencies, and determine the total frame size + u_long frame_size = 1; + ACE_Unbounded_Set_Iterator <Task_Entry_Link *> dep_iter (callers_); + for (dep_iter.first (); dep_iter.done () == 0; dep_iter.advance ()) + { + Task_Entry_Link **link; + if ((dep_iter.next (link) == 0) || (! link) || (! (*link))) + { + return -1; + } + + // the link matches the dependency type given + if ((*link)->dependency_type () == dt) + { + frame_size = minimum_frame_size (frame_size, (*link)->caller ().effective_period_); + } + } + + // reframe dispatches in the set to the new frame size + // (expands the set's effective period to be the new enclosing frame) + if (reframe (dispatch_entries, *this, dispatches_, + effective_period_, frame_size) < 0) + { + return -1; + } + + // A set and iterator for virtual dispatch sets + // over which the conjunction will iterate + ACE_Ordered_MultiSet <Dispatch_Proxy_Iterator *> conj_set; + ACE_Ordered_MultiSet_Iterator <Dispatch_Proxy_Iterator *> conj_set_iter (conj_set); + + // iterate over the dependencies, and for each of the given call type, + // create a Dispatch_Proxy_Iterator for the caller's dispatch set, using + // the caller's period, the total frame size, and the number of calls: + // if any of the sets is empty, just return 0; + for (dep_iter.first (); dep_iter.done () == 0; dep_iter.advance ()) + { + Task_Entry_Link **link; + if ((dep_iter.next (link) == 0) || (! link) || (! (*link))) + { + return -1; + } + + // the link matches the dependency type given + if ((*link)->dependency_type () == dt) + { + Dispatch_Proxy_Iterator *proxy_ptr; + ACE_NEW_RETURN (proxy_ptr, + Dispatch_Proxy_Iterator ( + (*link)->caller ().dispatches_, + (*link)->caller ().effective_period_, + frame_size, (*link)->number_of_calls ()), + -1); + + // if there are no entries in the virtual set, we're done + if (proxy_ptr->done ()) + { + return 0; + } + if (conj_set.insert (proxy_ptr, conj_set_iter) < 0) + { + return -1; + } + } + } + + // loop, adding conjunctive dispatches, until one of the conjunctive + // dispatch sources runs out of entries over the total frame + conj_set_iter.first (); + int more_dispatches = (conj_set_iter.done ()) ? 0 : 1; + while (more_dispatches) + { + u_long arrival = 0; + u_long deadline = 0; + long priority = 0; + + for (conj_set_iter.first (); + conj_set_iter.done () == 0; + conj_set_iter.advance ()) + { + // initialize to earliest arrival and deadline, and highest priority + arrival = 0; + deadline = 0; + priority = 0; + + // Policy: conjunctively dispatched operations get the latest deadline of any + // of the dispatches in the conjunction at the time they were dispatched + // - when and if it is useful to change any of the merge policies, this + // should be one of the decisions factored out into the conjunctive merge + // strategy class. + + // Policy: conjunctively dispatched operations get the lowest priority of any + // of the dispatches in the conjunction at the time they were dispatched + // - when and if it is useful to change any of the merge policies, this + // should be one of the decisions factored out into the conjunctive merge + // strategy class. + + // obtain a pointer to the current dispatch proxy iterator + Dispatch_Proxy_Iterator **proxy_iter; + if ((conj_set_iter.next (proxy_iter) == 0) || (! proxy_iter) || (! (*proxy_iter))) + { + return -1; + } + + // use latest arrival, latest deadline, lowest priority (0 is highest) + arrival = (arrival < (*proxy_iter)->arrival ()) + ? arrival : (*proxy_iter)->arrival (); + deadline = (deadline < (*proxy_iter)->deadline ()) + ? deadline : (*proxy_iter)->deadline (); + priority = (priority < (*proxy_iter)->priority ()) + ? priority : (*proxy_iter)->priority (); + + (*proxy_iter)->advance (); + if ((*proxy_iter)->done ()) + { + more_dispatches = 0; + } + } + + Dispatch_Entry *entry_ptr; + ACE_NEW_RETURN (entry_ptr, + Dispatch_Entry (arrival, deadline, priority, *this), + -1); + + // if even one new dispatch was inserted, result is "something happened". + result = 1; + + // add the new dispatch entry to the set of all dispatches, and + // a link to it to the dispatch links for this task entry + if (dispatch_entries.insert (entry_ptr) < 0) + { + return -1; + } + + // use iterator for efficient insertion into the dispatch set + ACE_Ordered_MultiSet_Iterator <Dispatch_Entry_Link> insert_iter (dispatches_); + if (dispatches_.insert (Dispatch_Entry_Link (*entry_ptr), insert_iter) < 0) + { + return -1; + } + + // TBD - Clients are not assigned priority, but rather obtain it from + // their call dependencies. We could complain here if there is a + // priority specified that doesn't match (or is lower QoS?) + } + + return result; +} + +// this static method is used to reframe an existing dispatch set +// to the given new period multiplier, creating new instances of +// each existing dispatch (with adjusted arrival and deadline) +// in each successive sub-frame. Returns 1 if the set was reframed +// to a new period, 0 if the set was not changed (the new period +// was not a multiple of the old one), or -1 if an error occurred. +int +Task_Entry::reframe ( + ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries, + Task_Entry &owner, + ACE_Ordered_MultiSet <Dispatch_Entry_Link> &set, + u_long &set_period, u_long new_period) +{ + // make sure the new period is greater than the current + // set period, and that they are harmonically related + if (new_period <= set_period) + { + // return an error if they're not harmonically related, + // do nothing if set's frame is a multiple of the new frame + return (set_period % new_period) ? -1 : 0; + } + else if (new_period % set_period) + { + return -1; + } + + // use an empty ordered multiset for subsequent sub-frame dispatches + // (the set already holds all dispatches the 0th sub-frame) + ACE_Ordered_MultiSet <Dispatch_Entry_Link> new_set; + + // merge the old set with its old period into the new (empty) + // set with the new period, starting after the 0th sub-frame: + // this puts all dispatches after the 0th sub-frame of the new period + // in the new set, and leaves all dispatches in the 0th sub-frame of + // the new period in the old set. + u_long temp_period = new_period; + int result = merge_frames (dispatch_entries, owner, new_set, set, + temp_period, set_period, 1, 1); + + // if the period changed during the merge, or an error was returned, bail out + if ((temp_period != new_period) || result == -1) + { + return -1; + } + + // now, update the period for the set, and merge the + // new set into the old set, over the same period + set_period = new_period; + result = merge_frames (dispatch_entries, owner, set, + new_set, set_period, set_period); + + // if the period changed during the merge, return an error + if (set_period != new_period) + { + result = -1; + } + + return result; +} + + +// this static method is used to merge an existing dispatch set, +// multiplied by the given multipliers for the period and number of +// instances in each period of each existing dispatch, into the +// given "into" set, without affecting the "from set". +int +Task_Entry::merge_frames ( + ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries, + Task_Entry &owner, + ACE_Ordered_MultiSet <Dispatch_Entry_Link> &dest, + ACE_Ordered_MultiSet <Dispatch_Entry_Link> &src, + u_long &dest_period, + u_long src_period, + u_long number_of_calls, + u_long starting_dest_sub_frame) +{ + int status = 0; + + // reframe dispatches in the destination set to the new frame size + // (expands the destination set's period to be the new enclosing frame) + if (reframe (dispatch_entries, owner, dest, dest_period, + minimum_frame_size (dest_period, src_period)) < 0) + { + return -1; + } + + // use iterator for efficient insertion into the destination set + ACE_Ordered_MultiSet_Iterator <Dispatch_Entry_Link> dest_iter (dest); + + // do virutal iteration over the source set in the new frame, + // adding adjusted dispatch entries to the destination + + for (Dispatch_Proxy_Iterator src_iter (src, src_period, dest_period, + number_of_calls, + starting_dest_sub_frame); + src_iter.done () == 0; src_iter.advance ()) + { + + // Policy: disjunctively dispatched operations get their deadline and + // priority from the original dispatch - when and if it is useful + // to change any of the merge policies, this should be one of the + // decisions factored out into the disjunctive merge strategy + // class. + + Dispatch_Entry *entry_ptr; + ACE_NEW_RETURN (entry_ptr, + Dispatch_Entry (src_iter.arrival (), + src_iter.deadline (), + src_iter.priority (), owner), + -1); + + // if even one new dispatch was inserted, status is "something happened". + status = 1; + + // add the new dispatch entry to the set of all dispatches, and + // a link to it to the dispatch links for this task entry + if (dispatch_entries.insert (entry_ptr) < 0) + { + return -1; + } + + if (dest.insert (Dispatch_Entry_Link (*entry_ptr), dest_iter) < 0) + { + return -1; + } + + // TBD - Clients are not assigned priority, but rather obtain it from + // their call dependencies. We could complain here if there is a + // priority specified that doesn't match (or is lower QoS?) + } + + return status; +} + + +/////////////////////////// +// Class Task_Entry_Link // +/////////////////////////// + + +Task_Entry_Link::Task_Entry_Link ( + Task_Entry &caller, + Task_Entry &called, + CORBA::Long number_of_calls, + RtecScheduler::Dependency_Type dependency_type) + : caller_ (caller) + , called_ (called) + , dependency_type_ (dependency_type) + , number_of_calls_ (number_of_calls) +{ +} + + +////////////////////////// +// Class Dispatch_Entry // +////////////////////////// + +Dispatch_Entry::Dispatch_Id Dispatch_Entry::next_id_ = 0; + +Dispatch_Entry::Dispatch_Entry ( + Time arrival, + Time deadline, + Preemption_Priority priority, + Task_Entry &task_entry) + + : priority_ (priority) + , OS_priority_ (0) + , dynamic_subpriority_ (0) + , static_subpriority_ (0) + , arrival_ (arrival) + , deadline_ (deadline) + , task_entry_ (task_entry) +{ + // obtain, increment the next id + dispatch_id_ = next_id_++; +} + +Dispatch_Entry::Dispatch_Entry (const Dispatch_Entry &d) + : priority_ (d.priority_) + , OS_priority_ (d.OS_priority_) + , dynamic_subpriority_ (d.dynamic_subpriority_) + , static_subpriority_ (d.static_subpriority_) + , arrival_ (d.arrival_) + , deadline_ (d.deadline_) + , task_entry_ (d.task_entry_) +{ + // obtain, increment the next id + dispatch_id_ = next_id_++; +} + + +ACE_INLINE int +Dispatch_Entry::operator < (const Dispatch_Entry &d) const +{ + // for positioning in the ordered dispatch multiset + + // lowest arrival time first + if (this->arrival_ != d.arrival_) + { + return (this->arrival_ < d.arrival_) ? 1 : 0; + } + + // highest priority second + if (this->priority_ != d.priority_) + { + return (this->priority_ > d.priority_) ? 1 : 0; + } + + // lowest laxity (highest dynamic sub-priority) third + Time this_laxity = deadline_ - + task_entry ().rt_info ()->worst_case_execution_time; + Time that_laxity = d.deadline_ - + d.task_entry ().rt_info ()->worst_case_execution_time; + if (this_laxity != that_laxity) + { + return (this_laxity < that_laxity) ? 1 : 0; + } + + // finally, by higher importance + return (task_entry ().rt_info ()->importance > + d.task_entry ().rt_info ()->importance) ? 1 : 0; +} + + +/////////////////////////////// +// Class Dispatch_Entry_Link // +/////////////////////////////// + + +Dispatch_Entry_Link::Dispatch_Entry_Link (Dispatch_Entry &d) + : dispatch_entry_ (d) +{ +} + // ctor + +Dispatch_Entry_Link::Dispatch_Entry_Link ( + const Dispatch_Entry_Link &d) + : dispatch_entry_ (d.dispatch_entry_) +{ +} + // copy ctor + + +/////////////////////////////////// +// Class Dispatch_Proxy_Iterator // +/////////////////////////////////// + +Dispatch_Proxy_Iterator::Dispatch_Proxy_Iterator + (ACE_Ordered_MultiSet <Dispatch_Entry_Link> set, + u_long actual_frame_size, + u_long virtual_frame_size, + u_long number_of_calls, + u_long starting_sub_frame) + : number_of_calls_ (number_of_calls) + , current_call_ (0) + , actual_frame_size_ (actual_frame_size) + , virtual_frame_size_ (virtual_frame_size) + , current_frame_offset_ (actual_frame_size * starting_sub_frame) + , iter_ (set) +{ + first (); +} + // ctor + +int +Dispatch_Proxy_Iterator::first (u_int sub_frame) +{ + if (actual_frame_size_ * (sub_frame + 1) >= virtual_frame_size_) + { + // can not position the virtual iterator + // in the given range: do nothing + return 0; + } + + // restart the call counter + current_call_ = 0; + + // use the given sub-frame offset if it's valid + current_frame_offset_ = actual_frame_size_ * sub_frame; + + // restart the iterator + return iter_.first (); +} + // positions the iterator at the first entry of the passed + // sub-frame, returns 1 if it could position the iterator + // correctly, 0 if not, and -1 if an error occurred. + +int +Dispatch_Proxy_Iterator::last () +{ + // use the last call + current_call_ = number_of_calls_ - 1; + + // use the last sub-frame + current_frame_offset_ = virtual_frame_size_ - actual_frame_size_; + + // position the iterator at the last dispatch + return iter_.first (); +} + // positions the iterator at the last entry of the total + // frame, returns 1 if it could position the iterator + // correctly, 0 if not, and -1 if an error occurred. + +int +Dispatch_Proxy_Iterator::advance () +{ + int result = 1; + + if (iter_.done ()) + { + result = 0; // cannot retreat if we're out of bounds + } + else if (current_call_ < number_of_calls_ - 1) + { + // if we're still in the same set of calls, increment the call counter + ++current_call_; + } + else + { + // roll over the call counter + current_call_ = 0; + + // advance the iterator in the current sub-frame + if (! iter_.advance ()) + { + // if we're not already in the last sub_frame + if (current_frame_offset_ + actual_frame_size_ < virtual_frame_size_) + { + // increment the sub-frame offset + current_frame_offset_ += actual_frame_size_; + + // restart the iterator at the front of the sub-frame + result = iter_.first (); + } + else + { + result = 0; // cannot advance if we're already at the end + } + } + } + + return result; +} + // positions the iterator at the next entry of the total + // frame, returns 1 if it could position the iterator + // correctly, 0 if not, and -1 if an error occurred. + +int +Dispatch_Proxy_Iterator::retreat () +{ + int result = 1; + + if (iter_.done ()) + { + result = 0; // cannot retreat if we're out of bounds + } + else if (current_call_ > 0) + { + // if we're still in the same set of calls, decrement the call counter + --current_call_; + } + else + { + // roll over the call counter + current_call_ = number_of_calls_ - 1; + + // back up the iterator in the current sub-frame + if (!iter_.retreat ()) + { + // if we're not already in the 0th sub_frame + if (current_frame_offset_ > 0) + { + // decrement the sub-frame offset + current_frame_offset_ -= actual_frame_size_; + + // restart the iterator at the tail of the sub-frame + result = iter_.last (); + } + else + { + result = 0; // cannot retreat if we're already at the start + } + } + } + + return result; +} + // positions the iterator at the previous entry of the total + // frame, returns 1 if it could position the iterator + // correctly, 0 if not, and -1 if an error occurred. + +u_long +Dispatch_Proxy_Iterator::arrival () const +{ + Dispatch_Entry_Link *link; + if ((iter_.done ()) || (iter_.next(link) == 0) || (! link)) + { + return 0; + } + + return link->dispatch_entry ().arrival () + current_frame_offset_; +} + // returns the adjusted arrival time of the virtual entry + +u_long +Dispatch_Proxy_Iterator::deadline () const +{ + Dispatch_Entry_Link *link; + if ((iter_.done ()) || (iter_.next(link) == 0) || (! link)) + { + return 0; + } + + return link->dispatch_entry ().deadline () + current_frame_offset_; +} + // returns the adjusted deadline time of the virtual entry + +Dispatch_Proxy_Iterator::Preemption_Priority +Dispatch_Proxy_Iterator::priority () const +{ + Dispatch_Entry_Link *link; + if ((iter_.done ()) || (iter_.next(link) == 0) || (! link)) + { + return 0; + } + + return link->dispatch_entry ().priority (); +} + // returns the scheduler priority of the virtual entry + + + +////////////////////////// +// Class TimeLine_Entry // +////////////////////////// + + + // time slice constructor +TimeLine_Entry::TimeLine_Entry (Dispatch_Entry &dispatch_entry, + u_long start, u_long stop, + TimeLine_Entry *next, + TimeLine_Entry *prev) + : dispatch_entry_ (dispatch_entry) + , start_ (start) + , stop_ (stop) + , next_ (next) + , prev_ (prev) +{ +} + diff --git a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.h b/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.h new file mode 100644 index 00000000000..4330fb1f15b --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.h @@ -0,0 +1,579 @@ +/* -*- C++ -*- */ +// +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// SchedEntry.h +// +// = CREATION DATE +// 7 February 1998 +// +// = AUTHOR +// Chris Gill +// +// ============================================================================ + +#if ! defined (SCHEDENTRY_H) +#define SCHEDENTRY_H + +#include "orbsvcs/RtecSchedulerC.h" +#include "orbsvcs/Event_Service_Constants.h" + + +////////////////////// +// Helper Functions // +////////////////////// + +// TBD - move this to the ACE class +// Euclid's greatest common divisor algorithm +u_long gcd (u_long x, u_long y); + +// TBD - move this to the ACE class +// calculate the minimum frame size +u_long minimum_frame_size (u_long period1, u_long period2); + +// forward declaration of classes +class Task_Entry; +class Task_Entry_Link; +class Dispatch_Entry; +class Dispatch_Entry_Link; +class Dispatch_Proxy_Iterator; + + +// Wrapper for the RT_Info, which aggregates all its dispatches +class Task_Entry +{ +public: + + typedef RtecScheduler::handle_t handle_t; + typedef RtecScheduler::Dependency_Info Dependency_Info; + typedef RtecScheduler::Preemption_Priority Preemption_Priority; + typedef RtecScheduler::OS_Priority OS_Priority; + typedef RtecScheduler::Sub_Priority Sub_Priority; + typedef RtecScheduler::RT_Info RT_Info; + typedef RtecScheduler::Time Time; + typedef RtecScheduler::Period Period; + typedef RtecScheduler::Info_Type Info_Type; + typedef RtecScheduler::Dependency_Type Dependency_Type; + + // info for DFS traversal, topological sort of call graph + enum DFS_Status {NOT_VISITED, VISITED, FINISHED}; + + // ctor + Task_Entry (); + + // dtor + ~Task_Entry (); + + // merge dispatches according to info type, update + // relevant scheduling characteristics for this entry. + // Returns 0 if all is well, or -1 if an error occurred + int merge_dispatches ( + ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries); + + // get, set pointer to underlying RT_Info + RT_Info *rt_info () const; + void rt_info (RT_Info *info); + + + // get effective period for the task entry + Period effective_period () const; + void effective_period (Period p); + + // set/get time when node was discovered in DFS traversal + void discovered (long l); + long discovered () const; + + // set/get time when node was finished in DFS traversal + void finished (long l); + long finished () const; + + // set/get DFS traversal status of node + void dfs_status (DFS_Status ds); + DFS_Status dfs_status () const; + + // set/get flag indicating whether node is a thread delineator + void is_thread_delineator (int i); + int is_thread_delineator () const; + + // get set of links to Task Entries which this entry calls + ACE_Unbounded_Set <Task_Entry_Link *> & calls (); + + // get set of links to Task Entries which call this entry + ACE_Unbounded_Set <Task_Entry_Link *> & callers (); + + // get set of arrivals in the effective period + ACE_Ordered_MultiSet<Dispatch_Entry_Link> &dispatches (); + + // get the type of Info the entry wraps + Info_Type info_type () const; + + // effective execution time for the task entry + u_long effective_execution_time () const; + +private: + + // prohibit calls of the given type: currently used to enforce + // the notion that two-way calls to disjunctive or conjunctive + // RT_Infos do not have any defined meaning, and thus should be + // considered dependency specification errors: if these constraints + // are removed in the future, this method should be removed as well + // Returns 0 if all is well, or -1 if an error has occurred. + int prohibit_dispatches (Dependency_Type dt); + + // performs disjunctive merge of arrival times of calls of the given + // type: all arrival times of all callers of that type are duplicated by + // the multiplier and repetition over the new frame size and merged. + // Returns 0 if all is well, or -1 if an error has occurred. + int disjunctive_merge ( + Dependency_Type dt, + ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries); + + // perform conjunctive merge of arrival times of calls of the given + // type: all arrival times of all callers of that type are duplicated + // by the multiplier and repetition over the new frame size and then + // iteratively merged by choosing the maximal arrival time at + // the current position in each queue (iteration is in lockstep + // over all queues, and ends when any queue ends). Returns 0 if + // all is well, or -1 if an error has occurred. + int conjunctive_merge ( + Dependency_Type dt, + ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries); + + + // this static method is used to reframe an existing dispatch set + // to the given new period multiplier, creating new instances of + // each existing dispatch (with adjusted arrival and deadline) + // in each successive sub-frame. Returns 1 if the set was reframed + // to a new period, 0 if the set was not changed (the new period + // was not a multiple of the old one), or -1 if an error occurred. + static int reframe (ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries, + Task_Entry &owner, + ACE_Ordered_MultiSet <Dispatch_Entry_Link> &set, + u_long &set_period, u_long new_period); + + // this static method is used to merge an existing dispatch set, + // multiplied by the given multipliers for the period and number of + // instances in each period of each existing dispatch, into the + // given "into" set, without affecting the "from set". Returns 1 if + // the source set was correctly merged into the destination set, + // 0 if nothing happened, and -1 if an error occurred. + static int merge_frames (ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries, + Task_Entry &owner, + ACE_Ordered_MultiSet <Dispatch_Entry_Link> &dest, + ACE_Ordered_MultiSet <Dispatch_Entry_Link> &src, + u_long &dest_period, + u_long src_period, + u_long number_of_calls = 1, + u_long starting_dest_sub_frame = 0); + + // pointer to the underlying RT_Info + RT_Info *rt_info_; + + // effective period for the task entry + u_long effective_period_; + + // set of arrivals in the effective period + ACE_Ordered_MultiSet<Dispatch_Entry_Link> dispatches_; + + // count of the arrivals in the effective period + u_long arrival_count_; + + DFS_Status dfs_status_; + long discovered_; + long finished_; + + // info for identifying threads in the oneway call graph + int is_thread_delineator_; + + // get set of links to Task Entries which this entry calls + ACE_Unbounded_Set <Task_Entry_Link *> calls_; + + // get set of links to Task Entries which call this entry + ACE_Unbounded_Set <Task_Entry_Link *> callers_; +}; + + +class Task_Entry_Link +{ +public: + + typedef RtecScheduler::handle_t handle_t; + typedef RtecScheduler::Dependency_Info Dependency_Info; + typedef RtecScheduler::Preemption_Priority Preemption_Priority; + typedef RtecScheduler::OS_Priority OS_Priority; + typedef RtecScheduler::Sub_Priority Sub_Priority; + typedef RtecScheduler::RT_Info RT_Info; + typedef RtecScheduler::Time Time; + typedef RtecScheduler::Period Period; + typedef RtecScheduler::Info_Type Info_Type; + typedef RtecScheduler::Dependency_Type Dependency_Type; + + // ctor + Task_Entry_Link (Task_Entry &caller, + Task_Entry &called, + CORBA::Long number_of_calls, + Dependency_Type dependency_type); + + // accessor: number of calls + CORBA::Long number_of_calls () const; + + // accessor: dependency type + Dependency_Type dependency_type () const; + + // accessor: calling task entry + Task_Entry &caller () const; + + // accessor: called task entry + Task_Entry &called () const; + +private: + + // the number of calls of the operation + CORBA::Long number_of_calls_; + + // the calling operation + Task_Entry &caller_; + + // the called operation + Task_Entry &called_; + + // the type of call dependency + Dependency_Type dependency_type_; +}; + + +class Dispatch_Entry +{ +// = TITLE +// Dispatch Entry +// +// = DESCRIPTION +// Descriptor object for a single dispatch of an operation. +// +public: + + typedef RtecScheduler::handle_t handle_t; + typedef RtecScheduler::Dependency_Info Dependency_Info; + typedef RtecScheduler::Preemption_Priority Preemption_Priority; + typedef RtecScheduler::OS_Priority OS_Priority; + typedef RtecScheduler::Sub_Priority Sub_Priority; + typedef RtecScheduler::RT_Info RT_Info; + typedef RtecScheduler::Time Time; + typedef RtecScheduler::Period Period; + typedef RtecScheduler::Info_Type Info_Type; + typedef RtecScheduler::Dependency_Type Dependency_Type; + + typedef u_long Dispatch_Id; + + // ctor + Dispatch_Entry (Time arrival, + Time deadline, + Preemption_Priority priority, + Task_Entry &task_entry); + + // copy ctor + Dispatch_Entry (const Dispatch_Entry &d); + + // id accessor + Dispatch_Id dispatch_id () const; + + // arrival accessor + Time arrival () const; + + // deadline accessor + Time deadline () const; + + // scheduler priority accessor and mutator + Preemption_Priority priority () const; + void priority (Preemption_Priority p); + + // scheduler priority accessor and mutator + OS_Priority Dispatch_Entry::OS_priority () const; + void Dispatch_Entry::OS_priority (OS_Priority p); + + // dynamic subpriority accessor and mutator + Sub_Priority dynamic_subpriority () const; + void dynamic_subpriority (Sub_Priority p); + + // static subpriority accessor and mutator + Sub_Priority static_subpriority () const; + void static_subpriority (Sub_Priority p); + + // task entry accessor + Task_Entry &task_entry () const; + + // LT comparator + // TBD - make this a global comparison operator + // instead of a class member function + int operator < (const Dispatch_Entry &d) const; + + +private: + // TBD - add reference counting to Dispatch Entry class, + // make the link a friend, up/down count as links come and go, + // and call entry dtor when ref count drops to 0 + + // stores the next dispatch entry id to be used + static Dispatch_Id next_id_; + + // the id of the current dispatch entry + Dispatch_Id dispatch_id_; + + // scheduler priority of the current dispatch entry + Preemption_Priority priority_; + + // OS priority of the current dispatch entry + OS_Priority OS_priority_; + + // scheduler dynamic subpriority of the current dispatch entry + Sub_Priority dynamic_subpriority_; + + // scheduler static subpriority of the current dispatch entry + Sub_Priority static_subpriority_; + + // the arrival time of the current dispatch entry + Time arrival_; + + // the deadline of the current dispatch entry + Time deadline_; + + // stores the id of the related task entry + Task_Entry &task_entry_; + +}; + +class Dispatch_Entry_Link +// = TITLE +// Dispatch Entry Link +// +// = DESCRIPTION +// Light-weight sortable "smart pointer" to a dispatch entry. +// +{ +public: + + typedef RtecScheduler::handle_t handle_t; + typedef RtecScheduler::Dependency_Info Dependency_Info; + typedef RtecScheduler::Preemption_Priority Preemption_Priority; + typedef RtecScheduler::OS_Priority OS_Priority; + typedef RtecScheduler::Sub_Priority Sub_Priority; + typedef RtecScheduler::RT_Info RT_Info; + typedef RtecScheduler::Time Time; + typedef RtecScheduler::Period Period; + typedef RtecScheduler::Info_Type Info_Type; + typedef RtecScheduler::Dependency_Type Dependency_Type; + + Dispatch_Entry_Link (Dispatch_Entry &d); + // ctor + + Dispatch_Entry_Link (const Dispatch_Entry_Link &d); + // copy ctor + + ~Dispatch_Entry_Link (); + // dtor + + // TBD - make this a global comparison operator + // instead of a class member function + int operator < (const Dispatch_Entry_Link &d) const; + // LT comparator + + Dispatch_Entry &dispatch_entry () const; + // accessor for reference to dispatch entry + +private: + + Dispatch_Entry &dispatch_entry_; +}; + +class Dispatch_Proxy_Iterator +// = TITLE +// This class implements an iterator abstraction over a virtual +// frame size and number of calls, using an actual ordered +// multiset of dispatch entries over an actual frame size. +// It also serves as a proxy for the virtual dispatch to which +// it refers. Rhetorical question: is it possible to separate +// the iterator and proxy abstractions here without defeating the +// purpose of the design, which is to avoid constructing +// superfluous dispatch entries (per the conjunctive merge use case) ? +{ +public: + + typedef RtecScheduler::handle_t handle_t; + typedef RtecScheduler::Dependency_Info Dependency_Info; + typedef RtecScheduler::Preemption_Priority Preemption_Priority; + typedef RtecScheduler::OS_Priority OS_Priority; + typedef RtecScheduler::Sub_Priority Sub_Priority; + typedef RtecScheduler::RT_Info RT_Info; + typedef RtecScheduler::Time Time; + typedef RtecScheduler::Period Period; + typedef RtecScheduler::Info_Type Info_Type; + typedef RtecScheduler::Dependency_Type Dependency_Type; + + Dispatch_Proxy_Iterator (ACE_Ordered_MultiSet <Dispatch_Entry_Link> set, + u_long actual_frame_size, + u_long virtual_frame_size, + u_long number_of_calls_ = 1, + u_long starting_sub_frame = 0); + // ctor + + //////////////////////// + // iterator interface // + //////////////////////// + + int done () const; + // returns 0 if there are more entries to see, 1 if not + + int first (u_int sub_frame = 0); + // positions the iterator at the first entry of the passed + // sub-frame, returns 1 if it could position the iterator + // correctly, 0 if not, and -1 if an error occurred. + + int last (); + // positions the iterator at the last entry of the total + // frame, returns 1 if it could position the iterator + // correctly, 0 if not, and -1 if an error occurred. + + int advance (); + // positions the iterator at the next entry of the total + // frame, returns 1 if it could position the iterator + // correctly, 0 if not, and -1 if an error occurred. + + int retreat (); + // positions the iterator at the previous entry of the total + // frame, returns 1 if it could position the iterator + // correctly, 0 if not, and -1 if an error occurred. + + ///////////////////// + // proxy interface // + ///////////////////// + + u_long arrival () const; + // returns the adjusted arrival time of the virtual entry + + u_long deadline () const; + // returns the adjusted deadline time of the virtual entry + + Preemption_Priority priority () const; + // returns the scheduler priority of the virtual entry + + +private: + + u_long number_of_calls_; + // the number of calls corresponding to each actual dispatch + + u_long current_call_; + // the current call number for this dispatch (zero based) + + u_long actual_frame_size_; + // the frame size of the actual dispatches + + u_long virtual_frame_size_; + // the virtaul frame size over which to iterate + + u_long current_frame_offset_; + // the current offset into the virtual frame + // (should be a multiple of the actual frame size) + + ACE_Ordered_MultiSet_Iterator <Dispatch_Entry_Link> iter_; +}; + + + +class TimeLine_Entry +{ +public: + + typedef RtecScheduler::handle_t handle_t; + typedef RtecScheduler::Dependency_Info Dependency_Info; + typedef RtecScheduler::Preemption_Priority Preemption_Priority; + typedef RtecScheduler::OS_Priority OS_Priority; + typedef RtecScheduler::Sub_Priority Sub_Priority; + typedef RtecScheduler::RT_Info RT_Info; + typedef RtecScheduler::Time Time; + typedef RtecScheduler::Period Period; + typedef RtecScheduler::Info_Type Info_Type; + typedef RtecScheduler::Dependency_Type Dependency_Type; + + // time slice constructor + TimeLine_Entry (Dispatch_Entry &dispatch_entry, + u_long start, + u_long stop, + TimeLine_Entry *next = 0, + TimeLine_Entry *prev = 0); + + // dispatch entry accessor + Dispatch_Entry &dispatch_entry () const; + + // accessors for time slice start and stop times (100 nanoseconds) + u_long start () const; + u_long stop () const; + + // accessor and mutator for next and prev slices for this dispatch + TimeLine_Entry *next (void) const; + void next (TimeLine_Entry *); + TimeLine_Entry *prev (void) const; + void prev (TimeLine_Entry *); + + int operator < (const TimeLine_Entry&) const; + +private: + + // the dispatch entry to which the time slice corresponds + Dispatch_Entry &dispatch_entry_; + + // priority time slice start and stop times (100 nanoseconds) + u_long start_; + u_long stop_; + + // next and previous priority time slices for this dispatch entry + TimeLine_Entry *next_; + TimeLine_Entry *prev_; + +}; + +class TimeLine_Entry_Link +{ +public: + + typedef RtecScheduler::handle_t handle_t; + typedef RtecScheduler::Dependency_Info Dependency_Info; + typedef RtecScheduler::Preemption_Priority Preemption_Priority; + typedef RtecScheduler::OS_Priority OS_Priority; + typedef RtecScheduler::Sub_Priority Sub_Priority; + typedef RtecScheduler::RT_Info RT_Info; + typedef RtecScheduler::Time Time; + typedef RtecScheduler::Period Period; + typedef RtecScheduler::Info_Type Info_Type; + typedef RtecScheduler::Dependency_Type Dependency_Type; + + TimeLine_Entry_Link (TimeLine_Entry &t); + // ctor + + TimeLine_Entry &entry () const; + // accessor for the underlying entry + + int operator < (const TimeLine_Entry_Link&) const; + // comparison operator + +private: + + TimeLine_Entry &entry_; + // the underlying entry + +}; + + +#if defined (__ACE_INLINE__) +#include "SchedEntry.i" +#endif /* __ACE_INLINE__ */ + +#endif /* SCHEDENTRY_H */ + +// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.i b/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.i new file mode 100644 index 00000000000..690f7c33f33 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.i @@ -0,0 +1,374 @@ +/* -*- C++ -*- */ +// +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// SchedEntry.i +// +// = CREATION DATE +// 7 February 1998 +// +// = AUTHOR +// Chris Gill +// +// ============================================================================ + +////////////////////// +// Class Task_Entry // +////////////////////// + +// return a pointer to the underlying RT_Info +ACE_INLINE Task_Entry::RT_Info * +Task_Entry::rt_info () const +{ + return rt_info_; +} + +// set the underlying RT_Info pointer +ACE_INLINE void +Task_Entry::rt_info (Task_Entry::RT_Info *info) +{ + rt_info_ = info; +} + +// get effective period for the task entry +ACE_INLINE Task_Entry::Period +Task_Entry::effective_period () const +{ + return effective_period_; +} + +// set effective period for the task entry +ACE_INLINE void +Task_Entry::effective_period (Task_Entry::Period p) +{ + effective_period_ = p; +} + +ACE_INLINE void +Task_Entry::discovered (long l) +{ + discovered_ = l; + dfs_status_ = VISITED; +} + +ACE_INLINE long +Task_Entry::discovered () const +{ + return discovered_; +} + +ACE_INLINE void +Task_Entry::finished (long l) +{ + finished_ = l; + dfs_status_ = FINISHED; +} + +ACE_INLINE long +Task_Entry::finished () const +{ + return finished_; +} + +ACE_INLINE Task_Entry::DFS_Status +Task_Entry::dfs_status () const +{ + return dfs_status_; +} + +ACE_INLINE void +Task_Entry::dfs_status (Task_Entry::DFS_Status ds) +{ + dfs_status_ = ds; +} + +ACE_INLINE void +Task_Entry::is_thread_delineator (int i) +{ + is_thread_delineator_ = i; +} + +ACE_INLINE int +Task_Entry::is_thread_delineator () const +{ + return is_thread_delineator_; +} + +// access set of Task Entries on which this entry depends +ACE_INLINE ACE_Unbounded_Set <Task_Entry_Link *> & +Task_Entry::calls () +{ + return calls_; +} + +// access set of Task Entries which depend on this entry +ACE_INLINE ACE_Unbounded_Set <Task_Entry_Link *> & +Task_Entry::callers () +{ + return callers_; +} + +// get set of arrivals in the effective period +ACE_Ordered_MultiSet<Dispatch_Entry_Link> & +Task_Entry::dispatches () +{ + return dispatches_; +} + + +ACE_INLINE Task_Entry::Info_Type +Task_Entry::info_type () const +{ + return rt_info_->info_type; +} + +ACE_INLINE u_long +Task_Entry::effective_execution_time () const +{ + return (rt_info_->info_type == RtecScheduler::OPERATION) + ? rt_info_->worst_case_execution_time * arrival_count_ + : 0; +} + + +/////////////////////////// +// Class Task_Entry_Link // +/////////////////////////// + + +// accessor: number of calls of dependency by dependant +ACE_INLINE CORBA::Long +Task_Entry_Link::number_of_calls () const +{ + return number_of_calls_; +} + +ACE_INLINE Task_Entry_Link::Dependency_Type +Task_Entry_Link::dependency_type () const +{ + return dependency_type_; +} + +// accessor: dependant task entry +ACE_INLINE Task_Entry & +Task_Entry_Link::caller () const +{ + return caller_; +} + +// accessor: dependency task entry +ACE_INLINE Task_Entry & +Task_Entry_Link::called () const +{ + return called_; +} + +////////////////////////// +// Class Dispatch Entry // +////////////////////////// + +ACE_INLINE u_long +Dispatch_Entry::dispatch_id () const +{ + return dispatch_id_; +} + +ACE_INLINE Dispatch_Entry::Preemption_Priority +Dispatch_Entry::priority () const +{ + return priority_; +} + +ACE_INLINE void +Dispatch_Entry::priority (Dispatch_Entry::Preemption_Priority p) +{ + priority_ = p; +} + +ACE_INLINE Dispatch_Entry::OS_Priority +Dispatch_Entry::OS_priority () const +{ + return OS_priority_; +} + +ACE_INLINE void +Dispatch_Entry::OS_priority (Dispatch_Entry::OS_Priority p) +{ + OS_priority_ = p; +} + +ACE_INLINE Dispatch_Entry::Sub_Priority +Dispatch_Entry::dynamic_subpriority () const +{ + return dynamic_subpriority_; +} + +ACE_INLINE void +Dispatch_Entry::dynamic_subpriority (Dispatch_Entry::Sub_Priority p) +{ + dynamic_subpriority_ = p; +} + +ACE_INLINE Dispatch_Entry::Sub_Priority +Dispatch_Entry::static_subpriority () const +{ + return static_subpriority_; +} + +ACE_INLINE void +Dispatch_Entry::static_subpriority (Dispatch_Entry::Sub_Priority p) +{ + static_subpriority_ = p; +} + + +ACE_INLINE Dispatch_Entry::Time +Dispatch_Entry::arrival () const +{ + return arrival_; +} + +ACE_INLINE Dispatch_Entry::Time +Dispatch_Entry::deadline () const +{ + return deadline_; +} + +ACE_INLINE Task_Entry & +Dispatch_Entry::task_entry () const +{ + return task_entry_; +} + + +/////////////////////////////// +// Class Dispatch_Entry_Link // +/////////////////////////////// + +ACE_INLINE +Dispatch_Entry_Link::~Dispatch_Entry_Link () +{ +} + // dtor + +Dispatch_Entry_Link::operator < (const Dispatch_Entry_Link &d) const +{ + return (this->dispatch_entry_ < d.dispatch_entry_); +} + // GT comparator + + +ACE_INLINE Dispatch_Entry & +Dispatch_Entry_Link::dispatch_entry () const +{ + return dispatch_entry_; +} + // accessor for reference to dispatch entry + + +/////////////////////////////////// +// Class Dispatch_Proxy_Iterator // +/////////////////////////////////// + +ACE_INLINE int +Dispatch_Proxy_Iterator::done () const +{ + return iter_.done (); +} + // returns 0 if there are more entries to see, 1 if not + + +////////////////////////// +// Class TimeLine_Entry // +////////////////////////// + + // dispatch entry accessor +ACE_INLINE Dispatch_Entry & +TimeLine_Entry::dispatch_entry () const +{ + return dispatch_entry_; +} + + +// accessor for time slice start time (100 nanoseconds) +ACE_INLINE u_long +TimeLine_Entry::start () const +{ + return start_; +} + +// accessor for time slice stop time (100 nanoseconds) +ACE_INLINE u_long +TimeLine_Entry::stop () const +{ + return stop_; +} + +// accessor for next slice for this dispatch +ACE_INLINE TimeLine_Entry * +TimeLine_Entry::next (void) const +{ + return next_; +} + +// mutator for next slice for this dispatch +ACE_INLINE void +TimeLine_Entry::next (TimeLine_Entry *t) +{ + next_ = t; +} + +// accessor for previous slice for this dispatch +ACE_INLINE TimeLine_Entry * +TimeLine_Entry::prev (void) const +{ + return prev_; +} + +// mutator for previous slice for this dispatch +ACE_INLINE void +TimeLine_Entry::prev (TimeLine_Entry *t) +{ + prev_ = t; +} + + +ACE_INLINE int +TimeLine_Entry::operator < (const TimeLine_Entry &t) const +{ + return (start_ < t.start_) ? 1 : 0; +} + // comparison operator + + +/////////////////////////////// +// Class TimeLine_Entry_Link // +/////////////////////////////// + + +ACE_INLINE TimeLine_Entry_Link::TimeLine_Entry_Link (TimeLine_Entry &t) + : entry_ (t) +{ +} + // ctor + +ACE_INLINE TimeLine_Entry & +TimeLine_Entry_Link::entry () const +{ + return entry_; +} + // accessor for the underlying entry + +ACE_INLINE int +TimeLine_Entry_Link::operator < (const TimeLine_Entry_Link &l) const +{ + return (entry_ < l.entry_) ? 1 : 0; +} + // comparison operator + diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduler.cpp b/TAO/orbsvcs/orbsvcs/Sched/Scheduler.cpp new file mode 100644 index 00000000000..cfa1f2c97aa --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/Scheduler.cpp @@ -0,0 +1,283 @@ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// Scheduler.cpp +// +// = CREATION DATE +// 23 January 1997 +// +// = AUTHOR +// David Levine +// +// ============================================================================ + +#include "ace/Sched_Params.h" +#include "orbsvcs/Time_Utilities.h" +#include "Scheduler.h" + +#if ! defined (__ACE_INLINE__) +#include "Scheduler.i" +#endif /* __ACE_INLINE__ */ + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// class Scheduler static members +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +const ACE_Scheduler::mode_t ACE_Scheduler::CURRENT_MODE = 0xFFFFFFFF; + +ACE_Scheduler *ACE_Scheduler::instance_ = 0; + + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// class ACE_Scheduler static functions +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +void +ACE_Scheduler::output (FILE *file, const status_t status) +{ + switch (status) + { + case NOT_SCHEDULED : + ACE_OS::fprintf (file, "NOT_SCHEDULED"); + break; + case SUCCEEDED : + ACE_OS::fprintf (file, "SUCCEEDED"); + break; + case ST_TASK_ALREADY_REGISTERED : + ACE_OS::fprintf (file, "TASK_ALREADY_REGISTERED"); + break; + case ST_VIRTUAL_MEMORY_EXHAUSTED : + ACE_OS::fprintf (file, "VIRTUAL_MEMORY_EXHAUSTED"); + break; + case ST_UNKNOWN_TASK : + ACE_OS::fprintf (file, "UNKNOWN_TASK"); + break; + case INVALID_MODE : + ACE_OS::fprintf (file, "INVALID_MODE"); + break; + case MODE_COUNT_MISMATCH : + ACE_OS::fprintf (file, "MODE_COUNT_MISMATCH"); + break; + case TASK_COUNT_MISMATCH : + ACE_OS::fprintf (file, "TASK_COUNT_MISMATCH"); + break; + case INVALID_PRIORITY : + ACE_OS::fprintf (file, "INVALID_PRIORITY"); + break; + + // The following are only used during scheduling (in the case of + // off-line scheduling, they are only used prior to runtime). + // To save a little code space (280 bytes on g++ 2.7.2/Solaris 2.5.1), + // we could conditionally compile them so that they're not in the + // runtime version. + case ST_UTILIZATION_BOUND_EXCEEDED : + ACE_OS::fprintf (file, "UTILIZATION_BOUND_EXCEEDED"); + break; + case ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS : + ACE_OS::fprintf (file, "INSUFFICIENT_THREAD_PRIORITY_LEVELS"); + break; + case ST_CYCLE_IN_DEPENDENCIES : + ACE_OS::fprintf (file, "CYCLE_IN_DEPENDENCIES"); + break; + case UNABLE_TO_OPEN_SCHEDULE_FILE : + ACE_OS::fprintf (file, "UNABLE_TO_OPEN_SCHEDULE_FILE"); + break; + case UNABLE_TO_WRITE_SCHEDULE_FILE : + ACE_OS::fprintf (file, "UNABLE_TO_WRITE_SCHEDULE_FILE"); + break; + // End of config-only status values. + + default: + ACE_OS::fprintf (file, "UNKNOWN STATUS: %d", status); + } +} + + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// class ACE_Scheduler member functions +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +ACE_Scheduler::ACE_Scheduler () : + minimum_priority_queue_ (0), // Could initialize this to -1, but it's + // unsigned and we don't really need to + // distinguish between no queues and one + // queue. + modes_ (0), + tasks_ (0), + threads_ (0), + mode_ (0), + status_ (NOT_SCHEDULED), + output_level_ (0) +{ +} + + +ACE_Scheduler::~ACE_Scheduler () +{ +} + + +// ************************************************************ + +ACE_Scheduler::status_t +ACE_Scheduler::get_rt_info (Object_Name name, + RT_Info* &rtinfo) +{ + handle_t handle; + + // This makes a copy. We can optimize this with our own string + // class. + ACE_CString lookup (name); + // Search the map for the <name>. If found, return the RT_Info. + RT_Info **info_array = 0; + if (info_collection_.find (lookup, info_array) >= 0) + { + rtinfo = info_array[0]; + // If we find it, return. + return SUCCEEDED; + } + else + // Otherwise, make one, bind it, and register it. + { + rtinfo = new RT_Info; + rtinfo->entry_point = name; + // Create and array (size one) of RT_Info* + info_array = new RT_Info*[1]; + info_array[0] = rtinfo; + // Bind the rtinfo to the name. + if (info_collection_.bind (lookup, info_array) != 0) + { + delete rtinfo; + delete info_array; + rtinfo = 0; + return FAILED; // Error! + } + else + { + // Register the array. + status_t result = this->register_task (info_array, 1, handle); + if (result == SUCCEEDED) + { + rtinfo->handle = handle; + return ST_UNKNOWN_TASK; // Didn't find it, but made one! + } + else + { + rtinfo->handle = 0; + return FAILED; + } + } + } +} + + + +int ACE_Scheduler::number_of_dependencies(RT_Info* rt_info) +{ + return rt_info->dependencies.length(); +} + +int ACE_Scheduler::number_of_dependencies(RT_Info& rt_info) +{ + return rt_info.dependencies.length(); +} + +int ACE_Scheduler::add_dependency(RT_Info* rt_info, + const Dependency_Info& d) +{ + ACE_DEBUG ((LM_DEBUG, "adding dependecy to: %s\n", + (const char*)rt_info->entry_point)); + RtecScheduler::Dependency_Set& set = rt_info->dependencies; + int l = set.length(); + set.length(l + 1); + set[l] = d; + return 0; +} + +void ACE_Scheduler::export(RT_Info* info, FILE* file) +{ + export(*info, file); +} + +void ACE_Scheduler::export(RT_Info& info, FILE* file) +{ + // The divide-by-1 is for ACE_U_LongLong support. + (void) ACE_OS::fprintf (file, + "%s\n%d\n%ld\n%ld\n%ld\n%ld\n%d\n%ld\n%u\n" + "# begin dependencies\n%d\n", + (const char*)info.entry_point, + info.handle, + ORBSVCS_Time::to_hrtime (info.worst_case_execution_time) / 1, + ORBSVCS_Time::to_hrtime (info.typical_execution_time) / 1, + ORBSVCS_Time::to_hrtime (info.cached_execution_time) / 1, + info.period, + info.importance, + ORBSVCS_Time::to_hrtime (info.quantum) / 1, + info.threads, + number_of_dependencies(info)); + + for (int i = 0; i < number_of_dependencies(info); ++i) + { + RT_Info tmp; + // TODO: info.dependencies [i].rt_info >>= &tmp; + (void) ACE_OS::fprintf (file, "%s, %d\n", + (const char*)tmp.entry_point, + info.dependencies[i].number_of_calls); + + } + + (void) ACE_OS::fprintf (file, "# end dependencies\n%d\n%d\n\n", + info.priority, + info.subpriority); + + +} + + + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Lock_Adapter<ACE_SYNCH_NULL_MUTEX>; +template class ACE_Map_Entry<ACE_CString, ACE_Scheduler::RT_Info **>; + + template class ACE_Lock_Adapter<ACE_SYNCH_RW_MUTEX>; + template class ACE_Lock_Adapter<ACE_SYNCH_MUTEX>; + template class ACE_Map_Manager<ACE_CString, + ACE_Scheduler::RT_Info **, + ACE_SYNCH_MUTEX>; + template class ACE_Map_Iterator_Base<ACE_CString, ACE_Scheduler::RT_Info **, + ACE_SYNCH_MUTEX>; + template class ACE_Map_Iterator<ACE_CString, ACE_Scheduler::RT_Info **, + ACE_SYNCH_MUTEX>; + template class ACE_Map_Reverse_Iterator<ACE_CString, ACE_Scheduler::RT_Info **, + ACE_SYNCH_MUTEX>; + template class ACE_Read_Guard<ACE_SYNCH_MUTEX>; + template class ACE_Write_Guard<ACE_SYNCH_MUTEX>; + +#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate ACE_Lock_Adapter<ACE_SYNCH_NULL_MUTEX> +#pragma instantiate ACE_Map_Entry<ACE_CString, ACE_Scheduler::RT_Info **> + +#pragma instantiate ACE_Lock_Adapter<ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Lock_Adapter<ACE_SYNCH_MUTEX> +#pragma instantiate ACE_Map_Manager<ACE_CString, ACE_Scheduler::RT_Info **, ACE_SYNCH_MUTEX> +#pragma instantiate ACE_Map_Iterator_Base<ACE_CString, ACE_Scheduler::RT_Info **, ACE_SYNCH_MUTEX> +#pragma instantiate ACE_Map_Iterator<ACE_CString, ACE_Scheduler::RT_Info **, ACE_SYNCH_MUTEX> +#pragma instantiate ACE_Map_Reverse_Iterator<ACE_CString, ACE_Scheduler::RT_Info **, ACE_SYNCH_MUTEX> +#pragma instantiate ACE_Read_Guard<ACE_SYNCH_MUTEX> +#pragma instantiate ACE_Write_Guard<ACE_SYNCH_MUTEX> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + +// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduler.h b/TAO/orbsvcs/orbsvcs/Sched/Scheduler.h new file mode 100644 index 00000000000..e75dc5cb72e --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/Scheduler.h @@ -0,0 +1,272 @@ +/* -*- C++ -*- */ +// +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// Scheduler.h +// +// = CREATION DATE +// 23 January 1997 +// +// = AUTHOR +// David Levine +// +// ============================================================================ + +#if ! defined (SCHEDULER_H) +#define SCHEDULER_H + +#include "ace/ACE.h" +#include "ace/Map_Manager.h" +#include "ace/Message_Block.h" +#include "ace/Synch.h" +#include "ace/SString.h" + +#include "orbsvcs/RtecSchedulerC.h" +#include "orbsvcs/Event_Service_Constants.h" + +class ACE_Scheduler + // = TITLE + // Thread scheduler interface. + // + // = DESCRIPTION + // This virtual base class is the interface to either an off-line + // scheduler, or to the necessary on-line component of the Scheduler. +{ +public: + typedef u_int mode_t; + + typedef RtecScheduler::handle_t handle_t; + typedef RtecScheduler::Dependency_Info Dependency_Info; + typedef RtecScheduler::Preemption_Priority Preemption_Priority; + typedef RtecScheduler::OS_Priority OS_Thread_Priority; + typedef RtecScheduler::Sub_Priority Sub_Priority; + typedef RtecScheduler::RT_Info RT_Info; + // Map some types to simplify re-use. + + typedef const char *Object_Name; + // Objects are named by unique strings. + + static const mode_t CURRENT_MODE; + + enum status_t { + // The following are used both by the runtime Scheduler and during + // scheduling. + NOT_SCHEDULED = -1 // the schedule () method has not been called yet + , FAILED = -1 + , SUCCEEDED + , ST_UNKNOWN_TASK + , ST_TASK_ALREADY_REGISTERED + , ST_VIRTUAL_MEMORY_EXHAUSTED + + // The following are only used by the runtime Scheduler. + , INVALID_MODE + , MODE_COUNT_MISMATCH // only used by schedule () + , TASK_COUNT_MISMATCH // only used by schedule () + , INVALID_PRIORITY // only used by schedule (): mismatch of + // (off-line, maybe) Scheduler output to + // the runtime Scheduler component. + + // The following are only used during scheduling (in the case of + // off-line scheduling, they are only used prior to runtime). + , ST_UTILIZATION_BOUND_EXCEEDED + , ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS + , ST_CYCLE_IN_DEPENDENCIES + , UNABLE_TO_OPEN_SCHEDULE_FILE + , UNABLE_TO_WRITE_SCHEDULE_FILE + }; + + virtual ~ACE_Scheduler (); + + // = Utility function for outputting the textual representation of a + // status_t value to a FILE. + static void output (FILE *, const status_t); + + // = Initialize the scheduler. + virtual void init (const int minimum_priority, + const int maximum_priority, + const char *runtime_filename = 0, + const char *rt_info_filename = 0, + const char *timeline_filename = 0) = 0; + // The minimum and maximum priority are the OS-specific priorities that + // are used when creating the schedule (assigning priorities). The + // minimum_priority is the priority value of the lowest priority. + // It may be numerically higher than the maximum_priority, on OS's such + // as VxWorks that use lower values to indicate higher priorities. + // + // When Scheduler::schedule is called, the schedule is output to the + // file named by "runtime_filename" if it is non-zero. + // This file is compilable; it is linked into the runtime executable + // to provide priorities to the runtime scheduling component. + // If the "rt_info_filename" is non-zero, the RT_Info for + // every task is exported to it. It is not used at runtime. + // If the "timeline_filename" is non-zero, the timeline output + // file is created. It is not used at runtime. + // + // The runtime scheduling component ignores these filenames. It just + // uses the priorities that were linked in to the executable, after + // converting them to platform-specific values. + + // = Registers a task. + virtual status_t register_task (RT_Info *[], + const u_int number_of_modes, + handle_t &handle) = 0; + // If the Task registration succeeds, this function returns SUCCEEDED + // and sets "handle" to a unique identifier for the task. + // Otherwise, it returns either VIRTUAL_MEMORY_EXHAUSTED or + // TASK_ALREADY_REGISTERED sets the handle to 0. (A task may + // only be registered once.) + // The RT_Info * array is indexed by mode; there must be one element for + // each mode, as specified by number_of_modes. If a task does not + // run in a mode, then its entry in the array for that mode must + // be 0. + + virtual status_t get_rt_info (Object_Name name, + RT_Info* &rtinfo); + // Tries to find the RT_Info corresponding to <name> in the RT_Info + // database. Returns SUCCEEDED if <name> was found and <rtinfo> was + // set. Returns UNKNOWN_TASK if <name> was not found, but <rtinfo> + // was set to a newly allocated RT_Info. In this UNKNOWN_TASK case, + // the task must call RT_Info::set to fill in execution properties. + // In the SUCCEEDED and UNKNOWN_TASK cases, this->register_task + // (rtinfo, 0, handle) is called. Returns FAILED if an error + // occurs. + // + // One motivation for allocating RT_Info's from within the Scheduler + // is to allow RT_Infos to persist after the tasks that use them. + // For instance, we may want to call this->schedule right before the + // application exits a configuration run. If the tasks have been + // deleted (deleting their RT_Infos with them), this->schedule will + // fail. + + virtual status_t lookup_rt_info (handle_t handle, + RT_Info* &rtinfo) = 0; + // Obtains an RT_Info based on its "handle". + + // = Computes the schedule. + virtual status_t schedule (void) = 0; + // This actually generates the files. + + // = Access a thread priority. + virtual int priority (const handle_t handle, + OS_Thread_Priority &priority, + Sub_Priority &subpriority, + Preemption_Priority &preemption_prio, + const mode_t = CURRENT_MODE) const = 0; + // Defines "priority" as the priority that was assigned to the Task that + // was assigned "handle", for the specified mode. Defines "subpriority" + // as the relative ordering (due to dependencies) within the priority. + // Returns 0 on success, or -1 if an invalid mode or handle are supplied. + // Queue numbers are platform-independent priority values, ranging from + // a highest priority value of 0 to the lowest priority value, which is + // returned by "minimum_priority_queue ()". + + // = Access the platform-independent priority value of the lowest-priority + // thread. + u_int minimum_priority_queue () const { return minimum_priority_queue_; } + // This is intended for use by the Event Channel, so it can determine the + // number of priority dispatch queues to create. + + // = Access the number of modes. + u_int modes () const { return modes_; } + + // = Access the number of tasks. + u_int tasks () const { return tasks_; } + + // = Access the number of threads. + u_int threads () const { return threads_; } + + // = Access the current mode. + mode_t mode () const { return mode_; } + + // = Set the current mode. + void mode (const mode_t mode) { mode_ = mode; } + + // = Access the current scheduler status. + status_t status () const { return status_; } + + // = Access the current output (debugging) level. + u_int output_level () const { return output_level_; } + // Default is 0; set to 1 to print out schedule, by task. Set + // to higher than one for debugging info. + + // = Set the scheduler output (debugging) level. + void output_level (const u_int level) { output_level_ = level; } + // the only supported levels are 0 (quiet), 1 (verbose) and 2 + // (debug) + + static int add_dependency(RT_Info* rt_info, + const Dependency_Info& d); + + static int number_of_dependencies(RT_Info* rt_info); + static int number_of_dependencies(RT_Info& rt_info); + + static void export(RT_Info*, FILE* file); + static void export(RT_Info&, FILE* file); + +protected: + ACE_Scheduler (); + + // = Set the minimum priority value. + void minimum_priority_queue (const u_int minimum_priority_queue_number) + { minimum_priority_queue_ = minimum_priority_queue_number; } + + // = Set the number of modes. + void modes (const u_int modes) { modes_ = modes; } + + // = Set the number of tasks. + void tasks (const u_int tasks) { tasks_ = tasks; } + + // = Set the number of threads. + void threads (const u_int threads) { threads_ = threads; } + + // = Set the current scheduler status. + void status (const status_t new_status) { status_ = new_status; } + +private: + typedef ACE_CString EXT; + typedef RT_Info **INT; + + typedef ACE_Map_Manager<EXT, INT, ACE_SYNCH_MUTEX> Info_Collection; + typedef ACE_Map_Iterator<EXT, INT, ACE_SYNCH_MUTEX> Info_Collection_Iterator; + typedef ACE_Map_Entry<EXT, INT> Info_Collection_Entry; + + Info_Collection info_collection_; + // A binding of name to rt_info. This is the mapping for every + // rt_info in the process. + + static ACE_Scheduler *instance_; + + u_int minimum_priority_queue_; + // The platform-independent priority value of the Event Channel's + // minimum priority dispatch queue. The value of the maximum priority + // dispatch queue is always 0. + + u_int modes_; + u_int tasks_; + u_int threads_; + + mode_t mode_; + status_t status_; + u_int output_level_; + + // the following functions are not implememented + ACE_UNIMPLEMENTED_FUNC(ACE_Scheduler (const ACE_Scheduler &)) + ACE_UNIMPLEMENTED_FUNC(ACE_Scheduler &operator= (const ACE_Scheduler &)) +}; + +typedef ACE_Scheduler Scheduler; + +#if defined (__ACE_INLINE__) +#include "Scheduler.i" +#endif /* __ACE_INLINE__ */ + +#endif /* SCHEDULER_H */ + + +// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduler.i b/TAO/orbsvcs/orbsvcs/Sched/Scheduler.i new file mode 100644 index 00000000000..57875ae26d1 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/Scheduler.i @@ -0,0 +1,20 @@ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// Scheduler.i +// +// = CREATION DATE +// 23 January 1997 +// +// = AUTHOR +// David Levine +// +// ============================================================================ + +// EOF + diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.cpp b/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.cpp new file mode 100644 index 00000000000..1b36d49e1d6 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.cpp @@ -0,0 +1,262 @@ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// Scheduler_Generic.cpp +// +// = CREATION DATE +// 19 November 1997 +// +// = AUTHOR +// David Levine +// +// ============================================================================ + +#include "ace/Sched_Params.h" + +#include "Scheduler_Generic.h" + +#if ! defined (__ACE_INLINE__) +#include "Scheduler_Generic.i" +#endif /* __ACE_INLINE__ */ + + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// static functions +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +// Structure for storing the RT_Info information for each task, per mode. +struct Mode_Entry +{ + RtecScheduler::RT_Info *rt_info_; + u_long start_time_; // microseconds + u_long stop_time_; // microseconds + + Mode_Entry() : + rt_info_ (0), + start_time_ (0), + stop_time_ (0) + { + } + + Mode_Entry(RtecScheduler::RT_Info *const rt_info, + const u_long start_time = 0, + const u_long stop_time = 0) : + rt_info_ (rt_info), + start_time_ (start_time), + stop_time_ (stop_time) + { + } + + ~Mode_Entry () {} + + Mode_Entry &operator= (const Mode_Entry &entry) + { + if (this != &entry) + { + rt_info_ = entry.rt_info_; + start_time_ = entry.start_time_; + stop_time_ = entry.stop_time_; + } + + return *this; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// class Scheduler_Generic member functions +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +Scheduler_Generic::Scheduler_Generic () : + Scheduler (), + handles_ (0), + // Set the minimum priority to that for the current platform. This + // shouldn't be necessary, but UPSingleProcessorOrb::initialize_reactors + // creates threads before the Event Channel calls Scheduler::init (). + minimum_priority_ (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, + ACE_SCOPE_THREAD)), + increasing_priority_ (-1), + task_entries_ () +{ +} + + +Scheduler_Generic::~Scheduler_Generic () +{ + reset (); +} + + +void +Scheduler_Generic::reset () +{ +} + +Scheduler::status_t +Scheduler_Generic::lookup_rt_info (handle_t handle, + RT_Info*& rtinfo) +{ + if (handle < 0 || (size_t) handle > task_entries_.size ()) + { + return ST_UNKNOWN_TASK; + } + RT_Info*** entry; + ACE_Unbounded_Set_Iterator <RT_Info **> i (task_entries_); + while (i.next (entry) != 0) + { + i.advance (); + RT_Info** array = *entry; + if (array[0]->handle == handle) + { + rtinfo = array[0]; + return SUCCEEDED; + } + } + + return ST_UNKNOWN_TASK; +} + + +Scheduler::status_t +Scheduler_Generic::register_task (RT_Info *rt_info [], + const u_int number_of_modes, + handle_t &handle) +{ + status_t ret; + + // try to store the new task's information . . . + switch (task_entries_.insert (rt_info)) + { + case 0 : // successfully inserted + { + rt_info [0]->handle = (handle = ++handles_); + + // assigned the same handle to the RT_Info for each of its modes + for (u_int i = 1; i < number_of_modes; ++i) + { + if (rt_info [i] != 0) + rt_info [i]->handle = handle; + } + + if (number_of_modes > modes ()) + { + modes (number_of_modes); + } + + ret = SUCCEEDED; + + if (output_level () >= 5) + { + ACE_OS::printf ("registered task \"%s\" with RT_Info starting " + "at %X\n", + (const char*)rt_info[0]->entry_point, + (void *) rt_info[0]); + } + } + break; + + case 1 : // the entry had already been inserted + handle = 0; + ret = ST_TASK_ALREADY_REGISTERED; + break; + + default : + // case -1 : insert failed, probably because virtual memory exhaused + handle = 0; + ret = ST_VIRTUAL_MEMORY_EXHAUSTED; + break; + } + + return ret; +} + + +void +Scheduler_Generic::init (const int minimum_priority, + const int maximum_priority, + const char *runtime_filename, + const char *rt_info_filename, + const char *timeline_filename) +{ + minimum_priority_ = minimum_priority; + maximum_priority_ = maximum_priority; + runtime_filename_ = runtime_filename; + rt_info_filename_ = rt_info_filename; + timeline_filename_ = timeline_filename; +} + + +Scheduler::status_t +Scheduler_Generic::schedule (void) +{ + ACE_Guard<LOCK> ace_mon (lock_); + + // here goes . . . + + increasing_priority_ = maximum_priority_ >= minimum_priority_; + + status_t status = ACE_Scheduler::SUCCEEDED; + + // store number of tasks, based on registrations + tasks (task_entries_.size ()); + + if (output_level () > 0) + { + print_schedule (); + } + + return status; +} + + +int +Scheduler_Generic::priority (const handle_t handle, + OS_Thread_Priority &priority, + Sub_Priority &subpriority, + Preemption_Priority &preemption_prio, + const mode_t requested_mode) const +{ + ACE_UNUSED_ARG (handle); + ACE_UNUSED_ARG (requested_mode); + + priority = minimum_priority_; + subpriority = ACE_Scheduler_MIN_SUB_PRIORITY; + preemption_prio = ACE_Scheduler_MAX_PREEMPTION_PRIORITY; + + if (output_level () >= 3) + { + ACE_OS::printf ("preemption_prio %d: min %d, pri %d, min_pri %d\n", + preemption_prio, minimum_priority_queue (), + priority, minimum_priority_); + } + + return 0; +} + + +void +Scheduler_Generic::print_schedule () +{ +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Node<RtecScheduler::RT_Info **>; +template class ACE_Unbounded_Set<RtecScheduler::RT_Info **>; +template class ACE_Unbounded_Set_Iterator<RtecScheduler::RT_Info **>; +#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Node<RtecScheduler::RT_Info **> +#pragma instantiate ACE_Unbounded_Set<RtecScheduler::RT_Info **> +#pragma instantiate ACE_Unbounded_Set_Iterator<RtecScheduler::RT_Info **> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + + +// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.h b/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.h new file mode 100644 index 00000000000..ab22666a41e --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.h @@ -0,0 +1,129 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// Scheduler_Generic.h +// +// = CREATION DATE +// 19 November 1997 +// +// = AUTHOR +// David Levine +// +// ============================================================================ + +#if ! defined (SCHEDULER_INTERNAL_H) +#define SCHEDULER_INTERNAL_H + +#include "Scheduler.h" + +class Scheduler_Generic : public ACE_Scheduler + // = TITLE + // Implementation of an off-line scheduler. + // + // = DESCRIPTION + // Schedules tasks, assigning the same priority to all of them. +{ +public: + Scheduler_Generic (); + virtual ~Scheduler_Generic (); + + // = Initialize the scheduler. + virtual void init (const int minimum_priority, + const int maximum_priority, + const char *runtime_filename = 0, + const char *rt_info_filename = 0, + const char *timeline_filename = 0); + + // = Registers a task. + virtual status_t register_task (RT_Info *[], + const u_int number_of_modes, + handle_t &handle); + + virtual status_t lookup_rt_info (handle_t handle, + RT_Info* &rtinfo); + // Obtains an RT_Info based on its "handle". + + // = Computes the schedule. + virtual status_t schedule (void); + + // = Access a thread priority. + virtual int priority (const handle_t handle, + OS_Thread_Priority &priority, + Sub_Priority &subpriority, + Preemption_Priority &preemption_prio, + const mode_t = CURRENT_MODE) const; + // Defines "priority" as the priority that was assigned to the Task that + // was assigned "handle", for the specified mode. Defines "subpriority" + // as the relative ordering (due to dependencies) within the priority. + // Returns 0 on success, or 1 if an invalid mode or handle are supplied. + +private: + u_int handles_; + // The number of task handles dispensed so far. + + int minimum_priority_; + // The minimum priority value that the application specified (in + // its call to init ()). + + int maximum_priority_; + // The maximum priority value that the application specified (in + // its call to init ()). + + const char *runtime_filename_; + // Destination file of Scheduler output from the configuration run. + + const char *rt_info_filename_; + // Destination file of all rt_info data from the configuration run. + + const char *timeline_filename_; + // The destination of the timeline. + + int increasing_priority_; + // Set to 1 if priority values increase with increasing priority, + // such as on Solaris and Win32, or 0 if they decrease, such as on + // VxWorks. + + ACE_Unbounded_Set <RT_Info **> task_entries_; + // Collection of known tasks. + +#if defined (ACE_HAS_THREADS) + typedef ACE_Recursive_Thread_Mutex LOCK; +#else + typedef ACE_Null_Mutex LOCK; +#endif /* ACE_HAS_THREADS */ + + LOCK lock_; + // This protects access to the scheduler during configuration runs. + + + /////////////////////////////////////// + // member functions for internal use // + /////////////////////////////////////// + + void reset (); + // Prepare for another schedule computation, but do not + // disturb the "output" (priorities that have already been assigned). + + void print_schedule (); + // Display the schedule, task-by-task. + + ACE_UNIMPLEMENTED_FUNC (Scheduler_Generic (const Scheduler_Generic &)) + ACE_UNIMPLEMENTED_FUNC (Scheduler_Generic &operator= ( + const Scheduler_Generic &)) +}; + + +#if defined (__ACE_INLINE__) +#include "Scheduler_Generic.i" +#endif /* __ACE_INLINE__ */ + +#endif /* SCHEDULER_INTERNAL_H */ + + +// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.i b/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.i new file mode 100644 index 00000000000..71e3695dc35 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/Scheduler_Generic.i @@ -0,0 +1,21 @@ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// Scheduler_Generic.i +// +// = CREATION DATE +// 23 January 1997 +// +// = AUTHOR +// David Levine +// +// ============================================================================ + + +// EOF + diff --git a/TAO/orbsvcs/orbsvcs/Sched/Scheduling_Service.cpp b/TAO/orbsvcs/orbsvcs/Sched/Scheduling_Service.cpp new file mode 100644 index 00000000000..ffe45c7e582 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/Scheduling_Service.cpp @@ -0,0 +1,81 @@ +// +// $Id$ +// + +#include "tao/corba.h" + +#include "orbsvcs/CosNamingC.h" +#include "Config_Scheduler.h" + +int main (int argc, char *argv[]) +{ + TAO_TRY + { + // Initialize ORB. + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "internet", TAO_TRY_ENV); + TAO_CHECK_ENV; + + CORBA::Object_var poa_object = + orb->resolve_initial_references("RootPOA"); + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n"), + 1); + + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (poa_object.in (), TAO_TRY_ENV); + TAO_CHECK_ENV; + + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (TAO_TRY_ENV); + TAO_CHECK_ENV; + + CORBA::Object_var naming_obj = + orb->resolve_initial_references ("NameService"); + if (CORBA::is_nil (naming_obj.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n"), + 1); + + CosNaming::NamingContext_var naming_context = + CosNaming::NamingContext::_narrow (naming_obj.in (), TAO_TRY_ENV); + TAO_CHECK_ENV; + + // Create an Scheduling service servant... + ACE_Config_Scheduler scheduler_impl; + TAO_CHECK_ENV; + + RtecScheduler::Scheduler_var scheduler = + scheduler_impl._this (TAO_TRY_ENV); + TAO_CHECK_ENV; + + CORBA::String_var str = + orb->object_to_string (scheduler.in (), TAO_TRY_ENV); + TAO_CHECK_ENV; + + ACE_DEBUG ((LM_DEBUG, "The scheduler IOR is <%s>\n", str.in ())); + + // Register the servant with the Naming Context.... + CosNaming::Name schedule_name (1); + schedule_name.length (1); + schedule_name[0].id = CORBA::string_dup ("ScheduleService"); + naming_context->bind (schedule_name, scheduler.in (), TAO_TRY_ENV); + TAO_CHECK_ENV; + + poa_manager->activate (TAO_TRY_ENV); + TAO_CHECK_ENV; + + ACE_DEBUG ((LM_DEBUG, "running scheduling service\n")); + if (orb->run () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "run"), 1); + + } + TAO_CATCHANY + { + TAO_TRY_ENV.print_exception ("schedule_service"); + } + TAO_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.cpp b/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.cpp new file mode 100644 index 00000000000..8460a689eea --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.cpp @@ -0,0 +1,981 @@ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// Strategy_Scheduler.cpp +// +// = CREATION DATE +// 22 December 1997 +// +// = AUTHOR +// Chris Gill +// +// ============================================================================ + +#include <math.h> +#include <float.h> + +#include "ace/Sched_Params.h" + +#include "Strategy_Scheduler.h" + +#if ! defined (__ACE_INLINE__) +#include "Strategy_Scheduler.i" +#endif /* __ACE_INLINE__ */ + +////////////////////////////////////////////// +// helper function type definition for sort // +////////////////////////////////////////////// + +// this is awkward, but it makes MSVC++ happy +extern "C" +{ +typedef int (*COMP_FUNC) (const void*, const void*); +} + +/////////////////////////////////////////////////// +// class ACE_Strategy_Scheduler member functions // +/////////////////////////////////////////////////// + +ACE_Strategy_Scheduler::ACE_Strategy_Scheduler (ACE_Scheduler_Strategy &strategy) + : ACE_Scheduler (), + strategy_ (strategy) +{ +} + // = ctor + + +ACE_Strategy_Scheduler::~ACE_Strategy_Scheduler () +{ +} + // = virtual dtor + + +ACE_Scheduler::status_t +ACE_Strategy_Scheduler::sort_dispatches (Dispatch_Entry **dispatches, + u_int count) +{ + // sort the entries in order of priority and subpriority + strategy_.sort (dispatches, count); + + return ACE_Scheduler::SUCCEEDED; +} + // = sets up the schedule in the order generated + // by the strategy's comparison operators + +ACE_Scheduler::status_t +ACE_Strategy_Scheduler::assign_priorities (Dispatch_Entry **dispatches, + u_int count) +{ + // start with happy status + ACE_Scheduler::status_t status = ACE_Scheduler::SUCCEEDED; + + // start with the highest OS priority in the given range and work downward: + // if we run out of values to assign, return an error. + int current_OS_priority = maximum_priority_; + + // start scheduler priority at 0 (highest priority queue number) + // NOTE: 0 is highest for priority, lowest for dynamic and static subpriority + Preemption_Priority current_scheduler_priority = 0; + + // value the OS and scheduler priorities in 0th dispatch entry + dispatches[0]->OS_priority (current_OS_priority); + dispatches[0]->priority (current_scheduler_priority); + + // traverse ordered dispatch entry array, assigning priority + // (array is sorted from highest to lowest priority) + for (u_int i = 1; i < count; ++i) + { + switch (strategy_.priority_comp (*(dispatches[i-1]), + *(dispatches[i]))) + { + case -1: // the current entry is at lower priority than the previous + { + // decrease priority by incrementing the current scheduling priority + // number: 0 is the highest priority number. + ++current_scheduler_priority; + + // check for OS priority level boundaries: because OS priority values + // can run in either increasing or decreasing order, there is no easy, + // portable way to check other than exact comparison to the bounds + // that were given in init () or that came from the platform itself. + if ((current_OS_priority == minimum_priority_) || + (current_OS_priority == ACE_Sched_Params::previous_priority ( + ACE_SCHED_FIFO, + current_OS_priority, + ACE_SCOPE_PROCESS))) + { + // if we have run out of priority levels to assign, indicate + // this in the return status, but keep right on assigning the + // minimum OS priority in the range to the remaining tasks. + status = ACE_Scheduler::ST_INSUFFICIENT_THREAD_PRIORITY_LEVELS; + } + else + { + // we're still in range, so decrement the current OS priority level + current_OS_priority = + ACE_Sched_Params::previous_priority (ACE_SCHED_FIFO, + current_OS_priority, + ACE_SCOPE_PROCESS); + } + + break; + } + case 0: // still at the same priority level + + break; + + default: // should never reach here: something *bad* has happened + + ACE_ERROR_RETURN (( + LM_ERROR, + "Priority assignment failure: tasks" + " \"%s\" and \"%s\" are out of order.\n", + dispatches [i-1]->task_entry ().rt_info ()->entry_point, + dispatches [i]->task_entry ().rt_info ()->entry_point), + ACE_Scheduler::ST_INVALID_PRIORITY_ORDERING); + } + + // set OS priority of the current dispatch entry + dispatches[i]->OS_priority (current_OS_priority); + + // set scheduler priority of the current dispatch entry + dispatches[i]->priority (current_scheduler_priority); + } + + return status; +} + // = assigns priorities and sub-priorities to the sorted schedule, + // according to the strategy's priority comparison operator. + +ACE_Scheduler::status_t +ACE_Strategy_Scheduler::assign_subpriorities (Dispatch_Entry **dispatches, + u_int count) +{ + // start both subpriority counts at 0, set these values in + // the first entry, and increment the static subpriority count + Sub_Priority dynamic_subpriorities = 0; + Sub_Priority static_subpriorities = 0; + dispatches[0]->dynamic_subpriority (dynamic_subpriorities); + dispatches[0]->static_subpriority (static_subpriorities++); + + + // traverse ordered dispatch entry array, assigning priority + // (array is sorted from highest to lowest priority) + for (u_int i = 1; i < count; ++i) + { + switch (strategy_.priority_comp (*(dispatches[i-1]), + *(dispatches[i]))) + { + case -1: // the current entry is at lower priority than the previous + { + // fill in the high to low subpriority values by subtracting the + // previously assigned subpriorities from the total number of + // subpriorities + int j; + for (j = 1; j <= dynamic_subpriorities; ++j) + { + dispatches[i - j]-> + dynamic_subpriority (dynamic_subpriorities - + dispatches[i - j]-> + dynamic_subpriority ()); + } + for (j = 1; j <= static_subpriorities; ++j) + { + dispatches[i - j]-> + static_subpriority (static_subpriorities - + dispatches[i - j]-> + static_subpriority ()); + } + + // reset the subpriority counters, set these values in the + // current entry, and increment the static subpriority counter + dynamic_subpriorities = 0; + static_subpriorities = 0; + dispatches[i]->dynamic_subpriority (dynamic_subpriorities); + dispatches[i]->static_subpriority (static_subpriorities++); + + break; + } + + case 0: // still at the same priority level + + // compare the dynamic subpriorities + switch (strategy_.dynamic_subpriority_comp (*(dispatches[i-1]), + *(dispatches[i]))) + { + case -1: // the current entry is at lower dynamic subpriority + { + // increment dynamic subpriority counter + ++dynamic_subpriorities; + + // fill in the high to low static subpriority values by + // subtracting the previously assigned subpriorities from + // the total number of subpriorities + for (int j = 1; j <= static_subpriorities; ++j) + { + dispatches[i - j]-> + static_subpriority (static_subpriorities - + dispatches[i - j]-> + static_subpriority ()); + } + + // reset the static subpriority counter, set this value in the + // current entry, and increment the static subpriority counter + static_subpriorities = 0; + dispatches[i]->static_subpriority (static_subpriorities++); + + break; + } + + case 0: // still at the same dynamic subpriority level + + { + switch (strategy_.static_subpriority_comp (*(dispatches[i-1]), + *(dispatches[i]))) + { + case -1: + case 0: + + // assign and then increment the static subpriority: even if + // still at the same static subpriority level as far as the + // scheduling strategy is concerned, assign a new one + // anyway, to give a completely deterministic schedule + dispatches[i]->static_subpriority (static_subpriorities++); + break; + + default: // should never reach here: something *bad* has happened + + ACE_ERROR_RETURN (( + LM_ERROR, + "Static subpriority assignment failure: tasks" + " \"%s\" and \"%s\" are out of order.\n", + dispatches[i-1]->task_entry ().rt_info ()->entry_point, + dispatches[i]->task_entry ().rt_info ()->entry_point), + ACE_Scheduler::ST_INVALID_PRIORITY_ORDERING); + } + + break; + } + + default: // should never reach here: something *bad* has happened + + ACE_ERROR_RETURN (( + LM_ERROR, + "Dynamic subpriority assignment failure: tasks" + " \"%s\" and \"%s\" are out of order.\n", + dispatches[i-1]->task_entry ().rt_info ()->entry_point, + dispatches[i]->task_entry ().rt_info ()->entry_point), + ACE_Scheduler::ST_INVALID_PRIORITY_ORDERING); + } + + dispatches[i]->dynamic_subpriority (dynamic_subpriorities); + break; + + default: // should never reach here: something *bad* has happened + + ACE_ERROR_RETURN (( + LM_ERROR, + "Priority assignment failure: tasks" + " \"%s\" and \"%s\" are out of order.\n", + dispatches[i-1]->task_entry ().rt_info ()->entry_point, + dispatches[i]->task_entry ().rt_info ()->entry_point), + ACE_Scheduler::ST_INVALID_PRIORITY_ORDERING); + } + } + + return ACE_Scheduler::SUCCEEDED; +} + + +ACE_Scheduler::Preemption_Priority +ACE_Strategy_Scheduler::minimum_critical_priority () +{ + return strategy_.minimum_critical_priority (); +} + // = determine the minimum critical priority number + + +//////////////////////////////////////////////////////////////////// +// class template ACE_Strategy_Scheduler_Factory member functions // +//////////////////////////////////////////////////////////////////// + +template <class STRATEGY> +ACE_Strategy_Scheduler * +ACE_Strategy_Scheduler_Factory<STRATEGY>::create (ACE_Scheduler::Preemption_Priority minimum_critical_priority) +{ + ACE_Strategy_Scheduler *the_scheduler = 0; + STRATEGY *the_strategy; + + ACE_NEW_RETURN(the_strategy, STRATEGY(minimum_critical_priority), 0); + + ACE_NEW_RETURN (the_scheduler, ACE_Strategy_Scheduler (*the_strategy), 0); + + return the_scheduler; +}; + // construct and return a scheduler strategized with + // an instance of the the parameterized strategy type + + + +///////////////////////////////////////////////////////////////// +// abstract base class ACE_Scheduler_Strategy member functions // +///////////////////////////////////////////////////////////////// + + +ACE_Scheduler_Strategy::ACE_Scheduler_Strategy ( + ACE_Scheduler::Preemption_Priority minimum_critical_priority) + : minimum_critical_priority_ (minimum_critical_priority) +{ +} + // ctor + +int +ACE_Scheduler_Strategy::sort_comp + (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry) +{ + // order first by the priority ordering + int result = priority_comp (first_entry, second_entry); + + // within same priority, order by dynamic subpriority + if (result == 0) + { + result = dynamic_subpriority_comp (first_entry, second_entry); + } + + // if same dynamic subpriority, order by static subpriority + if (result == 0) + { + result = static_subpriority_comp (first_entry, second_entry); + } + + return result; +} + // = comparison of two dispatch entries using the specific priority, dynamic + // subpriority, and static subpriority method definitions provided by + // the derived strategy class to produce the strategy specific sort + // ordering: returns -1 if the first Dispatch_Entry is greater in the order, + // 0 if they are equivalent, or 1 if the second Dispatch_Entry is greater in + // the order + + +ACE_Scheduler_Strategy::static_subpriority_comp ( + const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry) +{ + // order first by importance assigned to underlying RT_Info (descending) + if (first_entry.task_entry ().rt_info ()->importance > + second_entry.task_entry ().rt_info ()->importance) + { + return -1; + } + else if (first_entry.task_entry ().rt_info ()->importance < + second_entry.task_entry ().rt_info ()->importance) + { + return 1; + } + else + { + // order last by the topological sort finishing time (ascending) + if (first_entry.task_entry ().finished () < + second_entry.task_entry ().finished ()) + { + return -1; + } + else if (first_entry.task_entry ().finished () > + second_entry.task_entry ().finished ()) + { + return 1; + } + else + { + // should never get here: all entries should be ordered by finishing time + ACE_ERROR ((LM_ERROR, + "minimal ordering failure for tasks \"%s\" and \"%s\".\n", + first_entry.task_entry ().rt_info ()->entry_point, + second_entry.task_entry ().rt_info ()->entry_point)); + return 0; + } + } +} + +ACE_Scheduler::Preemption_Priority +ACE_Scheduler_Strategy::minimum_critical_priority () +{ + return 0; +} + // = returns 0 for minimum critical priority number + + +///////////////////////////////////////////////////////////////////////// +// class ACE_MUF_Scheduler_Strategy static data member initializations // +///////////////////////////////////////////////////////////////////////// + +ACE_MUF_Scheduler_Strategy * ACE_MUF_Scheduler_Strategy::instance_ = 0; + +/////////////////////////////////////////////////////// +// class ACE_MUF_Scheduler_Strategy member functions // +/////////////////////////////////////////////////////// + +ACE_MUF_Scheduler_Strategy * +ACE_MUF_Scheduler_Strategy::instance () +{ + if (0 == ACE_MUF_Scheduler_Strategy::instance_) + { + ACE_NEW_RETURN (ACE_MUF_Scheduler_Strategy::instance_, + ACE_MUF_Scheduler_Strategy, 0); + } + + return ACE_MUF_Scheduler_Strategy::instance_; +} + +int +ACE_MUF_Scheduler_Strategy::priority_comp (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry) +{ + // order by criticality (descending) + if (first_entry.task_entry ().rt_info ()->criticality > + second_entry.task_entry ().rt_info ()->criticality) + { + return -1; + } + else if (first_entry.task_entry ().rt_info ()->criticality < + second_entry.task_entry ().rt_info ()->criticality) + { + return 1; + } + else + { + return 0; // same priority level + } +} + // = comparison of two dispatch entries by maximum criticality: returns -1 if the + // first Dispatch_Entry is greater in the order, 0 if they're equivalent, or + // 1 if the second Dispatch_Entry is greater in the order. + + +void +ACE_MUF_Scheduler_Strategy::sort (Dispatch_Entry **dispatch_entries, u_int size) +{ + ::qsort ((void *) dispatch_entries, + size, + sizeof (Dispatch_Entry *), + (COMP_FUNC) ACE_MUF_Scheduler_Strategy::sort_function); +} + // = sort the dispatch entry pointer array in descending urgency order + + +ACE_MUF_Scheduler_Strategy::ACE_MUF_Scheduler_Strategy ( + ACE_Scheduler::Preemption_Priority minimum_critical_priority) + :ACE_Scheduler_Strategy (minimum_critical_priority) +{ +} + // = default ctor + +ACE_MUF_Scheduler_Strategy::~ACE_MUF_Scheduler_Strategy () +{ +} + // = virtual dtor + +int +ACE_MUF_Scheduler_Strategy::dynamic_subpriority_comp + (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry) +{ + // order by descending dynamic priority according to ascending laxity + u_long laxity1 = + first_entry.deadline () - + first_entry.task_entry ().rt_info ()->worst_case_execution_time; + + u_long laxity2 = + second_entry.deadline () - + second_entry.task_entry ().rt_info ()->worst_case_execution_time; + + + if (laxity1 < laxity2) + { + return -1; + } + else if (laxity1 > laxity2) + { + return 1; + } + else + { + return 0; + } +} + // = orders of two dispatch entries by ascending laxity: returns -1 if the + // first Dispatch_Entry is greater in the order, 0 if they're equivalent, + // 1 if the second Dispatch_Entry is greater in the order. + + +int +ACE_MUF_Scheduler_Strategy::sort_function (void *arg1, void *arg2) +{ + return ACE_MUF_Scheduler_Strategy::instance ()-> + sort_comp (** ACE_static_cast (Dispatch_Entry **, arg1), + ** ACE_static_cast (Dispatch_Entry **, arg2)); +} + // comparison function to pass to qsort + +ACE_Scheduler::Preemption_Priority +ACE_MUF_Scheduler_Strategy::minimum_critical_priority () +{ + return minimum_critical_priority_; +} + // = returns 0 for minimum critical priority number + +///////////////////////////////////////////////////////////////////////// +// class ACE_RMS_Scheduler_Strategy static data member initializations // +///////////////////////////////////////////////////////////////////////// + +ACE_RMS_Scheduler_Strategy * ACE_RMS_Scheduler_Strategy::instance_ = 0; + +/////////////////////////////////////////////////////// +// class ACE_RMS_Scheduler_Strategy member functions // +/////////////////////////////////////////////////////// + +ACE_RMS_Scheduler_Strategy * +ACE_RMS_Scheduler_Strategy::instance () +{ + if (0 == ACE_RMS_Scheduler_Strategy::instance_) + { + ACE_NEW_RETURN (ACE_RMS_Scheduler_Strategy::instance_, + ACE_RMS_Scheduler_Strategy, 0); + } + + return ACE_RMS_Scheduler_Strategy::instance_; +} + +int +ACE_RMS_Scheduler_Strategy::priority_comp (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry) +{ + // compare by decreasing dispatch period + if ((first_entry.deadline () - first_entry.arrival ()) < + (second_entry.deadline () - second_entry.arrival ())) + { + return -1; + } + else if ((first_entry.deadline () - first_entry.arrival ()) > + (second_entry.deadline () - second_entry.arrival ())) + { + return 1; + } + else + { + return 0; // same priority level + } +} + // = comparison of two dispatch entries by minimum period: returns -1 if the + // first Dispatch_Entry is greater in the order, 0 if they're equivalent, + // or 1 if the second Dispatch_Entry is greater in the order. + +void +ACE_RMS_Scheduler_Strategy::sort ( + Dispatch_Entry **dispatch_entries_, u_int size) +{ + ::qsort ((void *) dispatch_entries_, + size, + sizeof (Dispatch_Entry *), + (COMP_FUNC) ACE_RMS_Scheduler_Strategy::sort_function); +} + // = sort the dispatch entry pointer array in descending RMS (rate) order + +ACE_RMS_Scheduler_Strategy::ACE_RMS_Scheduler_Strategy ( + ACE_Scheduler::Preemption_Priority minimum_critical_priority) + :ACE_Scheduler_Strategy (0) +{ +} + // = default ctor + +ACE_RMS_Scheduler_Strategy::~ACE_RMS_Scheduler_Strategy () +{ +} + // = virtual dtor + +int +ACE_RMS_Scheduler_Strategy::dynamic_subpriority_comp + (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry) +{ + return 0; +} + // = all tasks in a given priority level have the same dynamic + // subpriority under RMS + + +int +ACE_RMS_Scheduler_Strategy::sort_function (void *arg1, void *arg2) +{ + return ACE_RMS_Scheduler_Strategy::instance ()-> + sort_comp (** ACE_static_cast (Dispatch_Entry **, arg1), + ** ACE_static_cast (Dispatch_Entry **, arg2)); +} + // comparison function to pass to qsort + + +///////////////////////////////////////////////////////////////////////// +// class ACE_MLF_Scheduler_Strategy static data member initializations // +///////////////////////////////////////////////////////////////////////// + +ACE_MLF_Scheduler_Strategy * ACE_MLF_Scheduler_Strategy::instance_ = 0; + +/////////////////////////////////////////////////////// +// class ACE_MLF_Scheduler_Strategy member functions // +/////////////////////////////////////////////////////// + +ACE_MLF_Scheduler_Strategy * +ACE_MLF_Scheduler_Strategy::instance () +{ + if (0 == ACE_MLF_Scheduler_Strategy::instance_) + { + ACE_NEW_RETURN (ACE_MLF_Scheduler_Strategy::instance_, + ACE_MLF_Scheduler_Strategy, 0); + } + + return ACE_MLF_Scheduler_Strategy::instance_; +} + +int +ACE_MLF_Scheduler_Strategy::priority_comp (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry) +{ + return 0; +} + // = just returns 0, as all dispatch entries are of equivalent priority under MLF. + +void +ACE_MLF_Scheduler_Strategy::sort ( + Dispatch_Entry **dispatch_entries_, u_int size) +{ + ::qsort ((void *) dispatch_entries_, + size, + sizeof (Dispatch_Entry *), + (COMP_FUNC) ACE_MLF_Scheduler_Strategy::sort_function); +} + // = sort the dispatch entry pointer array in ascending laxity order + + +ACE_MLF_Scheduler_Strategy::ACE_MLF_Scheduler_Strategy ( + ACE_Scheduler::Preemption_Priority minimum_critical_priority) + :ACE_Scheduler_Strategy (0) +{ +} + // = default ctor + +ACE_MLF_Scheduler_Strategy::~ACE_MLF_Scheduler_Strategy () +{ +} + // = virtual dtor + + +int +ACE_MLF_Scheduler_Strategy::dynamic_subpriority_comp + (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry) +{ + // order by laxity (ascending) + // order by descending dynamic priority according to ascending laxity + u_long laxity1 = + first_entry.deadline () - + first_entry.task_entry ().rt_info ()->worst_case_execution_time; + + u_long laxity2 = + second_entry.deadline () - + second_entry.task_entry ().rt_info ()->worst_case_execution_time; + + if (laxity1 < laxity2) + { + return -1; + } + else if (laxity1 > laxity2) + { + return 1; + } + else + { + return 0; + } +} + // = orders two dispatch entries by ascending laxity: returns -1 if the + // first Dispatch_Entry is greater in the order, 0 if they're equivalent, + // or 1 if the second Dispatch_Entry is greater in the order. + + +int +ACE_MLF_Scheduler_Strategy::sort_function (void *arg1, void *arg2) +{ + return ACE_MLF_Scheduler_Strategy::instance ()-> + sort_comp (** ACE_static_cast (Dispatch_Entry **, arg1), + ** ACE_static_cast (Dispatch_Entry **, arg2)); +} + // comparison function to pass to qsort + + +///////////////////////////////////////////////////////////////////////// +// class ACE_EDF_Scheduler_Strategy static data member initializations // +///////////////////////////////////////////////////////////////////////// + +ACE_EDF_Scheduler_Strategy * ACE_EDF_Scheduler_Strategy::instance_ = 0; + +/////////////////////////////////////////////////////// +// class ACE_EDF_Scheduler_Strategy member functions // +/////////////////////////////////////////////////////// + +ACE_EDF_Scheduler_Strategy * +ACE_EDF_Scheduler_Strategy::instance () +{ + if (0 == ACE_EDF_Scheduler_Strategy::instance_) + { + ACE_NEW_RETURN (ACE_EDF_Scheduler_Strategy::instance_, + ACE_EDF_Scheduler_Strategy, 0); + } + + return ACE_EDF_Scheduler_Strategy::instance_; +} + + +int +ACE_EDF_Scheduler_Strategy::priority_comp (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry) +{ + return 0; +} + // = just returns 0, as all dispatch entries are of equivalent priority under EDF. + +void +ACE_EDF_Scheduler_Strategy::sort ( + Dispatch_Entry **dispatch_entries_, u_int size) +{ + ::qsort ((void *) dispatch_entries_, + size, + sizeof (Dispatch_Entry *), + (COMP_FUNC) ACE_EDF_Scheduler_Strategy::sort_function); +} + // = sort the dispatch entry pointer array in ascending deadline (period) order + + +ACE_EDF_Scheduler_Strategy::ACE_EDF_Scheduler_Strategy ( + ACE_Scheduler::Preemption_Priority minimum_critical_priority) + :ACE_Scheduler_Strategy (0) +{ +} + // = default ctor + +ACE_EDF_Scheduler_Strategy::~ACE_EDF_Scheduler_Strategy () +{ +} + // = virtual dtor + +int +ACE_EDF_Scheduler_Strategy::dynamic_subpriority_comp + (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry) +{ + // order by dispatchable interval (ascending) + if (first_entry.deadline () < second_entry.deadline ()) + { + return -1; + } + else if (first_entry.deadline () > second_entry.deadline ()) + { + return 1; + } + else + { + return 0; + } +} + // = orders two dispatch entries by ascending time to deadline: returns -1 if + // the first Dispatch_Entry is greater in the order, 0 if they're equivalent, + // or 1 if the second Dispatch_Entry is greater in the order. + + +int +ACE_EDF_Scheduler_Strategy::sort_function (void *arg1, void *arg2) +{ + return ACE_EDF_Scheduler_Strategy::instance ()-> + sort_comp (** ACE_static_cast (Dispatch_Entry **, arg1), + ** ACE_static_cast (Dispatch_Entry **, arg2)); +} + // comparison function to pass to qsort + +///////////////////////////////////////////////////////////////////////////// +// class ACE_RMS_Dyn_Scheduler_Strategy static data member initializations // +///////////////////////////////////////////////////////////////////////////// + +ACE_RMS_Dyn_Scheduler_Strategy * ACE_RMS_Dyn_Scheduler_Strategy::instance_ = 0; + +/////////////////////////////////////////////////////////// +// class ACE_RMS_Dyn_Scheduler_Strategy member functions // +/////////////////////////////////////////////////////////// + +ACE_RMS_Dyn_Scheduler_Strategy * +ACE_RMS_Dyn_Scheduler_Strategy::instance () +{ + if (0 == ACE_RMS_Dyn_Scheduler_Strategy::instance_) + { + ACE_NEW_RETURN (ACE_RMS_Dyn_Scheduler_Strategy::instance_, + ACE_RMS_Dyn_Scheduler_Strategy, 0); + } + + return ACE_RMS_Dyn_Scheduler_Strategy::instance_; +} + + +int +ACE_RMS_Dyn_Scheduler_Strategy::priority_comp (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry) +{ + if ((first_entry.task_entry ().rt_info ()->criticality >= + RtecScheduler::HIGH_CRITICALITY) && + (second_entry.task_entry ().rt_info ()->criticality >= + RtecScheduler::HIGH_CRITICALITY)) + { + // if they're both in the high criticality bracket, + // order by dispatch period as in RMS scheduling + if ((first_entry.deadline () - first_entry.arrival ()) < + (second_entry.deadline () - second_entry.arrival ())) + { + return -1; + } + else if ((first_entry.deadline () - first_entry.arrival ()) > + (second_entry.deadline () - second_entry.arrival ())) + { + return 1; + } + + return 0; // same priority level + } + else if ((first_entry.task_entry ().rt_info ()->criticality < + RtecScheduler::HIGH_CRITICALITY) && + (second_entry.task_entry ().rt_info ()->criticality < + RtecScheduler::HIGH_CRITICALITY)) + { + // if they're both in the low criticality bracket, they have the same priority + return 0; + } + + // they're in different criticality brackets: order by criticality (descending) + return (first_entry.task_entry ().rt_info ()->criticality > + second_entry.task_entry ().rt_info ()->criticality) + ? -1 : 1; +} + // = comparison of two dispatch entries by maximum criticality: returns -1 + // if the first Dispatch_Entry is greater in the order, 0 if they're + // equivalent, or 1 if the second Dispatch_Entry is greater in the order. + + +void +ACE_RMS_Dyn_Scheduler_Strategy::sort ( + Dispatch_Entry **dispatch_entries_, u_int size) +{ + ::qsort ((void *) dispatch_entries_, + size, + sizeof (Dispatch_Entry *), + (COMP_FUNC) ACE_RMS_Dyn_Scheduler_Strategy::sort_function); +} + // = sort the dispatch entry pointer array in descending priority order + + +ACE_RMS_Dyn_Scheduler_Strategy::ACE_RMS_Dyn_Scheduler_Strategy ( + ACE_Scheduler::Preemption_Priority minimum_critical_priority) + :ACE_Scheduler_Strategy (minimum_critical_priority) +{ +} + // = default ctor + +ACE_RMS_Dyn_Scheduler_Strategy::~ACE_RMS_Dyn_Scheduler_Strategy () +{ +} + // = virtual dtor + +int +ACE_RMS_Dyn_Scheduler_Strategy::dynamic_subpriority_comp + (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry) +{ + // if either is in the high criticality bracket, we do not + // distinguish between them on the basis of dynamic subpriority + if ((first_entry.task_entry ().rt_info ()->criticality >= + RtecScheduler::HIGH_CRITICALITY) || + (second_entry.task_entry ().rt_info ()->criticality >= + RtecScheduler::HIGH_CRITICALITY)) + { + // for HIGH_CRITICALITY and VERY_HIGH_CRITICALITY, all + // entries have the same dynamic subpriority as in RMS + return 0; + } + else + { + // for VERY_LOW_CRITICALITY, LOW_CRITICALITY and MEDIUM_CRITICALITY, + // order second by laxity (ascending) + u_long laxity1 = + first_entry.deadline () - + first_entry.task_entry ().rt_info ()->worst_case_execution_time; + + u_long laxity2 = + second_entry.deadline () - + second_entry.task_entry ().rt_info ()->worst_case_execution_time; + + if (laxity1 < laxity2) + { + return -1; + } + else if (laxity1 > laxity2) + { + return 1; + } + else + { + return 0; + } + } +} + // = comparison of two dispatch entries within the very high and high + // criticality sets by minimum period (RMS) or of two dispatch entries + // within the medium, low, and very low criticality sets by minimum + // laxity: returns -1 if the first Dispatch_Entry is greater in the order, + // 0 if they're equivalent, or 1 if the second Dispatch_Entry is greater + // in the order. + +int +ACE_RMS_Dyn_Scheduler_Strategy::sort_function (void *arg1, void *arg2) +{ + return ACE_RMS_Dyn_Scheduler_Strategy::instance ()-> + sort_comp (** ACE_static_cast (Dispatch_Entry **, arg1), + ** ACE_static_cast (Dispatch_Entry **, arg2)); +} + // comparison function to pass to qsort + + +ACE_Scheduler::Preemption_Priority +ACE_RMS_Dyn_Scheduler_Strategy::minimum_critical_priority () +{ + return minimum_critical_priority_; +} + // = returns 0 for minimum critical priority number + + + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Node<Dispatch_Entry *>; +template class ACE_Unbounded_Set<Dispatch_Entry *>; +template class ACE_Unbounded_Set_Iterator<Dispatch_Entry *>; +template class ACE_Strategy_Scheduler_Factory<ACE_MUF_Scheduler_Strategy>; +template class ACE_Strategy_Scheduler_Factory<ACE_RMS_Scheduler_Strategy>; +template class ACE_Strategy_Scheduler_Factory<ACE_MLF_Scheduler_Strategy>; +template class ACE_Strategy_Scheduler_Factory<ACE_EDF_Scheduler_Strategy>; +template class ACE_Strategy_Scheduler_Factory<ACE_RMS_Dyn_Scheduler_Strategy>; +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + + +// EOF + diff --git a/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.h b/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.h new file mode 100644 index 00000000000..952993412ce --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.h @@ -0,0 +1,420 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// Strategy_Scheduler.h +// +// = CREATION DATE +// 22 December 1997 +// +// = AUTHOR +// Chris Gill +// +// ============================================================================ + +#if ! defined (STRATEGY_SCHEDULER_H) +#define STRATEGY_SCHEDULER_H + +#include "DynSched.h" + +// forward declaration of the abstract base class for scheduler strategies +class ACE_Scheduler_Strategy; + +///////////////////////////////// +// Strategized scheduler class // +///////////////////////////////// + +class ACE_Strategy_Scheduler : public ACE_Scheduler + // = TITLE + // ACE_Strategy_Scheduler + // + // = DESCRIPTION + // Strategized scheduler implementation. Provides an implementation + // of all strategy specific scheduling mechanisms, which relies on the + // methods of the associated strategy class. +{ +// public interface +public: + + ACE_Strategy_Scheduler (ACE_Scheduler_Strategy &strategy); + // = strategized ctor + + virtual ~ACE_Strategy_Scheduler (); + // = virtual dtor + + status_t assign_priorities (Dispatch_Entry **dispatches, u_int count); + // = assigns priorities to the sorted dispatch schedule, + // according to the strategy's priority comparison operator. + + status_t assign_subpriorities (Dispatch_Entry **dispatches, u_int count); + // = assigns dynamic and static sub-priorities to the sorted dispatch + // schedule, according to the strategy's subpriority comparisons. + + virtual Preemption_Priority minimum_critical_priority (); + // = determine the minimum critical priority number + +private: + + virtual status_t sort_dispatches (Dispatch_Entry **dispatches, u_int count); + // = sets up the schedule in the order generated by the strategy + + ACE_Scheduler_Strategy &strategy_; + // = strategy for comparison, sorting of dispatch entries + + ACE_UNIMPLEMENTED_FUNC (ACE_Strategy_Scheduler (const ACE_Strategy_Scheduler &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Strategy_Scheduler &operator= ( + const ACE_Strategy_Scheduler &)) +}; + + + +//////////////////////////////////////// +// Factory for strategized schedulers // +//////////////////////////////////////// + +template <class STRATEGY> +class ACE_Strategy_Scheduler_Factory + // = TITLE + // ACE_Strategy_Scheduler_Factory + // + // = DESCRIPTION + // Provides a type parameterized factory method that constructs + // and returns a scheduler that uses the given scheduling strategy +{ +public: + + static ACE_Strategy_Scheduler * create (ACE_Scheduler::Preemption_Priority minimum_critical_priority); + // construct and return a scheduler strategized with + // an instance of the the parameterized strategy type +}; + + +////////////////////////// +// Scheduler Strategies // +////////////////////////// + +class ACE_Scheduler_Strategy + // = TITLE + // ACE_Scheduler_Strategy + // + // = DESCRIPTION + // Abstract Base Class for scheduling strategies: each derived class + // must define an ordering strategy for dispatch entries based on a specific + // scheduling algorithm. +{ +public: + + ACE_Scheduler_Strategy (ACE_Scheduler::Preemption_Priority minimum_critical_priority = 0); + // ctor + + virtual int priority_comp (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry) = 0; + // = comparison of two dispatch entries in strategy specific high to low priority + // ordering: returns -1 if the first Dispatch_Entry is greater in the order, + // 0 if they are equivalent, or 1 if the second Dispatch_Entry is greater in + // the order + + virtual void sort (Dispatch_Entry **dispatch_entries, + u_int count) = 0; + // = sort the dispatch entry link pointer array according to + // the specific sort order defined by the strategy + + virtual ACE_Scheduler::Preemption_Priority minimum_critical_priority (); + // = determine the minimum critical priority number + + virtual int dynamic_subpriority_comp (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry) = 0; + // = comparison of two dispatch entries in strategy specific high to low + // dynamic subpriority ordering: returns -1 if the first Dispatch_Entry + // is greater in the order, 0 if they are equivalent, or 1 if the + // second Dispatch_Entry is greater in the order + + virtual int static_subpriority_comp (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry); + // = provide a lowest level ordering based first on importance (descending), + // and then on the dependency topological sort finishing time (ascending). + + +protected: + + int sort_comp (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry); + // = comparison of two dispatch entries using the specific priority, dynamic + // subpriority, and static subpriority method definitions provided by + // the derived strategy class to produce the strategy specific sort + // ordering: returns -1 if the first Dispatch_Entry is greater in the order, + // 0 if they are equivalent, or 1 if the second Dispatch_Entry is greater in + // the order. This is an example of the Template Method pattern (and also + // of Pree's Unification Metapattern), in which derived classes provide + // definitions of the methods on which the sort_comp Template Method relies. + + ACE_Scheduler::Preemption_Priority minimum_critical_priority_; + // = the minimum critical priority number for the strategy +}; + + + +class ACE_MUF_Scheduler_Strategy : public ACE_Scheduler_Strategy + // = TITLE + // ACE_MUF_Scheduler_Strategy + // + // = DESCRIPTION + // Defines "schedule" method using Maximum Urgency First + // scheduling algorithm. +{ +public: + + ACE_MUF_Scheduler_Strategy (ACE_Scheduler::Preemption_Priority minimum_critical_priority = 0); + // ctor + + virtual ~ACE_MUF_Scheduler_Strategy (); + // = virtual dtor + + + static ACE_MUF_Scheduler_Strategy *instance (); + // returns an instance of the strategy + + virtual int priority_comp (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry); + // = comparison of two dispatch entries by maximum criticality: returns -1 if the + // first Dispatch_Entry is greater in the order, 0 if they're equivalent, or + // 1 if the second Dispatch_Entry is greater in the order. + + virtual void sort (Dispatch_Entry **dispatch_entries, + u_int count); + // = sort the dispatch entry link pointer array in descending urgency order + + virtual ACE_Scheduler::Preemption_Priority minimum_critical_priority (); + // = determine the minimum critical priority number + +protected: + + virtual int dynamic_subpriority_comp ( + const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry); + // = orders of two dispatch entries by ascending laxity: returns -1 if the + // first Dispatch_Entry is greater in the order, 0 if they're equivalent, + // 1 if the second Dispatch_Entry is greater in the order. + +private: + + static int sort_function (void *arg1, void *arg2); + // comparison function to pass to qsort: calls instance ()->sort_comp (); + + static ACE_MUF_Scheduler_Strategy *instance_; + // instance of the strategy +}; + + +class ACE_RMS_Scheduler_Strategy : public ACE_Scheduler_Strategy + // = TITLE + // ACE_RMS_Scheduler_Strategy + // + // = DESCRIPTION + // Defines "schedule" method using Rate Monotonic + // Scheduling algorithm. +{ +public: + + ACE_RMS_Scheduler_Strategy (ACE_Scheduler::Preemption_Priority minimum_critical_priority = 0); + // ctor + + virtual ~ACE_RMS_Scheduler_Strategy (); + // = virtual dtor + + static ACE_RMS_Scheduler_Strategy *instance (); + // returns an instance of the strategy + + virtual int priority_comp (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry); + // = comparison of two dispatch entries by minimum period: returns -1 if the + // first Dispatch_Entry is greater in the order, 0 if they're equivalent, + // or 1 if the second Dispatch_Entry is greater in the order. + + virtual void sort (Dispatch_Entry **dispatch_entries, + u_int count); + // = sort the dispatch entry link pointer array in descending RMS (rate) order + +protected: + + virtual int dynamic_subpriority_comp + (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry); + // = all dispatches in a given priority level have the same dynamic + // subpriority under RMS: just returns 0 + +private: + + static int sort_function (void *arg1, void *arg2); + // comparison function to pass to qsort: calls instance ()->sort_comp (); + + static ACE_RMS_Scheduler_Strategy *instance_; + // instance of the strategy + +}; + + + + + +class ACE_MLF_Scheduler_Strategy : public ACE_Scheduler_Strategy + // = TITLE + // ACE_MLF_Scheduler_Strategy + // + // = DESCRIPTION + // Defines "schedule" method using Minimum Laxity First + // scheduling algorithm. +{ +public: + + ACE_MLF_Scheduler_Strategy (ACE_Scheduler::Preemption_Priority minimum_critical_priority = 0); + // = ctor + + virtual ~ACE_MLF_Scheduler_Strategy (); + // = virtual dtor + + static ACE_MLF_Scheduler_Strategy *instance (); + // returns an instance of the strategy + + virtual int priority_comp (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry); + // = just returns 0, as all dispatch entries are of equivalent priority under MLF. + + virtual void sort (Dispatch_Entry **dispatch_entries, + u_int count); + // = sort the dispatch entry link pointer array in ascending laxity order + +protected: + + virtual int dynamic_subpriority_comp + (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry); + // = orders two dispatch entries by ascending laxity: returns -1 if the + // first Dispatch_Entry is greater in the order, 0 if they're equivalent, + // or 1 if the second Dispatch_Entry is greater in the order. + +private: + + static int sort_function (void *arg1, void *arg2); + // comparison function to pass to qsort: calls instance ()->sort_comp (); + + static ACE_MLF_Scheduler_Strategy *instance_; + // instance of the strategy + +}; + + +class ACE_EDF_Scheduler_Strategy : public ACE_Scheduler_Strategy + // = TITLE + // ACE_EDF_Scheduler_Strategy + // + // = DESCRIPTION + // Defines "schedule" method using Earliest Deadline First + // scheduling algorithm. +{ +public: + + ACE_EDF_Scheduler_Strategy (ACE_Scheduler::Preemption_Priority minimum_critical_priority = 0); + // = default ctor + + virtual ~ACE_EDF_Scheduler_Strategy (); + // = virtual dtor + + static ACE_EDF_Scheduler_Strategy *instance (); + // returns an instance of the strategy + + virtual int priority_comp (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry); + // = returns 0, as all dispatch entries are of equivalent priority under EDF. + + virtual void sort (Dispatch_Entry **dispatch_entries, + u_int count); + // = sort the dispatch entry link pointer array in ascending deadline (period) order + +protected: + + virtual int dynamic_subpriority_comp + (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry); + // = orders two dispatch entries by ascending time to deadline: returns -1 if + // the first Dispatch_Entry is greater in the order, 0 if they're equivalent, + // or 1 if the second Dispatch_Entry is greater in the order. + +private: + + static int sort_function (void *arg1, void *arg2); + // comparison function to pass to qsort: calls instance ()->sort_comp (); + + static ACE_EDF_Scheduler_Strategy *instance_; + // instance of the strategy + +}; + + +class ACE_RMS_Dyn_Scheduler_Strategy : public ACE_Scheduler_Strategy + // = TITLE + // ACE_RMS_Dyn_Scheduler_Strategy + // + // = DESCRIPTION + // Defines "schedule" method using Rate Monotonic priority assignment for + // the critical set, single priority for the dynamic (non-critical) set. +{ +public: + + ACE_RMS_Dyn_Scheduler_Strategy (ACE_Scheduler::Preemption_Priority minimum_critical_priority = 0); + // = ctor + + virtual ~ACE_RMS_Dyn_Scheduler_Strategy (); + // = virtual dtor + + static ACE_RMS_Dyn_Scheduler_Strategy *instance (); + // returns an instance of the strategy + + virtual int priority_comp (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry); + // = comparison of two dispatch entries by maximum criticality: returns -1 + // if the first Dispatch_Entry is greater in the order, 0 if they're + // equivalent, or 1 if the second Dispatch_Entry is greater in the order. + + virtual void sort (Dispatch_Entry **dispatch_entries, + u_int count); + // = sort the dispatch entry pointer array in descending priority order + +protected: + + virtual int dynamic_subpriority_comp + (const Dispatch_Entry &first_entry, + const Dispatch_Entry &second_entry); + // = comparison of two dispatch entries within the very high and high + // criticality sets by minimum period (RMS) or of two dispatch entries + // within the medium, low, and very low criticality sets by minimum + // laxity: returns -1 if the first Dispatch_Entry is greater in the order, + // 0 if they're equivalent, or 1 if the second Dispatch_Entry is greater + // in the order. + + virtual ACE_Scheduler::Preemption_Priority minimum_critical_priority (); + // = determine the minimum critical priority number + +private: + + static int sort_function (void *arg1, void *arg2); + // comparison function to pass to qsort: calls instance ()->sort_comp (); + + static ACE_RMS_Dyn_Scheduler_Strategy *instance_; + // instance of the strategy + +}; + + +#if defined (__ACE_INLINE__) +#include "Strategy_Scheduler.i" +#endif /* __ACE_INLINE__ */ + +#endif /* STRATEGY_SCHEDULER_H */ + +// EOF diff --git a/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.i b/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.i new file mode 100644 index 00000000000..c84e9e2da77 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Sched/Strategy_Scheduler.i @@ -0,0 +1,21 @@ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// sched +// +// = FILENAME +// Strategy_Scheduler.i +// +// = CREATION DATE +// 22 December 1997 +// +// = AUTHOR +// Chris Gill +// +// ============================================================================ + + +// EOF + |