TAO_ESF  2.0.8
Public Member Functions
TAO_ESF_Proxy_Collection< PROXY > Class Template Reference

ESF_Proxy_Collection. More...

#include <ESF_Proxy_Collection.h>

Inheritance diagram for TAO_ESF_Proxy_Collection< PROXY >:
Inheritance graph
[legend]

List of all members.

Public Member Functions

virtual ~TAO_ESF_Proxy_Collection (void)
 destructor
virtual void for_each (TAO_ESF_Worker< PROXY > *worker)=0
virtual void connected (PROXY *proxy)=0
virtual void reconnected (PROXY *proxy)=0
virtual void disconnected (PROXY *proxy)=0
 Remove an element from the collection.
virtual void shutdown (void)=0
 The EC is shutting down, must release all the elements.

Detailed Description

template<class PROXY>
class TAO_ESF_Proxy_Collection< PROXY >

ESF_Proxy_Collection.

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.

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:

It assumes ownership of the proxies added to the collection, it increases the reference count.

Locking is provided by derived classes.


Constructor & Destructor Documentation

template<class PROXY >
TAO_ESF_Proxy_Collection< PROXY >::~TAO_ESF_Proxy_Collection ( void  ) [virtual]

destructor


Member Function Documentation

template<class PROXY >
virtual void TAO_ESF_Proxy_Collection< PROXY >::connected ( PROXY *  proxy) [pure virtual]
template<class PROXY >
virtual void TAO_ESF_Proxy_Collection< PROXY >::disconnected ( PROXY *  proxy) [pure virtual]
template<class PROXY >
virtual void TAO_ESF_Proxy_Collection< PROXY >::for_each ( TAO_ESF_Worker< PROXY > *  worker) [pure virtual]
template<class PROXY >
virtual void TAO_ESF_Proxy_Collection< PROXY >::reconnected ( PROXY *  proxy) [pure virtual]

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.

Implemented in TAO_ESF_Copy_On_Write< PROXY, COLLECTION, ITERATOR, ACE_SYNCH_DECL >, TAO_ESF_Delayed_Changes< PROXY, COLLECTION, ITERATOR, ACE_SYNCH_DECL >, TAO_ESF_Delayed_Changes< PROXY, COLLECTION, ITERATOR, ACE_SYNCH_USE >, TAO_ESF_Copy_On_Read< PROXY, COLLECTION, ITERATOR, ACE_LOCK >, and TAO_ESF_Immediate_Changes< PROXY, COLLECTION, ITERATOR, ACE_LOCK >.

template<class PROXY >
virtual void TAO_ESF_Proxy_Collection< PROXY >::shutdown ( void  ) [pure virtual]

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Defines