diff options
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/ESF')
40 files changed, 2608 insertions, 0 deletions
diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Busy_Lock.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Busy_Lock.cpp new file mode 100644 index 00000000000..a4e11e8837a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Busy_Lock.cpp @@ -0,0 +1,62 @@ +// $Id$ + +#ifndef TAO_ESF_BUSY_LOCK_CPP +#define TAO_ESF_BUSY_LOCK_CPP + +#include "ESF_Busy_Lock.h" + +#if ! defined (__ACE_INLINE__) +#include "ESF_Busy_Lock.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ESF, ESF_Busy_Lock, "$Id$") + +template<class T> +int TAO_ESF_Busy_Lock_Adapter<T>::remove (void) +{ + return 0; +} + +template<class T> +int TAO_ESF_Busy_Lock_Adapter<T>::acquire (void) +{ + return this->adaptee_->busy (); +} + +template<class T> +int TAO_ESF_Busy_Lock_Adapter<T>::tryacquire (void) +{ + return this->adaptee_->busy (); +} + +template<class T> +int TAO_ESF_Busy_Lock_Adapter<T>::release (void) +{ + return this->adaptee_->idle (); +} + +template<class T> +int TAO_ESF_Busy_Lock_Adapter<T>::acquire_read (void) +{ + return this->adaptee_->busy (); +} + +template<class T> +int TAO_ESF_Busy_Lock_Adapter<T>::acquire_write (void) +{ + return this->adaptee_->busy (); +} + +template<class T> +int TAO_ESF_Busy_Lock_Adapter<T>::tryacquire_read (void) +{ + return this->adaptee_->busy (); +} + +template<class T> +int TAO_ESF_Busy_Lock_Adapter<T>::tryacquire_write (void) +{ + return this->adaptee_->busy (); +} + +#endif /* TAO_ESF_BUSY_LOCK_CPP */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Busy_Lock.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_Busy_Lock.h new file mode 100644 index 00000000000..dc102a2cd69 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Busy_Lock.h @@ -0,0 +1,61 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Event Service Framework +// +// = FILENAME +// ESF_Busy_Lock +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef TAO_ESF_BUSY_LOCK_H +#define TAO_ESF_BUSY_LOCK_H + +#include "ace/OS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +template<class Adaptee> +class TAO_ESF_Busy_Lock_Adapter +{ +public: + TAO_ESF_Busy_Lock_Adapter (Adaptee* adaptee); + // Constructor + + // = The ACE_Lock methods, please check $ACE_ROOT/ace/Synch.h for + // details. + + int remove (void); + int acquire (void); + int tryacquire (void); + int release (void); + int acquire_read (void); + int acquire_write (void); + int tryacquire_read (void); + int tryacquire_write (void); + +private: + Adaptee* adaptee_; +}; + +#if defined (__ACE_INLINE__) +#include "ESF_Busy_Lock.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ESF_Busy_Lock.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("ESF_Busy_Lock.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* TAO_ESF_BUSY_LOCK_H */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Busy_Lock.i b/TAO/orbsvcs/orbsvcs/ESF/ESF_Busy_Lock.i new file mode 100644 index 00000000000..6723e66b926 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Busy_Lock.i @@ -0,0 +1,8 @@ +// $Id$ + +template<class T> ACE_INLINE +TAO_ESF_Busy_Lock_Adapter<T>::TAO_ESF_Busy_Lock_Adapter (T* adaptee) + : adaptee_ (adaptee) +{ +} + diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Read.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Read.cpp new file mode 100644 index 00000000000..703542b5a9d --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Read.cpp @@ -0,0 +1,82 @@ +// $Id$ + +#ifndef TAO_ESF_COPY_ON_READ_CPP +#define TAO_ESF_COPY_ON_READ_CPP + +#include "ESF_Copy_On_Read.h" + +#if ! defined (__ACE_INLINE__) +#include "ESF_Proxy_Collection.i" +#endif /* __ACE_INLINE__ */ + +#include "ESF_Worker.h" + +ACE_RCSID(ESF, ESF_Copy_On_Read, "$Id$") + +template<class PROXY, class COLLECTION, class ITERATOR, class ACE_LOCK> +TAO_ESF_Copy_On_Read<PROXY,COLLECTION,ITERATOR,ACE_LOCK>:: + TAO_ESF_Copy_On_Read (void) +{ +} + +template<class PROXY, class COLLECTION, class ITERATOR, class ACE_LOCK> +TAO_ESF_Copy_On_Read<PROXY,COLLECTION,ITERATOR,ACE_LOCK>:: + TAO_ESF_Copy_On_Read (const COLLECTION &collection) + : collection_ (collection) +{ +} + +template<class PROXY, class COLLECTION, class ITERATOR, class ACE_LOCK> void +TAO_ESF_Copy_On_Read<PROXY,COLLECTION,ITERATOR,ACE_LOCK>:: + for_each (TAO_ESF_Worker<PROXY> *worker, + CORBA::Environment &ACE_TRY_ENV) +{ + // @@ Use an allocator for this memory... + PROXY **proxies = 0; + size_t size = 0; + ACE_TRY + { + { + ACE_GUARD (ACE_LOCK, ace_mon, this->lock_); + + size = this->collection_.size (); + ACE_NEW (proxies, PROXY*[size]); + PROXY **j = proxies; + + for (; j != proxies + size; ++j) + *j = 0; + + j = proxies; + ITERATOR end = this->collection_.end (); + for (ITERATOR i = this->collection_.begin (); i != end; ++i) + { + *j = *i; + (*j)->_incr_refcnt (); + ++j; + } + } + + for (PROXY **j = proxies; j != proxies + size; ++j) + { + worker->work (*j, ACE_TRY_ENV); + ACE_TRY_CHECK; + (*j)->_decr_refcnt (); + } + delete[] proxies; + } + ACE_CATCHANY + { + for (PROXY **j = proxies; j != proxies + size; ++j) + { + if (*j != 0) + (*j)->_decr_refcnt (); + } + delete[] proxies; + + ACE_RETHROW; + } + ACE_ENDTRY; +} + +#endif /* TAO_ESF_COPY_ON_READ_CPP */ + diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Read.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Read.h new file mode 100644 index 00000000000..5bf008a8c5a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Read.h @@ -0,0 +1,82 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Event Service Framework +// +// = FILENAME +// ESF_Proxy_Collection +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// = CREDITS +// http://www.cs.wustl.edu/~coryan/EC/index.html +// +// ============================================================================ + +#ifndef TAO_ESF_COPY_ON_READ_H +#define TAO_ESF_COPY_ON_READ_H + +#include "ESF_Proxy_Collection.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +template<class Target> class TAO_ESF_Worker; + +// **************************************************************** + +template<class PROXY, class COLLECTION, class ITERATOR, class ACE_LOCK> +class TAO_ESF_Copy_On_Read : public TAO_ESF_Proxy_Collection<PROXY> +{ + // = TITLE + // TAO_ESF_Copy_On_Read + // + // = DESCRIPTION + // Implement the Copy_On_Read protocol + // The class is parametric on the kind of collection and locking + // mechanism used. + // + // = TODO + // +public: + TAO_ESF_Copy_On_Read (void); + TAO_ESF_Copy_On_Read (const COLLECTION &collection); + // Constructors + + // = The TAO_ESF_Proxy methods + virtual void for_each (TAO_ESF_Worker<PROXY> *worker, + CORBA::Environment &ACE_TRY_ENV); + virtual void connected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV); + virtual void reconnected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV); + virtual void disconnected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV); + virtual void shutdown (CORBA::Environment &ACE_TRY_ENV); + +private: + COLLECTION collection_; + + ACE_LOCK lock_; +}; + +// **************************************************************** + +#if defined (__ACE_INLINE__) +#include "ESF_Copy_On_Read.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ESF_Copy_On_Read.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("ESF_Copy_On_Read.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* TAO_ESF_COPY_ON_READ_H */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Read.i b/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Read.i new file mode 100644 index 00000000000..ba1cbb48e25 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Read.i @@ -0,0 +1,42 @@ +// $Id$ + +template<class PROXY, class C, class I, class L> void +TAO_ESF_Copy_On_Read<PROXY,C,I,L>:: + connected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD (L, ace_mon, this->lock_); + + proxy->_incr_refcnt (); + this->collection_.connected (proxy, ACE_TRY_ENV); +} + +template<class PROXY, class C, class I, class L> void +TAO_ESF_Copy_On_Read<PROXY,C,I,L>:: + reconnected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD (L, ace_mon, this->lock_); + + proxy->_incr_refcnt (); + this->collection_.reconnected (proxy, ACE_TRY_ENV); +} + +template<class PROXY, class C, class I, class L> void +TAO_ESF_Copy_On_Read<PROXY,C,I,L>:: + disconnected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD (L, ace_mon, this->lock_); + + this->collection_.disconnected (proxy, ACE_TRY_ENV); +} + +template<class PROXY, class C, class I, class L> void +TAO_ESF_Copy_On_Read<PROXY,C,I,L>:: + shutdown (CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD (L, ace_mon, this->lock_); + + this->collection_.shutdown (ACE_TRY_ENV); +} diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Defaults.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_Defaults.h new file mode 100644 index 00000000000..77846dcee44 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Defaults.h @@ -0,0 +1,42 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Event Service Framework +// +// = FILENAME +// ESF_Defaults +// +// = DESCRIPTION +// In this file we set the compile time defaults for the framework. +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef TAO_ESF_DEFAULTS_H +#define TAO_ESF_DEFAULTS_H + +#ifndef TAO_ESF_ENABLE_DEBUG_MESSAGES +#define TAO_ESF_ENABLE_DEBUG_MESSAGES 0 +#endif /* TAO_ESF_ENABLE_DEBUG_MESSAGES */ + +// Control the maximum degree of concurrency tolerated by the EC, some +// kind of limit is required to avoid starvation of delayed write +// operations. +#ifndef TAO_ESF_DEFAULT_BUSY_HWM +# define TAO_ESF_DEFAULT_BUSY_HWM 1024 +#endif /* TAO_ESF_DEFAULT_BUSY_HWM */ + +#ifndef TAO_ESF_DEFAULT_MAX_WRITE_DELAY +# define TAO_ESF_DEFAULT_MAX_WRITE_DELAY 2048 +#endif /* TAO_ESF_DEFAULT_MAX_WRITE_DELAY */ + +#ifndef TAO_ESF_DEFAULT_ORB_ID +# define TAO_ESF_DEFAULT_ORB_ID "" /* */ +#endif /* TAO_ESF_DEFAULT_ORB_ID */ + +#endif /* TAO_ESF_DEFAULTS_H */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.cpp new file mode 100644 index 00000000000..9dd18a0b5a1 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.cpp @@ -0,0 +1,206 @@ +// $Id$ + +#ifndef TAO_ESF_DELAYED_CHANGES_CPP +#define TAO_ESF_DELAYED_CHANGES_CPP + +#include "ESF_Delayed_Changes.h" + +#if ! defined (__ACE_INLINE__) +#include "ESF_Proxy_Collection.i" +#endif /* __ACE_INLINE__ */ + +#include "ESF_Defaults.h" +#include "ESF_Worker.h" +#include "ESF_Delayed_Command.h" + +ACE_RCSID(ESF, ESF_Immediate_Changes, "$Id$") + +// **************************************************************** + +template<class PROXY, class COLLECTION, class ITERATOR, ACE_SYNCH_DECL> +TAO_ESF_Delayed_Changes<PROXY,COLLECTION,ITERATOR,ACE_SYNCH_USE>:: + TAO_ESF_Delayed_Changes (void) + : lock_ (this), + busy_cond_ (busy_lock_), + busy_count_ (0), + write_delay_count_ (0), + busy_hwm_ (TAO_ESF_DEFAULT_BUSY_HWM), + max_write_delay_ (TAO_ESF_DEFAULT_MAX_WRITE_DELAY) +{ +} + +template<class PROXY, class COLLECTION, class ITERATOR, ACE_SYNCH_DECL> +TAO_ESF_Delayed_Changes<PROXY,COLLECTION,ITERATOR,ACE_SYNCH_USE>:: + TAO_ESF_Delayed_Changes (const COLLECTION &collection) + : collection_ (collection), + lock_ (this), + busy_cond_ (busy_lock_), + busy_count_ (0), + write_delay_count_ (0), + busy_hwm_ (TAO_ESF_DEFAULT_BUSY_HWM), + max_write_delay_ (TAO_ESF_DEFAULT_MAX_WRITE_DELAY) +{ +} + +template<class PROXY, class COLLECTION, class ITERATOR, ACE_SYNCH_DECL> void +TAO_ESF_Delayed_Changes<PROXY,COLLECTION,ITERATOR,ACE_SYNCH_USE>:: + for_each (TAO_ESF_Worker<PROXY> *worker, + CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD (Busy_Lock, ace_mon, this->lock_); + + ITERATOR end = this->collection_.end (); + for (ITERATOR i = this->collection_.begin (); i != end; ++i) + { + worker->work (*i, ACE_TRY_ENV); + ACE_CHECK; + } +} + +template<class PROXY, class COLLECTION, class ITERATOR, ACE_SYNCH_DECL> int +TAO_ESF_Delayed_Changes<PROXY,COLLECTION,ITERATOR,ACE_SYNCH_USE>:: + busy (void) +{ + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, ace_mon, this->busy_lock_, -1); + + while (this->busy_count_ >= this->busy_hwm_ + || this->write_delay_count_ >= this->max_write_delay_) + this->busy_cond_.wait (); + this->busy_count_++; + + return 0; +} + +template<class PROXY, class COLLECTION, class ITERATOR, ACE_SYNCH_DECL> int +TAO_ESF_Delayed_Changes<PROXY,COLLECTION,ITERATOR,ACE_SYNCH_USE>:: + idle (void) +{ + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, ace_mon, this->busy_lock_, -1); + + this->busy_count_--; + if (this->busy_count_ == 0) + { + this->write_delay_count_ = 0; + this->execute_delayed_operations (); + this->busy_cond_.broadcast (); + } + return 0; +} + +template<class PROXY, class COLLECTION, class ITERATOR, ACE_SYNCH_DECL> int +TAO_ESF_Delayed_Changes<PROXY,COLLECTION,ITERATOR,ACE_SYNCH_USE>:: + execute_delayed_operations (void) +{ + while (!this->command_queue_.is_empty ()) + { + ACE_Command_Base* command; + this->command_queue_.dequeue_head (command); + + command->execute (); + + delete command; + } + return 0; +} + +template<class PROXY, class C, class I,ACE_SYNCH_DECL> void +TAO_ESF_Delayed_Changes<PROXY,C,I,ACE_SYNCH_USE>:: + connected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD_THROW_EX (ACE_SYNCH_MUTEX_T, ace_mon, this->busy_lock_, + CORBA::INTERNAL ()); + ACE_CHECK; + + proxy->_incr_refcnt (); + if (this->busy_count_ == 0) + { + // We can add the object immediately + this->connected_i (proxy, ACE_TRY_ENV); + } + else + { + ACE_Command_Base* command; + ACE_NEW (command, + Connected_Command (this, + proxy)); + this->command_queue_.enqueue_tail (command); + this->write_delay_count_++; + } +} + +template<class PROXY, class C, class I,ACE_SYNCH_DECL> void +TAO_ESF_Delayed_Changes<PROXY,C,I,ACE_SYNCH_USE>:: + reconnected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD_THROW_EX (ACE_SYNCH_MUTEX_T, ace_mon, this->busy_lock_, + CORBA::INTERNAL ()); + ACE_CHECK; + + proxy->_incr_refcnt (); + if (this->busy_count_ == 0) + { + // We can reconnect the object immediately + this->reconnected_i (proxy, ACE_TRY_ENV); + } + else + { + ACE_Command_Base* command; + ACE_NEW (command, + Reconnected_Command (this, + proxy)); + this->command_queue_.enqueue_tail (command); + this->write_delay_count_++; + } +} + +template<class PROXY, class C, class I,ACE_SYNCH_DECL> void +TAO_ESF_Delayed_Changes<PROXY,C,I,ACE_SYNCH_USE>:: + disconnected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD_THROW_EX (ACE_SYNCH_MUTEX_T, ace_mon, this->busy_lock_, + CORBA::INTERNAL ()); + ACE_CHECK; + + if (this->busy_count_ == 0) + { + // We can remove the object immediately + this->disconnected_i (proxy, ACE_TRY_ENV); + } + else + { + ACE_Command_Base* command; + ACE_NEW (command, + Disconnected_Command (this, + proxy)); + this->command_queue_.enqueue_tail (command); + this->write_delay_count_++; + } +} + +template<class PROXY, class C, class I,ACE_SYNCH_DECL> void +TAO_ESF_Delayed_Changes<PROXY,C,I,ACE_SYNCH_USE>:: + shutdown (CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD_THROW_EX (ACE_SYNCH_MUTEX_T, ace_mon, this->busy_lock_, + CORBA::INTERNAL ()); + ACE_CHECK; + + if (this->busy_count_ == 0) + { + // We can shutdown the object immediately + this->shutdown_i (ACE_TRY_ENV); + } + else + { + ACE_Command_Base* command; + ACE_NEW (command, + Shutdown_Command (this)); + this->command_queue_.enqueue_tail (command); + this->write_delay_count_++; + } +} + +#endif /* TAO_ESF_DELAYED_CHANGES_CPP */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.h new file mode 100644 index 00000000000..6b9bf11ff0a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.h @@ -0,0 +1,161 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Event Service Framework +// +// = FILENAME +// ESF_Proxy_Collection +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// = CREDITS +// http://www.cs.wustl.edu/~coryan/EC/index.html +// +// ============================================================================ + +#ifndef TAO_ESF_DELAYED_CHANGES_H +#define TAO_ESF_DELAYED_CHANGES_H + +#include "ESF_Proxy_Collection.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ESF_Busy_Lock.h" +#include "ace/Containers.h" + +template<class Target,class Object> class TAO_ESF_Connected_Command; +template<class Target,class Object> class TAO_ESF_Disconnected_Command; +template<class Target,class Object> class TAO_ESF_Reconnected_Command; +template<class Target> class TAO_ESF_Shutdown_Command; + +template<class PROXY, class COLLECTION, class ITERATOR, ACE_SYNCH_DECL> +class TAO_ESF_Delayed_Changes : public TAO_ESF_Proxy_Collection<PROXY> +{ + // = TITLE + // TAO_ESF_Delayed_Operations + // + // = DESCRIPTION + // This class implements the Delayed Operations protocol to solve + // the concurrency challenges outlined in the documentation of + // TAO_ESF_Proxy_Collection. + // In short the class delays changes by putting them on an + // "operation queue", the operations are stored as command objects + // in this queue and executed once the system is quiescent + // (i.e. no threads are iterating over the collection). + // + // The algorithm implemented so far is: + // - If a thread is using the set then it increases the busy + // count, this is done by calling the busy() method. Once the + // thread has stopped using the collection the idle() method is + // invoked and the busy count is decreased. + // A helper class (Busy_Lock) is used to hide this protocol + // behind the familiar GUARD idiom. + // - If the busy count reaches the busy_hwm then the thread must + // wait until the count reaches 0 again. + // This can be used to control the maximum concurrency in the + // EC, matching it (for example) with the number of + // processors. Setting the concurrency to a high value (say one + // million) allows for an arbitrary number of threads to execute + // concurrently. + // - If a modification is posted to the collection we need to + // execute it at some point. + // Just using the busy_hwm would not work, the HWM may not be + // reached ever, so another form of control is needed. + // Instead we use another counter, that keeps track of how many + // threads have used the set since the modification was + // posted. If this number of threads reaches max_write_delay then + // we don't allow any more threads to go in, eventually the + // thread count reaches 0 and we can proceed with the operations. + // + // - There is one aspect of concurrency that can be problematic: if + // thread pushes events as part of an upcall then the same thread + // could be counted twice, we need to keep track of the threads + // that are dispatching events and not increase (or decrease) the + // reference count when a thread iterates twice over the same + // set. + // + // This solves the major problems, but there are other issues to + // be addressed: + // + How do we ensure that the operations are eventually executed? + // + How do we simplify the execution of the locking protocol for + // clients of this class? + // + How do we minimize overhead for single threaded execution? + // + How do we minimize the overhead for the cases where the + // threads dispatching events don't post changes to the + // collection? + // +public: + TAO_ESF_Delayed_Changes (void); + TAO_ESF_Delayed_Changes (const COLLECTION &collection); + + int busy (void); + int idle (void); + int execute_delayed_operations (void); + + void connected_i (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV); + void reconnected_i (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV); + void disconnected_i (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV); + void shutdown_i (CORBA::Environment &ACE_TRY_ENV); + + typedef TAO_ESF_Connected_Command<TAO_ESF_Delayed_Changes<PROXY,COLLECTION,ITERATOR,ACE_SYNCH_USE>,PROXY> Connected_Command; + typedef TAO_ESF_Reconnected_Command<TAO_ESF_Delayed_Changes<PROXY,COLLECTION,ITERATOR,ACE_SYNCH_USE>,PROXY> Reconnected_Command; + typedef TAO_ESF_Disconnected_Command<TAO_ESF_Delayed_Changes<PROXY,COLLECTION,ITERATOR,ACE_SYNCH_USE>,PROXY> Disconnected_Command; + typedef TAO_ESF_Shutdown_Command<TAO_ESF_Delayed_Changes<PROXY,COLLECTION,ITERATOR,ACE_SYNCH_USE> > Shutdown_Command; + + // = The TAO_ESF_Proxy methods + virtual void for_each (TAO_ESF_Worker<PROXY> *worker, + CORBA::Environment &ACE_TRY_ENV); + virtual void connected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV); + virtual void reconnected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV); + virtual void disconnected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV); + virtual void shutdown (CORBA::Environment &ACE_TRY_ENV); + +private: + COLLECTION collection_; + + typedef TAO_ESF_Busy_Lock_Adapter<TAO_ESF_Delayed_Changes<PROXY,COLLECTION,ITERATOR,ACE_SYNCH_USE> > Busy_Lock; + + Busy_Lock lock_; + + ACE_SYNCH_MUTEX_T busy_lock_; + + ACE_SYNCH_CONDITION_T busy_cond_; + + CORBA::ULong busy_count_; + + CORBA::ULong write_delay_count_; + + CORBA::ULong busy_hwm_; + CORBA::ULong max_write_delay_; + // Control variables for the concurrency policies. + + ACE_Unbounded_Queue<ACE_Command_Base*> command_queue_; +}; + +// **************************************************************** + +#if defined (__ACE_INLINE__) +#include "ESF_Delayed_Changes.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ESF_Delayed_Changes.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("ESF_Delayed_Changes.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* TAO_ESF_DELAYED_CHANGES_H */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.i b/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.i new file mode 100644 index 00000000000..b6511ed1a28 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.i @@ -0,0 +1,32 @@ +// $Id$ + +template<class PROXY, class C, class I,ACE_SYNCH_DECL> void +TAO_ESF_Delayed_Changes<PROXY,C,I,ACE_SYNCH_USE>:: + connected_i (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) +{ + this->collection_.connected (proxy, ACE_TRY_ENV); +} + +template<class PROXY, class C, class I,ACE_SYNCH_DECL> void +TAO_ESF_Delayed_Changes<PROXY,C,I,ACE_SYNCH_USE>:: + reconnected_i (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) +{ + this->collection_.reconnected (proxy, ACE_TRY_ENV); +} + +template<class PROXY, class C, class I,ACE_SYNCH_DECL> void +TAO_ESF_Delayed_Changes<PROXY,C,I,ACE_SYNCH_USE>:: + disconnected_i (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) +{ + this->collection_.disconnected (proxy, ACE_TRY_ENV); +} + +template<class PROXY, class C, class I,ACE_SYNCH_DECL> void +TAO_ESF_Delayed_Changes<PROXY,C,I,ACE_SYNCH_USE>:: + shutdown_i (CORBA::Environment &ACE_TRY_ENV) +{ + this->collection_.shutdown (ACE_TRY_ENV); +} diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Command.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Command.cpp new file mode 100644 index 00000000000..8f2a176d4ab --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Command.cpp @@ -0,0 +1,66 @@ +// $Id$ + +#ifndef TAO_ESF_DELAYED_COMMAND_CPP +#define TAO_ESF_DELAYED_COMMAND_CPP + +#include "ESF_Delayed_Command.h" + +#if ! defined (__ACE_INLINE__) +#include "ESF_Delayed_Command.i" +#endif /* __ACE_INLINE__ */ + +#include "tao/corba.h" + +ACE_RCSID(ESF, ESF_Delayed_Command, "$Id$") + +template<class Target, class Object> int +TAO_ESF_Connected_Command<Target,Object>::execute (void* arg) +{ + CORBA::Environment *env = &TAO_default_environment (); + if (arg != 0) + env = ACE_static_cast(CORBA::Environment*, arg); + + this->target_->connected_i (this->object_, *env); + return 0; +} + +// **************************************************************** + +template<class Target, class Object> int +TAO_ESF_Reconnected_Command<Target,Object>::execute (void* arg) +{ + CORBA::Environment *env = &TAO_default_environment (); + if (arg != 0) + env = ACE_static_cast(CORBA::Environment*, arg); + + this->target_->reconnected_i (this->object_, *env); + return 0; +} + +// **************************************************************** + +template<class Target, class Object> int +TAO_ESF_Disconnected_Command<Target,Object>::execute (void* arg) +{ + CORBA::Environment *env = &TAO_default_environment (); + if (arg != 0) + env = ACE_static_cast(CORBA::Environment*, arg); + + this->target_->disconnected_i (this->object_, *env); + return 0; +} + +// **************************************************************** + +template<class Target> int +TAO_ESF_Shutdown_Command<Target>::execute (void* arg) +{ + CORBA::Environment *env = &TAO_default_environment (); + if (arg != 0) + env = ACE_static_cast(CORBA::Environment*, arg); + + this->target_->shutdown_i (*env); + return 0; +} + +#endif /* TAO_ESF_DELAYED_COMMAND_CPP */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Command.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Command.h new file mode 100644 index 00000000000..b66259c2c4e --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Command.h @@ -0,0 +1,198 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Event Service Framework +// +// = FILENAME +// ESF_Delayed_Command +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef TAO_ESF_DELAYED_COMMAND_H +#define TAO_ESF_DELAYED_COMMAND_H + +#include "ace/Functor.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +template<class Target, class Object> +class TAO_ESF_Connected_Command : public ACE_Command_Base +{ + // = TITLE + // ESF_Connected_Command + // + // = DESCRIPTION + // Implements a Command object that invokes the connected_i() method + // on the target, passing an argument of type Object. + // + // = MEMORY MANAGMENT + // It does not assume ownership of Object nor the Target + // arguments. + // Usually allocated from the heap or an allocator; but it is not + // self-managed. + // + // = LOCKING + // No provisions for locking, access must be serialized + // externally. + // + // = TODO + // +public: + TAO_ESF_Connected_Command (Target *target, + Object *object); + // constructor... + + virtual int execute (void *arg); + // The callback method, if the argument is not nil it is interpreted + // as a CORBA::Environment. + +private: + Target *target_; + // The target + + Object *object_; + // The argument +}; + +// **************************************************************** + +template<class Target, class Object> +class TAO_ESF_Reconnected_Command : public ACE_Command_Base +{ + // = TITLE + // ESF_Reconnected_Command + // + // = DESCRIPTION + // Implements a Command object that invokes the reconnected_i() method + // on the target, passing an argument of type Object. + // + // = MEMORY MANAGMENT + // It does not assume ownership of Object nor the Target + // arguments. + // Usually allocated from the heap or an allocator; but it is not + // self-managed. + // + // = LOCKING + // No provisions for locking, access must be serialized + // externally. + // + // = TODO + // +public: + TAO_ESF_Reconnected_Command (Target *target, + Object *object); + // constructor... + + virtual int execute (void *arg); + // The callback method, if the argument is not nil it is interpreted + // as a CORBA::Environment. + +private: + Target *target_; + // The target + + Object *object_; + // The argument +}; + +// **************************************************************** + +template<class Target, class Object> +class TAO_ESF_Disconnected_Command : public ACE_Command_Base +{ + // = TITLE + // ESF_Disconnected_Command + // + // = DESCRIPTION + // Implements a Command object that invokes the disconnected_i() + // method on the target, passing an argument of type Object. + // + // = MEMORY MANAGMENT + // It does not assume ownership of Object nor the Target + // arguments. + // Usually allocated from the heap or an allocator; but it is not + // self-managed. + // + // = LOCKING + // No provisions for locking, access must be serialized + // externally. + // + // = TODO + // +public: + TAO_ESF_Disconnected_Command (Target *target, + Object *object); + // constructor... + + virtual int execute (void *arg); + // The callback method, if the argument is not nil it is interpreted + // as a CORBA::Environment. + +private: + Target *target_; + // The target + + Object *object_; + // The argument +}; + +// **************************************************************** + +template<class Target> +class TAO_ESF_Shutdown_Command : public ACE_Command_Base +{ + // = TITLE + // ESF_Shutdown_Command + // + // = DESCRIPTION + // Implements a Command object that invokes the shutdown_i() + // method on the target, passing an argument of type Object. + // + // = MEMORY MANAGMENT + // It does not assume ownership of Object nor the Target + // arguments. + // Usually allocated from the heap or an allocator; but it is not + // self-managed. + // + // = LOCKING + // No provisions for locking, access must be serialized + // externally. + // + // = TODO + // +public: + TAO_ESF_Shutdown_Command (Target *target); + // constructor... + + virtual int execute (void *arg); + // The callback method, if the argument is not nil it is interpreted + // as a CORBA::Environment. + +private: + Target *target_; + // The target +}; + +// **************************************************************** + +#if defined (__ACE_INLINE__) +#include "ESF_Delayed_Command.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ESF_Delayed_Command.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("ESF_Delayed_Command.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* TAO_ESF_DELAYED_COMMAND_H */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Command.i b/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Command.i new file mode 100644 index 00000000000..5465f38c4bd --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Command.i @@ -0,0 +1,41 @@ +// $Id$ + +template<class Target, class Object> +TAO_ESF_Connected_Command<Target,Object>:: + TAO_ESF_Connected_Command (Target *target, + Object *object) + : target_ (target), + object_ (object) +{ +} + +// **************************************************************** + +template<class Target, class Object> +TAO_ESF_Reconnected_Command<Target,Object>:: + TAO_ESF_Reconnected_Command (Target *target, + Object *object) + : target_ (target), + object_ (object) +{ +} + +// **************************************************************** + +template<class Target, class Object> +TAO_ESF_Disconnected_Command<Target,Object>:: + TAO_ESF_Disconnected_Command (Target *target, + Object *object) + : target_ (target), + object_ (object) +{ +} + +// **************************************************************** + +template<class Target> +TAO_ESF_Shutdown_Command<Target>:: + TAO_ESF_Shutdown_Command (Target *target) + : target_ (target) +{ +} diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Immediate_Changes.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Immediate_Changes.cpp new file mode 100644 index 00000000000..a41c7eabdb0 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Immediate_Changes.cpp @@ -0,0 +1,46 @@ +// $Id$ + +#ifndef TAO_ESF_IMMEDIATE_CHANGES_CPP +#define TAO_ESF_IMMEDIATE_CHANGES_CPP + +#include "ESF_Immediate_Changes.h" + +#if ! defined (__ACE_INLINE__) +#include "ESF_Proxy_Collection.i" +#endif /* __ACE_INLINE__ */ + +#include "ESF_Worker.h" + +ACE_RCSID(ESF, ESF_Immediate_Changes, "$Id$") + +// **************************************************************** + +template<class PROXY, class COLLECTION, class ITERATOR, class ACE_LOCK> +TAO_ESF_Immediate_Changes<PROXY,COLLECTION,ITERATOR,ACE_LOCK>:: + TAO_ESF_Immediate_Changes (void) +{ +} + +template<class PROXY, class COLLECTION, class ITERATOR, class ACE_LOCK> +TAO_ESF_Immediate_Changes<PROXY,COLLECTION,ITERATOR,ACE_LOCK>:: + TAO_ESF_Immediate_Changes (const COLLECTION &collection) + : collection_ (collection) +{ +} + +template<class PROXY, class COLLECTION, class ITERATOR, class ACE_LOCK> void +TAO_ESF_Immediate_Changes<PROXY,COLLECTION,ITERATOR,ACE_LOCK>:: + for_each (TAO_ESF_Worker<PROXY> *worker, + CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD (ACE_LOCK, ace_mon, this->lock_); + + ITERATOR end = this->collection_.end (); + for (ITERATOR i = this->collection_.begin (); i != end; ++i) + { + worker->work ((*i), ACE_TRY_ENV); + ACE_CHECK; + } +} + +#endif /* TAO_ESF_IMMEDIATE_CHANGES_CPP */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Immediate_Changes.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_Immediate_Changes.h new file mode 100644 index 00000000000..89d35b9f71d --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Immediate_Changes.h @@ -0,0 +1,72 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Event Service Framework +// +// = FILENAME +// ESF_Proxy_Collection +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// = CREDITS +// http://www.cs.wustl.edu/~coryan/EC/index.html +// +// ============================================================================ + +#ifndef TAO_ESF_IMMEDIATE_CHANGES_H +#define TAO_ESF_IMMEDIATE_CHANGES_H + +#include "ESF_Proxy_Collection.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +template<class PROXY, class COLLECTION, class ITERATOR, class ACE_LOCK> +class TAO_ESF_Immediate_Changes : public TAO_ESF_Proxy_Collection<PROXY> +{ + // = TITLE + // TAO_ESF_Immediate_Changes + // + // = DESCRIPTION + // Implement the Immediate_ +public: + TAO_ESF_Immediate_Changes (void); + TAO_ESF_Immediate_Changes (const COLLECTION &collection); + + // = The TAO_ESF_Proxy methods + virtual void for_each (TAO_ESF_Worker<PROXY> *worker, + CORBA::Environment &ACE_TRY_ENV); + virtual void connected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV); + virtual void reconnected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV); + virtual void disconnected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV); + virtual void shutdown (CORBA::Environment &ACE_TRY_ENV); + +private: + COLLECTION collection_; + + ACE_LOCK lock_; +}; + +// **************************************************************** + +#if defined (__ACE_INLINE__) +#include "ESF_Immediate_Changes.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ESF_Immediate_Changes.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("ESF_Immediate_Changes.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* TAO_ESF_IMMEDIATE_CHANGES_H */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Immediate_Changes.i b/TAO/orbsvcs/orbsvcs/ESF/ESF_Immediate_Changes.i new file mode 100644 index 00000000000..7ffce621b6b --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Immediate_Changes.i @@ -0,0 +1,43 @@ +// $Id$ + +template<class PROXY, class C, class I, class L> void +TAO_ESF_Immediate_Changes<PROXY,C,I,L>:: + connected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD (L, ace_mon, this->lock_); + + proxy->_incr_refcnt (); + this->collection_.connected (proxy, ACE_TRY_ENV); +} + +template<class PROXY, class C, class I, class L> void +TAO_ESF_Immediate_Changes<PROXY,C,I,L>:: + reconnected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD (L, ace_mon, this->lock_); + + proxy->_incr_refcnt (); + this->collection_.reconnected (proxy, ACE_TRY_ENV); +} + +template<class PROXY, class C, class I, class L> void +TAO_ESF_Immediate_Changes<PROXY,C,I,L>:: + disconnected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD (L, ace_mon, this->lock_); + + this->collection_.disconnected (proxy, ACE_TRY_ENV); +} + +template<class PROXY, class C, class I, class L> void +TAO_ESF_Immediate_Changes<PROXY,C,I,L>:: + shutdown (CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD (L, ace_mon, this->lock_); + + this->collection_.shutdown (ACE_TRY_ENV); +} + diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Admin.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Admin.cpp new file mode 100644 index 00000000000..b8df55d9d0b --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Admin.cpp @@ -0,0 +1,46 @@ +// $Id$ + +#ifndef TAO_ESF_PEER_ADMIN_CPP +#define TAO_ESF_PEER_ADMIN_CPP + +#include "ESF_Peer_Admin.h" + +#if ! defined (__ACE_INLINE__) +#include "ESF_Peer_Admin.i" +#endif /* __ACE_INLINE__ */ + +#include "ESF_Peer_Workers.h" + +ACE_RCSID(ESF, ESF_Peer_Admin, "$Id$") + +template<class EC, class P, class PEER> void +TAO_ESF_Peer_Admin<EC,P,PEER>::peer_connected (PEER *peer, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC (()) +{ + TAO_ESF_Peer_Connected<P,PEER> worker (peer); + + this->for_each (&worker, ACE_TRY_ENV); +} + +template<class EC, class P, class PEER> void +TAO_ESF_Peer_Admin<EC,P,PEER>::peer_reconnected (PEER *peer, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC (()) +{ + TAO_ESF_Peer_Reconnected<P,PEER> worker (peer); + + this->for_each (&worker, ACE_TRY_ENV); +} + +template<class EC, class P, class PEER> void +TAO_ESF_Peer_Admin<EC,P,PEER>::peer_disconnected (PEER *peer, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC (()) +{ + TAO_ESF_Peer_Disconnected<P,PEER> worker (peer); + + this->for_each (&worker, ACE_TRY_ENV); +} + +#endif /* TAO_ESF_PEER_ADMIN_CPP */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Admin.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Admin.h new file mode 100644 index 00000000000..8076f100978 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Admin.h @@ -0,0 +1,102 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Event Service Framework +// +// = FILENAME +// ESF_Peer_Admin +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// = CREDITS +// http://www.cs.wustl.edu/~coryan/EC/index.html +// +// ============================================================================ + +#ifndef TAO_ESF_PEER_ADMIN_H +#define TAO_ESF_PEER_ADMIN_H + +#include "ESF_Proxy_Admin.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +template<class EVENT_CHANNEL, class PROXY, class PEER> +class TAO_ESF_Peer_Admin : TAO_ESF_Proxy_Admin<EVENT_CHANNEL,PROXY> +{ + // = TITLE + // ESF_Peer_Admin + // + // = DESCRIPTION + // Some Event Services that perform filtering have to propagate + // the consumer connect/disconnect activities to the suppliers, + // and vice-versa. + // In that scenario the ESF_Proxy_Admin<> interface is augmented + // with connected()/reconnected()/disconnected() operations for + // the proxy peers (i.e. the ProxySuppliers for the ProxyConsumers + // and vice-versa). + // + // = REQUIREMENTS + // In addition to the requirements imposed by ESF_Proxy_Admin<> + // the PROXY interface must implement: + // + // void connected (PEER *peer, CORBA::Environment&) throw (); + // void reconnected (PEER *peer, CORBA::Environment&) throw (); + // void disconnected (PEER *peer, CORBA::Environment&) throw (); + // + // Similarly, the PEER interface must implement: + // + // void connected (PROXY *proxy, CORBA::Environment&) throw (); + // void reconnected (PROXY *proxy, CORBA::Environment&) throw (); + // void disconnected (PROXY *proxy, CORBA::Environment&) throw (); + // +public: + TAO_ESF_Peer_Admin (EVENT_CHANNEL *ec); + // Constructor + + virtual ~TAO_ESF_Peer_Admin (void); + // destructor + + virtual void peer_connected (PEER *peer, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC (()); + // A <peer> has connected, this is invoked when the peer's client + // has invoked the connect_xxx_yyy() method. + // The default implementation is a no-op. + + virtual void peer_reconnected (PEER *peer, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC (()); + // A <peer> has reconnected, i.e. its client has invoked the + // connect_xxx_yyy() method, but the peer was connected already. + // The default implementation delegates on the collection + // <reconnected> method + + virtual void peer_disconnected (PEER *peer, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC (()); + // A <peer> has been disconnected. The default implementation + // removes the object from the collection and deactivates the + // proxy. +}; + +// **************************************************************** + +#if defined (__ACE_INLINE__) +#include "ESF_Peer_Admin.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ESF_Peer_Admin.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("ESF_Peer_Admin.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* TAO_ESF_PEER_ADMIN_H */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Admin.i b/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Admin.i new file mode 100644 index 00000000000..06c4aefb359 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Admin.i @@ -0,0 +1,7 @@ +// $Id$ + +template<class EC,class P,class R> ACE_INLINE +TAO_ESF_Peer_Admin<EC,P,R>::TAO_ESF_Peer_Admin (EC *ec) + : TAO_ESF_Proxy_Admin<EC,P> (ec) +{ +} diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Workers.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Workers.cpp new file mode 100644 index 00000000000..cd5c8ca1e8c --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Workers.cpp @@ -0,0 +1,51 @@ +// $Id$ + +#ifndef TAO_ESF_PEER_WORKERS_CPP +#define TAO_ESF_PEER_WORKERS_CPP + +#include "ESF_Peer_Workers.h" + +#if ! defined (__ACE_INLINE__) +#include "ESF_Peer_Workers.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ESF, ESF_Peer_Workers, "$Id$") + +template<class P, class R> void +TAO_ESF_Peer_Connected<P,R>::work (P *proxy, + CORBA::Environment &ACE_TRY_ENV) +{ + proxy->connected (this->peer_, ACE_TRY_ENV); + ACE_CHECK; // Shouldn't happen, just following the discipline + + this->peer_->connected (proxy, ACE_TRY_ENV); + ACE_CHECK; // Shouldn't happen, just following the discipline +} + +// **************************************************************** + +template<class P, class R> void +TAO_ESF_Peer_Reconnected<P,R>::work (P *proxy, + CORBA::Environment &ACE_TRY_ENV) +{ + proxy->reconnected (this->peer_, ACE_TRY_ENV); + ACE_CHECK; // Shouldn't happen, just following the discipline + + this->peer_->reconnected (proxy, ACE_TRY_ENV); + ACE_CHECK; // Shouldn't happen, just following the discipline +} + +// **************************************************************** + +template<class P, class R> void +TAO_ESF_Peer_Disconnected<P,R>::work (P *proxy, + CORBA::Environment &ACE_TRY_ENV) +{ + proxy->disconnected (this->peer_, ACE_TRY_ENV); + ACE_CHECK; // Shouldn't happen, just following the discipline + + this->peer_->disconnected (proxy, ACE_TRY_ENV); + ACE_CHECK; // Shouldn't happen, just following the discipline +} + +#endif /* TAO_ESF_PEER_WORKERS_CPP */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Workers.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Workers.h new file mode 100644 index 00000000000..b1939cefd81 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Workers.h @@ -0,0 +1,107 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Event Service Framework +// +// = FILENAME +// ESF_Peer_Connected +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// = CREDITS +// http://www.cs.wustl.edu/~coryan/EC/index.html +// +// ============================================================================ + +#ifndef TAO_ESF_PEER_WORKERS_H +#define TAO_ESF_PEER_WORKERS_H + +#include "ESF_Worker.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +template<class PROXY, class PEER> +class TAO_ESF_Peer_Connected : public TAO_ESF_Worker<PROXY> +{ + // = DESCRIPTION + // Helper class. + // Used to iterate over a Proxy_Collection and invoke: + // + // PROXY->connected (peer); + // peer->connected (proxy); + // +public: + TAO_ESF_Peer_Connected (PEER *peer); + + void work (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV); + +private: + PEER* peer_; +}; + +// **************************************************************** + +template<class PROXY, class PEER> +class TAO_ESF_Peer_Reconnected : public TAO_ESF_Worker<PROXY> +{ + // = DESCRIPTION + // Helper class. + // Used to iterate over a Proxy_Collection and invoke: + // + // PROXY->reconnected (peer); + // peer->reconnected (proxy); + // +public: + TAO_ESF_Peer_Reconnected (PEER *peer); + + void work (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV); + +private: + PEER* peer_; +}; + +// **************************************************************** + +template<class PROXY, class PEER> +class TAO_ESF_Peer_Disconnected : public TAO_ESF_Worker<PROXY> +{ + // = DESCRIPTION + // Helper class. + // Used to iterate over a Proxy_Collection and invoke: + // + // PROXY->disconnected (peer); + // peer->disconnected (proxy); + // +public: + TAO_ESF_Peer_Disconnected (PEER *peer); + + void work (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV); + +private: + PEER* peer_; +}; + +// **************************************************************** + +#if defined (__ACE_INLINE__) +#include "ESF_Peer_Workers.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ESF_Peer_Workers.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("ESF_Peer_Workers.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* TAO_ESF_PEER_WORKERS_H */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Workers.i b/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Workers.i new file mode 100644 index 00000000000..0ff67b7692e --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Workers.i @@ -0,0 +1,25 @@ +// $Id$ + +template<class P, class R> +TAO_ESF_Peer_Connected<P,R>::TAO_ESF_Peer_Connected (R *peer) + : peer_ (peer) +{ +} + +// **************************************************************** + +template<class P, class R> +TAO_ESF_Peer_Reconnected<P,R>::TAO_ESF_Peer_Reconnected (R *peer) + : peer_ (peer) +{ +} + +// **************************************************************** + +template<class P, class R> +TAO_ESF_Peer_Disconnected<P,R>::TAO_ESF_Peer_Disconnected (R *peer) + : peer_ (peer) +{ +} + +// **************************************************************** diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.cpp new file mode 100644 index 00000000000..f0b9b6f9fb1 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.cpp @@ -0,0 +1,101 @@ +// $Id$ + +#ifndef TAO_ESF_PROXY_ADMIN_CPP +#define TAO_ESF_PROXY_ADMIN_CPP + +#include "ESF_Proxy_Admin.h" + +#if ! defined (__ACE_INLINE__) +#include "ESF_Proxy_Admin.i" +#endif /* __ACE_INLINE__ */ + +#include "ESF_Shutdown_Proxy.h" + +ACE_RCSID(ESF, ESF_Proxy_Admin, "$Id$") + +template<class EC, class P> +TAO_ESF_Proxy_Admin<EC,P>::TAO_ESF_Proxy_Admin (EC *ec) + : event_channel_ (ec) +{ + this->event_channel_->create_proxy_collection (this->collection_); +} + +template<class EC, class P> +TAO_ESF_Proxy_Admin<EC,P>::~TAO_ESF_Proxy_Admin (void) +{ + this->event_channel_->destroy_proxy_collection (this->collection_); +} + +template<class EC, class PROXY> ACE_TYPENAME PROXY::_ptr_type +TAO_ESF_Proxy_Admin<EC,PROXY>::obtain (CORBA::Environment &) + ACE_THROW_SPEC (()) +{ + PROXY* proxy; + this->event_channel_->create_proxy (proxy); + + PortableServer::ServantBase_var holder = proxy; + + ACE_TYPENAME PROXY::_var_type result = + proxy->activate (ACE_TRY_ENV); + ACE_CHECK_RETURN (PROXY::Interface::_nil ()); + + this->collection_->connected (proxy, ACE_TRY_ENV); + ACE_CHECK_RETURN (PROXY::Interface::_nil ()); + + return result._retn (); +} + +template<class EC, class P> void +TAO_ESF_Proxy_Admin<EC,P>::shutdown (CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC (()) +{ + TAO_ESF_Shutdown_Proxy<P> worker; + + this->collection_->for_each (&worker, ACE_TRY_ENV); + ACE_CHECK; // Cannot happen, just following the discipline. + + this->collection_->shutdown (ACE_TRY_ENV); +} + +template<class EC, class P> void +TAO_ESF_Proxy_Admin<EC,P>::connected (P *, + CORBA::Environment &) + ACE_THROW_SPEC (()) +{ +} + +template<class EC, class P> void +TAO_ESF_Proxy_Admin<EC,P>::reconnected (P *proxy, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC (()) +{ + this->collection_->reconnected (proxy, ACE_TRY_ENV); +} + +template<class EC, class P> void +TAO_ESF_Proxy_Admin<EC,P>::disconnected (P *proxy, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC (()) +{ + ACE_TRY + { + this->collection_->disconnected (proxy, ACE_TRY_ENV); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // @@ In the future the collections may raise exceptions to + // report errors (such as out of memory or things like that). + // We must decide how is that info going to be used, and how + // would we propagate the exception to the application. + // For example: the CosEC has no exceptions for "out of + // resources" or something similar, and i've never seen a spec + // that has an exception for "could not acquire a mutex". + } + ACE_ENDTRY; + + proxy->deactivate (ACE_TRY_ENV); + ACE_CHECK; // Cannot happen, just following the discipline. +} + +#endif /* TAO_ESF_PROXY_ADMIN_CPP */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.h new file mode 100644 index 00000000000..7b04adf48fa --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.h @@ -0,0 +1,134 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Event Service Framework +// +// = FILENAME +// ESF_Proxy_Admin +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// = CREDITS +// http://www.cs.wustl.edu/~coryan/EC/index.html +// +// ============================================================================ + +#ifndef TAO_ESF_PROXY_ADMIN_H +#define TAO_ESF_PROXY_ADMIN_H + +#include "ESF_Proxy_Collection.h" +#include "ESF_Worker.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +template<class EVENT_CHANNEL, class PROXY> +class TAO_ESF_Proxy_Admin +{ + // = TITLE + // ESF_Proxy_Admin + // + // = DESCRIPTION + // Implement common tasks in the Admin interfaces. + // + // = REQUIREMENTS + // + // The EVENT_CHANNEL interface must implement: + // + // void create_proxy (PROXY*&); + // // create a new proxy + // void destroy_proxy (PROXY*); + // // destroy a proxy + // + // void create_proxy_collection (TAO_ESF_Proxy_Collection<PROXY>*&); + // // create a proxy collection + // void destroy_proxy_collection (TAO_ESF_Proxy_Collection<PROXY>*&); + // // destroy a proxy collection + // + // In addition to the requirements imposed by + // TAO_ESF_Proxy_Collection<>, the PROXY interface must define: + // + // typename .... _ptr_type; + // // The T_ptr for the IDL interface implemented by the PROXY. + // typename .... _var_type; + // // The T_var for the IDL interface implemented by the PROXY. + // + // PROXY::_ptr_type + // PROXY::activate (CORBA::Environment &) throw (); + // // activate the proxy and return the object reference + // +public: + TAO_ESF_Proxy_Admin (EVENT_CHANNEL *ec); + // Constructor + + virtual ~TAO_ESF_Proxy_Admin (void); + // destructor + + void for_each (TAO_ESF_Worker<PROXY> *worker, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC (()); + // Iterate over its internal collection. + + virtual ACE_TYPENAME PROXY::_ptr_type + obtain (CORBA::Environment &) + ACE_THROW_SPEC (()); + // Create a new PROXY and activate it. + + virtual void shutdown (CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC (()); + // The Event Channel that owns this Admin object is going + // down. Invoke <shutdown> on all the proxies, cleanup the + // collection and prepare to terminate. + + virtual void connected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC (()); + // A <proxy> has connected, this is invoked when the proxy's client + // has invoked the connect_xxx_yyy() method. + // The default implementation is a no-op. + + virtual void reconnected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC (()); + // A <proxy> has reconnected, i.e. its client has invoked the + // connect_xxx_yyy() method, but the proxy was connected already. + // The default implementation delegates on the collection + // <reconnected> method + + virtual void disconnected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC (()); + // A <proxy> has been disconnected. The default implementation + // removes the object from the collection and deactivates the + // proxy. + +private: + EVENT_CHANNEL *event_channel_; + // The Event Channel we belong to + + typedef TAO_ESF_Proxy_Collection<PROXY> Collection; + + Collection *collection_; + // The supplier container. +}; + +// **************************************************************** + +#if defined (__ACE_INLINE__) +#include "ESF_Proxy_Admin.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ESF_Proxy_Admin.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("ESF_Proxy_Admin.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* TAO_ESF_PROXY_ADMIN_H */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.i b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.i new file mode 100644 index 00000000000..9e2226e4e54 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.i @@ -0,0 +1,11 @@ +// $Id$ + +template<class EC,class P> ACE_INLINE void +TAO_ESF_Proxy_Admin<EC,P>:: + for_each (TAO_ESF_Worker<P> *worker, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC (()) +{ + this->collection_->for_each (worker, ACE_TRY_ENV); +} + diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Collection.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Collection.cpp new file mode 100644 index 00000000000..797ad4df35d --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Collection.cpp @@ -0,0 +1,22 @@ +// $Id$ + +#ifndef TAO_ESF_PROXY_COLLECTION_CPP +#define TAO_ESF_PROXY_COLLECTION_CPP + +#include "ESF_Proxy_Collection.h" +#include "ESF_Worker.h" + +#if ! defined (__ACE_INLINE__) +#include "ESF_Proxy_Collection.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ESF, ESF_Proxy_Collection, "$Id$") + +// **************************************************************** + +template<class PROXY> +TAO_ESF_Proxy_Collection<PROXY>::~TAO_ESF_Proxy_Collection (void) +{ +} + +#endif /* TAO_ESF_PROXY_COLLECTION_CPP */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Collection.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Collection.h new file mode 100644 index 00000000000..9f69b025d41 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Collection.h @@ -0,0 +1,184 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Event Service Framework +// +// = FILENAME +// ESF_Proxy_Collection +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// = CREDITS +// http://www.cs.wustl.edu/~coryan/EC/index.html +// +// ============================================================================ + +#ifndef TAO_ESF_PROXY_COLLECTION_H +#define TAO_ESF_PROXY_COLLECTION_H + +#include "tao/corba.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +template<class Target> class TAO_ESF_Worker; + +template<class PROXY> +class TAO_ESF_Proxy_Collection +{ + // = TITLE + // ESF_Proxy_Collection + // + // = DESCRIPTION + // Many components in an Event Service need to keep a collection + // of proxies; these collections must be able to cope with several + // concurrency issues: + // + Some threads may need to iterate over the collection and + // invoke a method on each element. Locking the collection + // while this is done is not feasible in all cases: under some + // configurations the same thread that is iterating over the + // collection may need to make changes to the set. + // + A recursive lock does not solve the concurrency problems + // because recursive changes to the collection still invalidate + // the iterators. + // + // There are several solutions to this problem (see the VARIANTS) + // section, and there is no single one that works bests in all + // cases. As usual, we wish the strategize the protocol used to + // serialize iterations and changes to the collection. This class + // encapsulates that protocol. + // + // The usual form of the Iterator pattern does not work well in + // this case: in several variants the synchronization protocol and + // the iteration loop must collaborate to work efficiently. + // Exposing an external iterator would require that every other + // component in the system can support all the synchronization + // protocols. It is possible to hide some of that complexity + // using heavy weight iterators, but their use is ackward, + // specially since the Koening-style iterators have become more + // popular. + // + // Regular member functions are used to insert, remove and update + // members of the collection and to shutdown (i.e. perform final + // cleanup operations). + // + // The class must also collaborate with other components of the + // EC to efficiently and safely perform memory managment of the + // members in the collection. + // + // = REQUIREMENTS + // The PROXY object must be reference counted with the following + // operations: + // + // _incr_refcnt() - increment the reference count. + // _decr_refcnt() - decrement the reference count. + // + // = VARIANTS + // + // We identify several sources of variation: + // + // + Immediate_Changes: in this variant the iteration in performed + // while holding some kind of synchronization primitive, such as a + // thread mutex, a recursive mutex, a RW lock, etc. + // This is only useful in configurations where a separate thread + // dispatches the events, and thus, can only be used with real + // locks. + // + // + Copy_On_Read: before performing the iteration the collection + // is duplicated into a temporary array. Thus no locks are held + // during the iteration. This is a very expensive approach, but + // useful in many cases. + // The kind of lock is also strategized in this case. + // + // + Copy_On_Write: this is very similar to the previous approach, + // but the collection is only duplicated when a change is required + // while some thread is performing an iteration. The iteration + // continues over the original copy, while the changes are + // performed in the duplicate. The new copy of the collection is + // used for any subsequent operations, the original is discarded + // when the last thread using it completes its work. + // This approach optimizes for the case where no changes are + // is duplicated into a temporary array. Thus no locks are held + // during the iteration. This is a very expensive approach, but + // useful in many cases. + // The kind of lock is also strategized in this case. + // + // + Delayed_Changes: before starting the iteration a counter is + // incremented, this counter is used to keep track of the number + // of threads concurrently using the collection. + // If a thread wants to perform a change to the collection it must + // first verify that there are no threads iterating over it. If + // there are any threads then the thread queues the modification + // for later execution, using the Command pattern. + // The kind of lock is strategized, as this approach is used in + // single threaded configurations. + // There are two main variations: + // - An upcall can result in new dispatches: in this case we + // have to keep track of a the list of current threads using + // a Set, to avoid dead-locks. + // IMPLEMENTATION: the design is not complete, probably + // similar to the next one. + // - Otherwise we just need to control the concurrency using the + // algorithm described below. + // + // + // = MEMORY MANAGMENT + // It assumes ownership of the proxies added to the collection, + // it increases the reference count. + // + // = LOCKING + // Locking is provided by derived classes. + // + // = TODO + // +public: + virtual ~TAO_ESF_Proxy_Collection (void); + // destructor + + virtual void for_each (TAO_ESF_Worker<PROXY> *worker, + CORBA::Environment &ACE_TRY_ENV) = 0; + // Iterate over the collection and invoke worker->work() for each + // member of the collection. + // This encapsulates + + virtual void connected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) = 0; + // Insert a new element into the collection. The collection assumes + // ownership of the element. + + virtual void reconnected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) = 0; + // Insert an element into the collection. No errors can be raised + // if the element is already present. + // The collection assumes ownership, i.e. must invoke + // <proxy->_decr_refcnt()> if the element is already present in the + // collection. + + virtual void disconnected (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) = 0; + // Remove an element from the collection. + + virtual void shutdown (CORBA::Environment &ACE_TRY_ENV) = 0; + // The EC is shutting down, must release all the elements. +}; + +// **************************************************************** + +#if defined (__ACE_INLINE__) +#include "ESF_Proxy_Collection.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ESF_Proxy_Collection.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("ESF_Proxy_Collection.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* TAO_ESF_PROXY_COLLECTION_H */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Collection.i b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Collection.i new file mode 100644 index 00000000000..cfa1da318d3 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Collection.i @@ -0,0 +1 @@ +// $Id$ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.cpp new file mode 100644 index 00000000000..5fd6f3adc5b --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.cpp @@ -0,0 +1,89 @@ +// $Id$ + +#ifndef TAO_ESF_PROXY_LIST_CPP +#define TAO_ESF_PROXY_LIST_CPP + +#include "ESF_Proxy_List.h" + +#if ! defined (__ACE_INLINE__) +#include "ESF_Proxy_List.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ESF, ESF_Proxy_List, "$Id$") + +template<class PROXY> +TAO_ESF_Proxy_List<PROXY>:: + TAO_ESF_Proxy_List (void) +{ +} + +template<class PROXY> void +TAO_ESF_Proxy_List<PROXY>::connected (PROXY *proxy, + CORBA::Environment &) +{ + int r = this->impl_.insert (proxy); + if (r == 0) + return; + + if (r == 1) + { + // @@ Already there, throw some user exception.. + proxy->_decr_refcnt (); + } + if (r == -1) + { + // @@ Cannot insert, running out of memory? throw some other + // user exception + proxy->_decr_refcnt (); + } +} + +template<class PROXY> void +TAO_ESF_Proxy_List<PROXY>::reconnected (PROXY *proxy, + CORBA::Environment &) +{ + int r = this->impl_.insert (proxy); + if (r == 0 || r == 1) + { + // Reference count is incremented by the callers to [re]connected. + // @@ Find out if the protocol could be simplified, and decoupling + // increased. + proxy->_decr_refcnt (); + return; + } + + if (r == -1) + { + // @@ Cannot insert, running out of memory? throw some other + // user exception + proxy->_decr_refcnt (); + } +} + +template<class PROXY> void +TAO_ESF_Proxy_List<PROXY>::disconnected (PROXY *proxy, + CORBA::Environment &) +{ + int r = this->impl_.remove (proxy); + if (r != 0) + { + // @@ Cannot remove, throw some other + // user exception + return; + } + proxy->_decr_refcnt (); +} + +template<class PROXY> void +TAO_ESF_Proxy_List<PROXY>::shutdown (CORBA::Environment &) +{ + Iterator end = this->impl_.end (); + for (Iterator i = this->impl_.begin (); i != end; ++i) + { + // Decrement reference count + (*i)->_decr_refcnt (); + } + this->impl_.reset (); +} + +#endif /* TAO_ESF_PROXY_LIST_CPP */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.h new file mode 100644 index 00000000000..0c8b593d8a9 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.h @@ -0,0 +1,72 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Event Service Framework +// +// = FILENAME +// ESF_Proxy_List +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// = CREDITS +// http://www.cs.wustl.edu/~coryan/EC/index.html +// +// ============================================================================ + +#ifndef TAO_ESF_PROXY_LIST_H +#define TAO_ESF_PROXY_LIST_H + +#include "tao/corba.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Containers.h" + +template<class PROXY> +class TAO_ESF_Proxy_List +{ + // = DESCRIPTION + // A concrete proxy collection. + // Based on the ACE_Unbounded_Set<> collection, used a double + // linked list internally. + // +public: + typedef ACE_Unbounded_Set<PROXY*> Implementation; + typedef ACE_Unbounded_Set_Iterator<PROXY*> Iterator; + + TAO_ESF_Proxy_List (void); + + ACE_Unbounded_Set_Iterator<PROXY*> begin (void); + ACE_Unbounded_Set_Iterator<PROXY*> end (void); + size_t size (void) const; + void connected (PROXY *, + CORBA::Environment &); + void reconnected (PROXY *, + CORBA::Environment &); + void disconnected (PROXY *, + CORBA::Environment &); + void shutdown (CORBA::Environment &); + +private: + ACE_Unbounded_Set<PROXY*> impl_; +}; + +#if defined (__ACE_INLINE__) +#include "ESF_Proxy_List.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ESF_Proxy_List.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("ESF_Proxy_List.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* TAO_ESF_PROXY_LIST_H */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.i b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.i new file mode 100644 index 00000000000..881283569ba --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.i @@ -0,0 +1,19 @@ +// $Id$ + +template<class PROXY> ACE_INLINE ACE_Unbounded_Set_Iterator<PROXY*> +TAO_ESF_Proxy_List<PROXY>::begin (void) +{ + return this->impl_.begin (); +} + +template<class PROXY> ACE_INLINE ACE_Unbounded_Set_Iterator<PROXY*> +TAO_ESF_Proxy_List<PROXY>::end (void) +{ + return this->impl_.end (); +} + +template<class PROXY> ACE_INLINE size_t +TAO_ESF_Proxy_List<PROXY>::size (void) const +{ + return this->impl_.size (); +} diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RB_Tree.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RB_Tree.cpp new file mode 100644 index 00000000000..3b439e54ab3 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RB_Tree.cpp @@ -0,0 +1,82 @@ +// $Id$ + +#ifndef TAO_ESF_PROXY_RB_TREE_CPP +#define TAO_ESF_PROXY_RB_TREE_CPP + +#include "ESF_Proxy_RB_Tree.h" + +#if ! defined (__ACE_INLINE__) +#include "ESF_Proxy_RB_Tree.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ESF, ESF_Proxy_RB_Tree, "$Id$") + +template<class PROXY> +TAO_ESF_Proxy_RB_Tree<PROXY>:: + TAO_ESF_Proxy_RB_Tree (void) +{ +} + +template<class PROXY> void +TAO_ESF_Proxy_RB_Tree<PROXY>::connected (PROXY *proxy, + CORBA::Environment &) +{ + int r = this->impl_.bind (proxy, 1); + if (r == 0) + return; + + if (r == 1) + { + // @@ Already there, throw some user exception.. + proxy->_decr_refcnt (); + } + if (r == -1) + { + // @@ Cannot insert, running out of memory? throw some other + // user exception + proxy->_decr_refcnt (); + } +} + +template<class PROXY> void +TAO_ESF_Proxy_RB_Tree<PROXY>::reconnected (PROXY *proxy, + CORBA::Environment &) +{ + int r = this->impl_.rebind (proxy, 1); + if (r != 0) + { + // Reference count is incremented by the callers to [re]connected. + // @@ Find out if the protocol could be simplified, and decoupling + // increased. + proxy->_decr_refcnt (); + return; + } +} + +template<class PROXY> void +TAO_ESF_Proxy_RB_Tree<PROXY>::disconnected (PROXY *proxy, + CORBA::Environment &) +{ + int r = this->impl_.unbind (proxy); + if (r != 0) + { + // @@ Cannot remove, throw some other + // user exception + return; + } + proxy->_decr_refcnt (); +} + +template<class PROXY> void +TAO_ESF_Proxy_RB_Tree<PROXY>::shutdown (CORBA::Environment &) +{ + Iterator end = this->impl_.end (); + for (Iterator i = this->impl_.begin (); i != end; ++i) + { + // Decrement reference count + (*i)->_decr_refcnt (); + } + this->impl_.clear (); +} + +#endif /* TAO_ESF_PROXY_RB_TREE_CPP */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RB_Tree.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RB_Tree.h new file mode 100644 index 00000000000..b4708000082 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RB_Tree.h @@ -0,0 +1,87 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Event Service Framework +// +// = FILENAME +// ESF_Proxy_RB_Tree +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// = CREDITS +// http://www.cs.wustl.edu/~coryan/EC/index.html +// +// ============================================================================ + +#ifndef TAO_ESF_PROXY_RB_TREE_H +#define TAO_ESF_PROXY_RB_TREE_H + +#include "tao/corba.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/RB_Tree.h" + +template<class PROXY> +class TAO_ESF_Proxy_RB_Tree_Iterator +{ +public: + typedef ACE_RB_Tree_Iterator<PROXY*,int,ACE_Less_Than<PROXY*>,ACE_Null_Mutex> Implementation; + + TAO_ESF_Proxy_RB_Tree_Iterator (const Implementation &i); + + int operator == (const TAO_ESF_Proxy_RB_Tree_Iterator<PROXY> &rhs) const; + int operator != (const TAO_ESF_Proxy_RB_Tree_Iterator<PROXY> &rhs) const; + TAO_ESF_Proxy_RB_Tree_Iterator<PROXY>& operator++ (void); + TAO_ESF_Proxy_RB_Tree_Iterator<PROXY> operator++ (int); + PROXY *operator *(void); + +private: + Implementation impl_; +}; + +// **************************************************************** + +template<class PROXY> +class TAO_ESF_Proxy_RB_Tree +{ +public: + typedef ACE_RB_Tree<PROXY*,int,ACE_Less_Than<PROXY*>,ACE_Null_Mutex> Implementation; + typedef TAO_ESF_Proxy_RB_Tree_Iterator<PROXY> Iterator; + + TAO_ESF_Proxy_RB_Tree (void); + + TAO_ESF_Proxy_RB_Tree_Iterator<PROXY> begin (void); + TAO_ESF_Proxy_RB_Tree_Iterator<PROXY> end (void); + size_t size (void) const; + void connected (PROXY *, + CORBA::Environment &); + void reconnected (PROXY *, + CORBA::Environment &); + void disconnected (PROXY *, + CORBA::Environment &); + void shutdown (CORBA::Environment &); + +private: + Implementation impl_; +}; + +#if defined (__ACE_INLINE__) +#include "ESF_Proxy_RB_Tree.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ESF_Proxy_RB_Tree.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("ESF_Proxy_RB_Tree.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* TAO_ESF_PROXY_RB_TREE_H */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RB_Tree.i b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RB_Tree.i new file mode 100644 index 00000000000..1efd97a1894 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RB_Tree.i @@ -0,0 +1,64 @@ +// $Id$ + + +template<class PROXY> ACE_INLINE +TAO_ESF_Proxy_RB_Tree_Iterator<PROXY>:: + TAO_ESF_Proxy_RB_Tree_Iterator (const Implementation &i) + : impl_ (i) +{ +} + +template<class PROXY> ACE_INLINE int +TAO_ESF_Proxy_RB_Tree_Iterator<PROXY>:: + operator == (const TAO_ESF_Proxy_RB_Tree_Iterator<PROXY> &rhs) const +{ + return this->impl_ == rhs.impl_; +} + +template<class PROXY> ACE_INLINE int +TAO_ESF_Proxy_RB_Tree_Iterator<PROXY>:: + operator != (const TAO_ESF_Proxy_RB_Tree_Iterator<PROXY> &rhs) const +{ + return this->impl_ != rhs.impl_; +} + +template<class PROXY> ACE_INLINE TAO_ESF_Proxy_RB_Tree_Iterator<PROXY>& +TAO_ESF_Proxy_RB_Tree_Iterator<PROXY>::operator++ (void) +{ + ++this->impl_; + return *this; +} + +template<class PROXY> ACE_INLINE TAO_ESF_Proxy_RB_Tree_Iterator<PROXY> +TAO_ESF_Proxy_RB_Tree_Iterator<PROXY>::operator++ (int) +{ + TAO_ESF_Proxy_RB_Tree_Iterator<PROXY> tmp = *this; + ++this->impl_; + return tmp; +} + +template<class PROXY> ACE_INLINE PROXY* +TAO_ESF_Proxy_RB_Tree_Iterator<PROXY>::operator *(void) +{ + return (*this->impl_).key (); +} + +// **************************************************************** + +template<class PROXY> ACE_INLINE TAO_ESF_Proxy_RB_Tree_Iterator<PROXY> +TAO_ESF_Proxy_RB_Tree<PROXY>::begin (void) +{ + return Iterator (this->impl_.begin ()); +} + +template<class PROXY> ACE_INLINE TAO_ESF_Proxy_RB_Tree_Iterator<PROXY> +TAO_ESF_Proxy_RB_Tree<PROXY>::end (void) +{ + return Iterator (this->impl_.end ()); +} + +template<class PROXY> ACE_INLINE size_t +TAO_ESF_Proxy_RB_Tree<PROXY>::size (void) const +{ + return this->impl_.current_size (); +} diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Shutdown_Proxy.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Shutdown_Proxy.cpp new file mode 100644 index 00000000000..628710224a9 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Shutdown_Proxy.cpp @@ -0,0 +1,30 @@ +// $Id$ + +#ifndef TAO_ESF_SHUTDOWN_PROXY_CPP +#define TAO_ESF_SHUTDOWN_PROXY_CPP + +#include "ESF_Shutdown_Proxy.h" + +#if ! defined (__ACE_INLINE__) +#include "ESF_Shutdown_Proxy.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ESF, ESF_Shutdown_Proxy, "$Id$") + +template<class PROXY> void +TAO_ESF_Shutdown_Proxy<PROXY>::work (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV) +{ + ACE_TRY + { + proxy->shutdown (ACE_TRY_ENV); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // Do not propagate any exceptions + } + ACE_ENDTRY; +} + +#endif /* TAO_ESF_SHUTDOWN_PROXY_CPP */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Shutdown_Proxy.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_Shutdown_Proxy.h new file mode 100644 index 00000000000..8d3986f5133 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Shutdown_Proxy.h @@ -0,0 +1,53 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Event Service Framework +// +// = FILENAME +// ESF_Shutdown_Proxy +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// = CREDITS +// http://www.cs.wustl.edu/~coryan/EC/index.html +// +// ============================================================================ + +#ifndef TAO_ESF_SHUTDOWN_PROXY_H +#define TAO_ESF_SHUTDOWN_PROXY_H + +#include "ESF_Worker.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +template<class PROXY> +class TAO_ESF_Shutdown_Proxy : public TAO_ESF_Worker<PROXY> +{ +public: + TAO_ESF_Shutdown_Proxy (void); + + void work (PROXY *proxy, + CORBA::Environment &ACE_TRY_ENV); +}; + +// **************************************************************** + +#if defined (__ACE_INLINE__) +#include "ESF_Shutdown_Proxy.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ESF_Shutdown_Proxy.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("ESF_Shutdown_Proxy.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* TAO_ESF_SHUTDOWN_PROXY_H */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Shutdown_Proxy.i b/TAO/orbsvcs/orbsvcs/ESF/ESF_Shutdown_Proxy.i new file mode 100644 index 00000000000..5266f0aa225 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Shutdown_Proxy.i @@ -0,0 +1,6 @@ +// $Id$ + +template<class PROXY> ACE_INLINE +TAO_ESF_Shutdown_Proxy<PROXY>::TAO_ESF_Shutdown_Proxy (void) +{ +} diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Worker.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Worker.cpp new file mode 100644 index 00000000000..2cc875b07c6 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Worker.cpp @@ -0,0 +1,19 @@ +// $Id$ + +#ifndef TAO_ESF_WORKER_CPP +#define TAO_ESF_WORKER_CPP + +#include "ESF_Worker.h" + +#if ! defined (__ACE_INLINE__) +#include "ESF_Worker.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ESF, ESF_Worker, "$Id$") + +template<class Object> +TAO_ESF_Worker<Object>::~TAO_ESF_Worker (void) +{ +} + +#endif /* TAO_ESF_WORKER_CPP */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Worker.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_Worker.h new file mode 100644 index 00000000000..f3001e69aef --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Worker.h @@ -0,0 +1,51 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Real-time Event Channel +// +// = FILENAME +// ESF_Worker +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// = CREDITS +// http://www.cs.wustl.edu/~coryan/EC/index.html +// +// ============================================================================ + +#ifndef TAO_ESF_WORKER_H +#define TAO_ESF_WORKER_H + +#include "tao/corba.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +template<class Object> +class TAO_ESF_Worker +{ +public: + virtual ~TAO_ESF_Worker (void); + + virtual void work (Object *object, + CORBA::Environment &ACE_TRY_ENV) = 0; +}; + +#if defined (__ACE_INLINE__) +#include "ESF_Worker.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ESF_Worker.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("ESF_Worker.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* TAO_ESF_WORKER_H */ diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Worker.i b/TAO/orbsvcs/orbsvcs/ESF/ESF_Worker.i new file mode 100644 index 00000000000..cfa1da318d3 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Worker.i @@ -0,0 +1 @@ +// $Id$ |