diff options
author | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-04-18 16:12:29 +0000 |
---|---|---|
committer | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-04-18 16:12:29 +0000 |
commit | 0e2e2f96605b5c2e8127e6e8becb8ec3b672bcf5 (patch) | |
tree | 02983a2f269a9608879831e8dc037d2259a39deb /TAO/orbsvcs/orbsvcs/ESF | |
parent | d46a0d285ecec084ada0b132cf1d0bf09ad0a30e (diff) | |
download | ATCD-0e2e2f96605b5c2e8127e6e8becb8ec3b672bcf5.tar.gz |
ChangeLogTag:Tue Apr 18 08:52:27 2000 Carlos O'Ryan <coryan@uci.edu>
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/ESF')
-rw-r--r-- | TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.cpp | 16 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.h | 13 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/ESF/ESF_Copy_On_Write.i | 22 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/ESF/ESF_Delayed_Changes.cpp | 3 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_Admin.cpp | 6 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_List.cpp | 5 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RefCount_Guard.cpp | 27 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RefCount_Guard.h | 79 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/ESF/ESF_Proxy_RefCount_Guard.i | 12 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/ESF/ESF_RefCount_Guard.cpp | 14 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/ESF/ESF_RefCount_Guard.h | 64 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/ESF/ESF_RefCount_Guard.i | 16 |
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_--; +} |