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_Copy_On_Write.cpp16
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.h13
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.i22
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.cpp3
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.cpp6
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.cpp5
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RefCount_Guard.cpp27
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RefCount_Guard.h79
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RefCount_Guard.i12
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_RefCount_Guard.cpp14
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_RefCount_Guard.h64
-rw-r--r--TAO/orbsvcs/orbsvcs/ESF/ESF_RefCount_Guard.i16
12 files changed, 260 insertions, 17 deletions
diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.cpp
index 268b10ab444..f2f32b69fcc 100644
--- a/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.cpp
+++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.cpp
@@ -43,7 +43,8 @@ TAO_ESF_Copy_On_Write_Collection<COLLECTION,ITERATOR>::_decr_refcnt (void)
template<class PROXY, class COLLECTION, class ITERATOR, ACE_SYNCH_DECL>
TAO_ESF_Copy_On_Write<PROXY,COLLECTION,ITERATOR,ACE_SYNCH_USE>::
TAO_ESF_Copy_On_Write (void)
- : writing_ (0),
+ : pending_writes_ (0),
+ writing_ (0),
cond_ (mutex_)
{
ACE_NEW (this->collection_, Collection);
@@ -53,7 +54,13 @@ template<class PROXY, class COLLECTION, class ITERATOR, ACE_SYNCH_DECL>
TAO_ESF_Copy_On_Write<PROXY,COLLECTION,ITERATOR,ACE_SYNCH_USE>::
~TAO_ESF_Copy_On_Write (void)
{
+ ACE_GUARD (ACE_SYNCH_MUTEX_T, ace_mon, this->mutex_);
+
+ while (this->pending_writes_ != 0)
+ this->cond_.wait ();
+
this->collection_->_decr_refcnt ();
+ this->collection_ = 0;
}
template<class PROXY, class COLLECTION, class ITERATOR, ACE_SYNCH_DECL> void
@@ -79,6 +86,7 @@ TAO_ESF_Copy_On_Write<PROXY,C,I,ACE_SYNCH_USE>::
{
Write_Guard ace_mon (this->mutex_,
this->cond_,
+ this->pending_writes_,
this->writing_,
this->collection_);
@@ -93,6 +101,7 @@ TAO_ESF_Copy_On_Write<PROXY,C,I,ACE_SYNCH_USE>::
{
Write_Guard ace_mon (this->mutex_,
this->cond_,
+ this->pending_writes_,
this->writing_,
this->collection_);
@@ -107,6 +116,7 @@ TAO_ESF_Copy_On_Write<PROXY,C,I,ACE_SYNCH_USE>::
{
Write_Guard ace_mon (this->mutex_,
this->cond_,
+ this->pending_writes_,
this->writing_,
this->collection_);
@@ -117,10 +127,10 @@ template<class PROXY, class C, class I, ACE_SYNCH_DECL> void
TAO_ESF_Copy_On_Write<PROXY,C,I,ACE_SYNCH_USE>::
shutdown (CORBA::Environment &ACE_TRY_ENV)
{
- // @@ Do we really need to perform a copy here?
- // I believe so, but i don't have a good scenario for it.
+ // We need to perform a copy to follow the protocol.
Write_Guard ace_mon (this->mutex_,
this->cond_,
+ this->pending_writes_,
this->writing_,
this->collection_);
diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.h
index d90b8596a1a..e7fd96273af 100644
--- a/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.h
+++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.h
@@ -62,7 +62,7 @@ class TAO_ESF_Copy_On_Write_Read_Guard
public:
typedef TAO_ESF_Copy_On_Write_Collection<COLLECTION,ITERATOR> Collection;
TAO_ESF_Copy_On_Write_Read_Guard (ACE_LOCK &mutex,
- Collection*& collection);
+ Collection *&collection);
// Constructor
~TAO_ESF_Copy_On_Write_Read_Guard (void);
@@ -92,9 +92,10 @@ class TAO_ESF_Copy_On_Write_Write_Guard
public:
typedef TAO_ESF_Copy_On_Write_Collection<COLLECTION,ITERATOR> Collection;
TAO_ESF_Copy_On_Write_Write_Guard (ACE_SYNCH_MUTEX_T &mutex,
- ACE_SYNCH_CONDITION_T &cond,
- int &writing_flag,
- Collection*& collection);
+ ACE_SYNCH_CONDITION_T &cond,
+ int &pending_writes,
+ int &writing_flag,
+ Collection*& collection);
// Constructor
~TAO_ESF_Copy_On_Write_Write_Guard (void);
@@ -105,6 +106,7 @@ public:
private:
ACE_SYNCH_MUTEX_T &mutex;
ACE_SYNCH_CONDITION_T &cond;
+ int &pending_writes;
int &writing_flag;
Collection *&collection;
};
@@ -150,6 +152,9 @@ private:
ACE_SYNCH_MUTEX_T mutex_;
// A mutex to serialize access to the collection pointer.
+ int pending_writes_;
+ // Number of pending writes
+
int writing_;
// If non-zero then a thread is changing the collection. Many
// threads can use the collection simulatenously, but only one
diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.i b/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.i
index a4a30b965c1..12f8525ba09 100644
--- a/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.i
+++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.i
@@ -12,7 +12,7 @@ TAO_ESF_Copy_On_Write_Collection<COLLECTION,ITERATOR>::
template<class COLLECTION, class ITERATOR, class ACE_LOCK> ACE_INLINE
TAO_ESF_Copy_On_Write_Read_Guard<COLLECTION,ITERATOR,ACE_LOCK>::
TAO_ESF_Copy_On_Write_Read_Guard (ACE_LOCK &m,
- Collection*& collection_ref)
+ Collection*& collection_ref)
: collection (0),
mutex (m)
{
@@ -37,18 +37,22 @@ TAO_ESF_Copy_On_Write_Read_Guard<COLLECTION,ITERATOR,ACE_LOCK>::
template<class COLLECTION, class ITERATOR, ACE_SYNCH_DECL> ACE_INLINE
TAO_ESF_Copy_On_Write_Write_Guard<COLLECTION,ITERATOR,ACE_SYNCH_USE>::
TAO_ESF_Copy_On_Write_Write_Guard (ACE_SYNCH_MUTEX_T &m,
- ACE_SYNCH_CONDITION_T &c,
- int &w,
- Collection*& cr)
+ ACE_SYNCH_CONDITION_T &c,
+ int &p,
+ int &w,
+ Collection*& cr)
: copy (0),
mutex (m),
cond (c),
+ pending_writes (p),
writing_flag (w),
collection (cr)
{
{
ACE_GUARD (ACE_SYNCH_MUTEX_T, ace_mon, this->mutex);
+ this->pending_writes++;
+
while (this->writing_flag != 0)
this->cond.wait ();
@@ -58,7 +62,13 @@ TAO_ESF_Copy_On_Write_Write_Guard<COLLECTION,ITERATOR,ACE_SYNCH_USE>::
// Copy outside the mutex, because it may take a long time.
// Nobody can change it, because it is protected by the
// writing_flag.
- ACE_NEW (this->copy, Collection (*this->collection));
+
+ // First initialize it (with the correct reference count
+ ACE_NEW (this->copy, Collection);
+ // Copy the contents
+ this->copy->collection = this->collection->collection;
+
+ // Increase the reference counts
ITERATOR end = this->copy->collection.end ();
for (ITERATOR i = this->copy->collection.begin (); i != end; ++i)
{
@@ -77,6 +87,8 @@ TAO_ESF_Copy_On_Write_Write_Guard<COLLECTION,ITERATOR,ACE_SYNCH_USE>::
tmp = this->collection;
this->collection = this->copy;
this->writing_flag = 0;
+ this->pending_writes--;
+
this->cond.signal ();
}
// Delete outside the mutex, because it may take a long time.
diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.cpp
index bc73c7d56cd..61668be4601 100644
--- a/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.cpp
+++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.cpp
@@ -54,7 +54,8 @@ TAO_ESF_Delayed_Changes<PROXY,COLLECTION,ITERATOR,ACE_SYNCH_USE>::
{
worker->work (*i, ACE_TRY_ENV);
ACE_CHECK;
- }
+
+ }
}
template<class PROXY, class COLLECTION, class ITERATOR, ACE_SYNCH_DECL> int
diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.cpp
index 144f7ff7756..d44befa55c0 100644
--- a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.cpp
+++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.cpp
@@ -77,6 +77,9 @@ TAO_ESF_Proxy_Admin<EC,P,I>::disconnected (P *proxy,
CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC (())
{
+ proxy->deactivate (ACE_TRY_ENV);
+ ACE_CHECK; // Cannot happen, just following the discipline.
+
ACE_TRY
{
this->collection_->disconnected (proxy, ACE_TRY_ENV);
@@ -93,9 +96,6 @@ TAO_ESF_Proxy_Admin<EC,P,I>::disconnected (P *proxy,
// 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_List.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.cpp
index 5fd6f3adc5b..f1244c91cca 100644
--- a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.cpp
+++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.cpp
@@ -43,7 +43,10 @@ TAO_ESF_Proxy_List<PROXY>::reconnected (PROXY *proxy,
CORBA::Environment &)
{
int r = this->impl_.insert (proxy);
- if (r == 0 || r == 1)
+ if (r == 0)
+ return;
+
+ if (r == 1)
{
// Reference count is incremented by the callers to [re]connected.
// @@ Find out if the protocol could be simplified, and decoupling
diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RefCount_Guard.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RefCount_Guard.cpp
new file mode 100644
index 00000000000..83a1490530f
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RefCount_Guard.cpp
@@ -0,0 +1,27 @@
+// $Id$
+
+#ifndef TAO_ESF_PROXY_REFCOUNT_GUARD_CPP
+#define TAO_ESF_PROXY_REFCOUNT_GUARD_CPP
+
+#include "ESF_Proxy_RefCount_Guard.h"
+
+#if ! defined (__ACE_INLINE__)
+#include "ESF_Proxy_RefCount_Guard.i"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID(ESF, ESF_Proxy_RefCount_Guard, "$Id$")
+
+template<class EC, class P>
+TAO_ESF_Proxy_RefCount_Guard<EC,P>::~TAO_ESF_Proxy_RefCount_Guard (void)
+{
+ // Checking for 0 is safe, once the variable reaches 0 the value
+ // will stay there.
+ // @@ But what if the thread is switched to another processor just
+ // after release the mutex?
+ if (this->refcount_ == 0)
+ {
+ this->event_channel_->destroy_proxy (this->proxy_);
+ }
+}
+
+#endif /* TAO_ESF_PROXY_REFCOUNT_GUARD_CPP */
diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RefCount_Guard.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RefCount_Guard.h
new file mode 100644
index 00000000000..4ecc951fc8c
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RefCount_Guard.h
@@ -0,0 +1,79 @@
+/* -*- C++ -*- */
+// $Id$
+//
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS Event Service Framework
+//
+// = FILENAME
+// ESF_Proxy_RefCount_Guard
+//
+// = AUTHOR
+// Carlos O'Ryan (coryan@cs.wustl.edu)
+//
+// ============================================================================
+
+#ifndef TAO_ESF_PROXY_REFCOUNT_GUARD_H
+#define TAO_ESF_PROXY_REFCOUNT_GUARD_H
+
+#include "tao/corbafwd.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+template<class EVENT_CHANNEL, class PROXY>
+class TAO_ESF_Proxy_RefCount_Guard
+{
+ // = TITLE
+ // Reference count based guard.
+ //
+ // = DESCRIPTION
+ // A common idiom used on event services is to increment a
+ // reference count before starting a long running operation.
+ // The system can then execute the operation without any risk of
+ // having the underlying object destroyed. The advantage of using
+ // a reference count is that no mutex or lock needs to be held
+ // while the operation is beign executed.
+ // This class implements that common idiom, but it also adds hooks
+ // to handle scenarios where more than one operation is performed
+ // while holding the reference count.
+ //
+ // = TODO
+ // @@ The type of lock could be parametric
+ //
+public:
+ TAO_ESF_Proxy_RefCount_Guard (CORBA::ULong &refcount,
+ EVENT_CHANNEL *ec,
+ PROXY *proxy);
+ // Constructor
+
+ ~TAO_ESF_Proxy_RefCount_Guard (void);
+ // Destructor
+
+protected:
+ CORBA::ULong &refcount_;
+ // The reference count, if it gets to zero then the object must be
+ // destroyed
+
+ EVENT_CHANNEL *event_channel_;
+ // The event channel used to destroy the proxy
+
+ PROXY *proxy_;
+ // The proxy whose lifetime is controlled by the reference count
+};
+
+#if defined (__ACE_INLINE__)
+#include "ESF_Proxy_RefCount_Guard.i"
+#endif /* __ACE_INLINE__ */
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "ESF_Proxy_RefCount_Guard.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("ESF_Proxy_RefCount_Guard.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#endif /* TAO_ESF_PROXY_REFCOUNT_GUARD_H */
diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RefCount_Guard.i b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RefCount_Guard.i
new file mode 100644
index 00000000000..7639a89ee12
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RefCount_Guard.i
@@ -0,0 +1,12 @@
+// $Id$
+
+template<class EC, class P> ACE_INLINE
+TAO_ESF_Proxy_RefCount_Guard<EC,P>::
+ TAO_ESF_Proxy_RefCount_Guard (CORBA::ULong &refcount,
+ EC *ec,
+ P *proxy)
+ : refcount_ (refcount),
+ event_channel_ (ec),
+ proxy_ (proxy)
+{
+}
diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_RefCount_Guard.cpp b/TAO/orbsvcs/orbsvcs/ESF/ESF_RefCount_Guard.cpp
new file mode 100644
index 00000000000..432189332bb
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_RefCount_Guard.cpp
@@ -0,0 +1,14 @@
+// $Id$
+
+#ifndef TAO_ESF_REFCOUNT_GUARD_CPP
+#define TAO_ESF_REFCOUNT_GUARD_CPP
+
+#include "ESF_RefCount_Guard.h"
+
+#if ! defined (__ACE_INLINE__)
+#include "ESF_RefCount_Guard.i"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID(ESF, ESF_RefCount_Guard, "$Id$")
+
+#endif /* TAO_ESF_REFCOUNT_GUARD_CPP */
diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_RefCount_Guard.h b/TAO/orbsvcs/orbsvcs/ESF/ESF_RefCount_Guard.h
new file mode 100644
index 00000000000..05731bb9fa7
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_RefCount_Guard.h
@@ -0,0 +1,64 @@
+/* -*- C++ -*- */
+// $Id$
+//
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS Event Service Framework
+//
+// = FILENAME
+// ESF_RefCount_Guard
+//
+// = AUTHOR
+// Carlos O'Ryan (coryan@cs.wustl.edu)
+//
+// ============================================================================
+
+#ifndef TAO_ESF_REFCOUNT_GUARD_H
+#define TAO_ESF_REFCOUNT_GUARD_H
+
+#include "ace/OS.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+template<class T>
+class TAO_ESF_RefCount_Guard
+{
+ // = TITLE
+ // Reference count based guard.
+ //
+ // = DESCRIPTION
+ // A common idiom used on event services is to increment a
+ // reference count before starting a long running operation.
+ // The system can then execute the operation without any risk of
+ // having the underlying object destroyed. The advantage of using
+ // a reference count is that no mutex or lock needs to be held
+ // while the operation is beign executed.
+ //
+public:
+ TAO_ESF_RefCount_Guard (T &refcount);
+ // Constructor
+
+ ~TAO_ESF_RefCount_Guard (void);
+ // Destructor
+
+protected:
+ T &refcount_;
+ // The reference count
+};
+
+#if defined (__ACE_INLINE__)
+#include "ESF_RefCount_Guard.i"
+#endif /* __ACE_INLINE__ */
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "ESF_RefCount_Guard.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("ESF_RefCount_Guard.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#endif /* TAO_ESF_REFCOUNT_GUARD_H */
diff --git a/TAO/orbsvcs/orbsvcs/ESF/ESF_RefCount_Guard.i b/TAO/orbsvcs/orbsvcs/ESF/ESF_RefCount_Guard.i
new file mode 100644
index 00000000000..b69511a8382
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/ESF/ESF_RefCount_Guard.i
@@ -0,0 +1,16 @@
+// $Id$
+
+template<class T> ACE_INLINE
+TAO_ESF_RefCount_Guard<T>::
+ TAO_ESF_RefCount_Guard (T &refcount)
+ : refcount_ (refcount)
+{
+ this->refcount_++;
+}
+
+template<class T> ACE_INLINE
+TAO_ESF_RefCount_Guard<T>::
+ ~TAO_ESF_RefCount_Guard (void)
+{
+ this->refcount_--;
+}