summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/Event/EC_ProxyPushSupplier_Set.h
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/Event/EC_ProxyPushSupplier_Set.h')
-rw-r--r--TAO/orbsvcs/orbsvcs/Event/EC_ProxyPushSupplier_Set.h264
1 files changed, 0 insertions, 264 deletions
diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_ProxyPushSupplier_Set.h b/TAO/orbsvcs/orbsvcs/Event/EC_ProxyPushSupplier_Set.h
deleted file mode 100644
index d4f828d0bac..00000000000
--- a/TAO/orbsvcs/orbsvcs/Event/EC_ProxyPushSupplier_Set.h
+++ /dev/null
@@ -1,264 +0,0 @@
-/* -*- C++ -*- */
-// $Id$
-//
-// ============================================================================
-//
-// = LIBRARY
-// ORBSVCS Real-time Event Channel
-//
-// = FILENAME
-// EC_ProxyPushSupplier_Set
-//
-// = AUTHOR
-// Carlos O'Ryan (coryan@cs.wustl.edu)
-//
-// = CREDITS
-// Based on previous work by Tim Harrison (harrison@cs.wustl.edu)
-// and other members of the DOC group.
-// More details can be found in:
-// http://www.cs.wustl.edu/~schmidt/oopsla.ps.gz
-// http://www.cs.wustl.edu/~schmidt/JSAC-98.ps.gz
-//
-// ============================================================================
-
-#ifndef TAO_EC_PROXYPUSHSUPPLIER_SET_H
-#define TAO_EC_PROXYPUSHSUPPLIER_SET_H
-
-#include "orbsvcs/orbsvcs_export.h"
-
-#if !defined (ACE_LACKS_PRAGMA_ONCE)
-# pragma once
-#endif /* ACE_LACKS_PRAGMA_ONCE */
-
-#include "ace/Containers.h"
-#include "tao/corba.h"
-#include "EC_Busy_Lock.h"
-#if defined(__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ < 8
-// g++ 2.7.2 is broken and cannot handle forward declaration of
-// templates in this case.
-// I could just include this file for all compilers, but I want to
-// minimize compile-time dependencies *and* document this problem so
-// we can fix it as g++ 2.7.2 is phased out.
-#include "EC_Command.h"
-#endif /* __GNUC__ */
-
-class TAO_EC_ProxyPushSupplier;
-template<class Target,class Object> class TAO_EC_Connected_Command;
-template<class Target,class Object> class TAO_EC_Disconnected_Command;
-
-class TAO_ORBSVCS_Export TAO_EC_ProxyPushSupplier_Set
-{
- // = TITLE
- // ProxyPushSupplier_Set
- //
- // = DESCRIPTION
- // Many components in the Event Channel need to keep a collection
- // of ProxyPushSuppliers; this 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.
- // + A recursive lock does not solve the concurrency problems
- // correctly because in the common case we don't want to stop
- // other threads from doing the same iteration, and changes to
- // the collection could be very uncommon wrt dispatching over
- // the set of ProxyPushSuppliers.
- // + Using a reader-write lock with upgrades does not solve the
- // problem either: upgrading the lock can fail and still
- // invalidates the iterators that the thread has.
- // + Copying the collection to iterate over it is a good solution
- // for non-real-time systems, but again the copying could be
- // non-deterministic, and is expensive since most iterations
- // will not result in changes.
- //
- // This class encapsulates a protocol to solve this concurrency
- // issues (and other minor ones). The first solution is to delay
- // 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).
- // 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?
- //
- // = VARIANTS
- //
- // We identify several sources of variation:
- //
- // + Immediate changes without delay (only locking). This is only
- // useful in configurations where a separate thread dispatches
- // the events, and thus, can only be used with real locks.
- // The busy()/idle() methods use a read acquire/release, the
- // connected()/disconnected() methods use a write
- // acquire/release. We can either use RW or regular mutexes.
- // IMPLEMENTATION: a derived class with strategized locking
- // (ACE_Lock? or templates?).
- //
- // + Copying data for iteration:
- // Can use a regular mutex (as in the previous case), or even a
- // null lock.
- // @@ Must stablish if there is a simple way to encapsulate this
- // in the Set class, as opposed to the clients of the class.
- // @@ The implementation is essentially the same as above, but
- // the clients must make the copy.
- // IMPLEMENTATION: As above.
- //
- // + Delayed operations:
- // Only makes sense if the thread dispatching is the same thread
- // where the upcalls run.
- // Can require regular locks or null locks (for ST
- // implementations); notice that this will require templates
- // to parametrize the mutexes and condition variables.
- // 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.
- // IMPLEMENTATION: a derived parametric class (the arguments
- // are the types of locks).
- //
- // = DELAYED OPERATIONS AND CONCURRENCY
- //
- // The algorithm proposed 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.
- //
- // = MEMORY MANAGMENT
- // It assumes ownership of the ProxyPushSuppliers added to the
- // collection: simply by increasing their reference count.
- //
- // = LOCKING
- // Locking is provided by derived classes.
- //
- // = TODO
- //
-public:
- TAO_EC_ProxyPushSupplier_Set (void);
- // Constructor.
-
- virtual ~TAO_EC_ProxyPushSupplier_Set (void);
- // Destructor.
-
- typedef ACE_Unbounded_Set<TAO_EC_ProxyPushSupplier*> SupplierSet;
- typedef ACE_Unbounded_Set_Iterator<TAO_EC_ProxyPushSupplier*> SupplierSetIterator;
- // The actual implementation of the collection, notice that only
- // iteration is exposed, methods to insert and remove objects are
- // hidden behind proper interfaces.
-
- SupplierSetIterator begin (void);
- SupplierSetIterator end (void);
- // Iterators over the set of ProxyPushSuppliers
- // Remember that all clients of this class must call busy() before
- // starting an iteration and call idle() once the iteration is
- // finished. Otherwise the iterators may be invalidated by other
- // threads.
- // A helper object (the busy_lock) is provided to simplify this task
- // and make it exception safe.
-
- typedef TAO_EC_Busy_Lock_Adapter<TAO_EC_ProxyPushSupplier_Set> Busy_Lock;
- Busy_Lock& busy_lock (void);
- // This object is an adapter to the busy/idle protocol.
-
- void busy_hwm (CORBA::ULong hwm);
- CORBA::ULong busy_hwm (void) const;
- void max_write_delay (CORBA::ULong hwm);
- CORBA::ULong max_write_delay (void) const;
- // This two attributes control the maximum number of concurrent
- // readers allowed in the set (busy_hwm) and the maximum number of
- // threads that can proceed after there is a modification posted.
-
- virtual int busy (void) = 0;
- virtual int idle (void) = 0;
- // The implementation of this methods is provided by derived
- // classes, that provide appropiate locking.
-
- virtual void connected (TAO_EC_ProxyPushSupplier*,
- CORBA::Environment&) = 0;
- virtual void disconnected (TAO_EC_ProxyPushSupplier*,
- CORBA::Environment&) = 0;
- // Used to inform the EC that a Supplier has connected or
- // disconnected from it.
-
-protected:
- virtual void connected_i (TAO_EC_ProxyPushSupplier* supplier,
- CORBA::Environment &env);
- // The implementation of connected(), without locking.
- // It does not increase the reference count on the supplier
-
- virtual void disconnected_i (TAO_EC_ProxyPushSupplier* supplier,
- CORBA::Environment &env);
- // The implementation of disconnected(), without locking.
- // It decreases the reference count on the supplier if the operation
- // is successful.
-
- typedef TAO_EC_Connected_Command<TAO_EC_ProxyPushSupplier_Set,TAO_EC_ProxyPushSupplier> Connected_Command;
- typedef TAO_EC_Connected_Command<TAO_EC_ProxyPushSupplier_Set,TAO_EC_ProxyPushSupplier> Disconnected_Command;
-
- friend class TAO_EC_Connected_Command<TAO_EC_ProxyPushSupplier_Set,TAO_EC_ProxyPushSupplier>;
- friend class TAO_EC_Disconnected_Command<TAO_EC_ProxyPushSupplier_Set,TAO_EC_ProxyPushSupplier>;
- // This two classes call the connected_i() and disconnected_i()
- // methods, that's ok because they do while this class is holding
- // its lock.
-
- virtual void execute_delayed_operations (void);
- // Derived classes that implement delayed disconnects and connects
- // must override this method.
-
-protected:
- SupplierSet all_suppliers_;
- // The collection of ProxyPushSupplier objects.
-
- TAO_EC_Busy_Lock_Adapter<TAO_EC_ProxyPushSupplier_Set> busy_lock_;
- // The busy lock object
-
-private:
- CORBA::ULong busy_hwm_;
- CORBA::ULong max_write_delay_;
- // Control variables for the concurrency policies.
-};
-
-#if defined (__ACE_INLINE__)
-#include "EC_ProxyPushSupplier_Set.i"
-#endif /* __ACE_INLINE__ */
-
-#endif /* TAO_EC_PROXYPUSHSUPPLIER_SET_H */