summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/ESF
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/ESF')
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Busy_Lock.cpp62
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Busy_Lock.h61
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Busy_Lock.i8
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Read.cpp82
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Read.h82
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Read.i42
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Defaults.h42
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.cpp206
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.h161
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.i32
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Command.cpp66
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Command.h198
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Command.i41
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Immediate_Changes.cpp46
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Immediate_Changes.h72
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Immediate_Changes.i43
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Admin.cpp46
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Admin.h102
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Admin.i7
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Workers.cpp51
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Workers.h107
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Peer_Workers.i25
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.cpp101
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.h134
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.i11
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Collection.cpp22
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Collection.h184
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Collection.i1
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.cpp89
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.h72
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.i19
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RB_Tree.cpp82
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RB_Tree.h87
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RB_Tree.i64
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Shutdown_Proxy.cpp30
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Shutdown_Proxy.h53
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Shutdown_Proxy.i6
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Worker.cpp19
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Worker.h51
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Worker.i1
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$