diff options
author | cbeaulac <cbeaulac@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2010-04-17 17:19:29 +0000 |
---|---|---|
committer | cbeaulac <cbeaulac@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2010-04-17 17:19:29 +0000 |
commit | c63a521ce457dbba44c5d272e53675bbd891d774 (patch) | |
tree | 63f2ed1fc70851018e25ddf8752ce3c008b6c7a5 | |
parent | f3a83b0dbe837270f45c225ef697efad170fdc6b (diff) | |
download | ATCD-c63a521ce457dbba44c5d272e53675bbd891d774.tar.gz |
Sat Apr 17 17:19:22 UTC 2010 Chad Beaulac <chad@objectivesolutions.com>
* ace/Service_Types.h
* ace/Service_Types.inl
* ace/Service_Types.cpp
Added service_type_ attr to expose the type of service being managed to the ACE_Service_Repository.
This allows the ASR to manage the lifecycle of the ACE_Module and ACE_Stream in order to
avoid a double delete of ACE_Module at shutdown.
Double delete of ACE_Module_Type is avoided by deleting the ACE_Module_Type in the
ACE_Stream_Type::fini method and not returning ACE_Service_Type_Impl::fini()
from ACE_Module_Type::fini(). Instead ACE_Module_Type::fini returns zero.
* ace/Service_Repository.cpp
Modified ASR::fini to iterate over the service_array_ twice. ACE_Service_Type::fini is called
on all ACE_Module_Type instances first. Then, fini is called on all ACE_Stream_Type and
ACE_Service_Object_Type instances in the order they appear in the service_array_.
This is a patch for Bugzilla #3334
-rw-r--r-- | ace/Service_Repository.cpp | 80 | ||||
-rw-r--r-- | ace/Service_Types.cpp | 30 | ||||
-rw-r--r-- | ace/Service_Types.h | 23 | ||||
-rw-r--r-- | ace/Service_Types.inl | 11 |
4 files changed, 108 insertions, 36 deletions
diff --git a/ace/Service_Repository.cpp b/ace/Service_Repository.cpp index 60f6b6fe831..48bf411784d 100644 --- a/ace/Service_Repository.cpp +++ b/ace/Service_Repository.cpp @@ -121,42 +121,76 @@ ACE_Service_Repository::fini (void) ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); int retval = 0; - // Do not be tempted to use the prefix decrement operator. Use // postfix decrement operator since the index is unsigned and may // wrap around the 0 - for (size_t i = this->service_array_.size(); i-- != 0; ) - { - // <fini> the services in reverse order. - ACE_Service_Type *s = - const_cast<ACE_Service_Type *> (this->service_array_[i]); + for (size_t i = this->service_array_.size (); i-- != 0;) + { + // <fini> the services in reverse order. + ACE_Service_Type *s = + const_cast<ACE_Service_Type *> (this->service_array_[i]); + if (s->type ()->service_type () == ACE_Service_Type::MODULE) + { #ifndef ACE_NLOGGING if (ACE::debug ()) - { - if (s != 0) - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d], ") - ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"), - this, - i, - s->name(), - s->type (), - (s->type () != 0) ? s->type ()->object () : 0, - s->active ())); - else - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] -> 0\n"), - this, - i)); - } + { + if (s != 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d], ") + ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"), + this, + i, + s->name (), + s->type (), + (s->type () != 0) ? s->type ()->object () : 0, + s->active ())); + else + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] -> 0\n"), + this, + i)); + } #endif // Collect any errors. if (s != 0) retval += s->fini (); } + } + for (size_t i = this->service_array_.size (); i-- != 0;) + { + // <fini> the services in reverse order. + ACE_Service_Type *s = + const_cast<ACE_Service_Type *> (this->service_array_[i]); + if (s->type ()->service_type () != ACE_Service_Type::MODULE) + { +#ifndef ACE_NLOGGING + if (ACE::debug ()) + { + if (s != 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d], ") + ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"), + this, + i, + s->name (), + s->type (), + (s->type () != 0) ? s->type ()->object () : 0, + s->active ())); + else + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] -> 0\n"), + this, + i)); + } +#endif + // Collect any errors. + if (s != 0) + retval += s->fini (); + } + } return (retval == 0) ? 0 : -1; } diff --git a/ace/Service_Types.cpp b/ace/Service_Types.cpp index 4552607640e..e05e2134a8f 100644 --- a/ace/Service_Types.cpp +++ b/ace/Service_Types.cpp @@ -35,11 +35,13 @@ ACE_Service_Type_Impl::dump (void) const ACE_Service_Type_Impl::ACE_Service_Type_Impl (void *so, const ACE_TCHAR *s_name, u_int f, - ACE_Service_Object_Exterminator gobbler) + ACE_Service_Object_Exterminator gobbler, + int stype) : name_ (0), obj_ (so), gobbler_ (gobbler), - flags_ (f) + flags_ (f), + service_type_ (stype) { ACE_TRACE ("ACE_Service_Type_Impl::ACE_Service_Type_Impl"); this->name (s_name); @@ -82,8 +84,9 @@ ACE_Service_Type_Impl::fini (void) const ACE_Service_Object_Type::ACE_Service_Object_Type (void *so, const ACE_TCHAR *s_name, u_int f, - ACE_Service_Object_Exterminator gobbler) - : ACE_Service_Type_Impl (so, s_name, f, gobbler) + ACE_Service_Object_Exterminator gobbler, + int stype) + : ACE_Service_Type_Impl (so, s_name, f, gobbler, stype) , initialized_ (-1) { ACE_TRACE ("ACE_Service_Object_Type::ACE_Service_Object_Type"); @@ -164,8 +167,9 @@ ACE_Module_Type::dump (void) const ACE_Module_Type::ACE_Module_Type (void *m, const ACE_TCHAR *m_name, - u_int f) - : ACE_Service_Type_Impl (m, m_name, f) + u_int f, + int stype) + : ACE_Service_Type_Impl (m, m_name, f, 0, stype) { ACE_TRACE ("ACE_Module_Type::ACE_Module_Type"); } @@ -230,7 +234,6 @@ int ACE_Module_Type::fini (void) const { ACE_TRACE ("ACE_Module_Type::fini"); - void *obj = this->object (); MT_Module *mod = (MT_Module *) obj; MT_Task *reader = mod->reader (); @@ -241,10 +244,15 @@ ACE_Module_Type::fini (void) const if (writer != 0) writer->fini (); + +#if 0 // Close the module and delete the memory. mod->close (MT_Module::M_DELETE); return ACE_Service_Type_Impl::fini (); + +#endif + return 0; } int @@ -324,8 +332,9 @@ ACE_Stream_Type::resume (void) const ACE_Stream_Type::ACE_Stream_Type (void *s, const ACE_TCHAR *s_name, - u_int f) - : ACE_Service_Type_Impl (s, s_name, f), + u_int f, + int stype) + : ACE_Service_Type_Impl (s, s_name, f, 0, stype), head_ (0) { ACE_TRACE ("ACE_Stream_Type::ACE_Stream_Type"); @@ -372,6 +381,9 @@ ACE_Stream_Type::fini (void) const // Finalize the Module (this may delete it, but we don't really // care since we don't access it again). m->fini (); + // This should be done in ACE_Module_Type::fini but that creates + // a double delete problem so we do it here. + delete m; m = t; } str->close (); diff --git a/ace/Service_Types.h b/ace/Service_Types.h index e741561d965..de442a6b431 100644 --- a/ace/Service_Types.h +++ b/ace/Service_Types.h @@ -43,7 +43,8 @@ public: ACE_Service_Type_Impl (void *object, const ACE_TCHAR *s_name, u_int flags = 0, - ACE_Service_Object_Exterminator gobbler = 0); + ACE_Service_Object_Exterminator gobbler = 0, + int stype = ACE_Service_Type::INVALID_TYPE); virtual ~ACE_Service_Type_Impl (void); // = Pure virtual interface (must be defined by the subclass). @@ -65,6 +66,12 @@ public: /// Dump the state of an object. void dump (void) const; + /// get the service_type of this service + int service_type (void) const; + + /// set the service_type of this service + void service_type (int stype); + /// Declare the dynamic allocation hooks. ACE_ALLOC_HOOK_DECLARE; @@ -81,6 +88,11 @@ protected: /// Flags that control serivce behavior (particularly deletion). u_int flags_; + + /// type of this service + /// Used to properly manage the lifecycle of ACE_Modules and ACE_Streams + /// during shutdown + int service_type_; }; /** @@ -96,7 +108,8 @@ public: ACE_Service_Object_Type (void *so, const ACE_TCHAR *name, u_int flags = 0, - ACE_Service_Object_Exterminator gobbler = 0); + ACE_Service_Object_Exterminator gobbler = 0, + int stype = ACE_Service_Type::SERVICE_OBJECT); ~ACE_Service_Object_Type (void); @@ -124,7 +137,8 @@ public: // = Initialization method. ACE_Module_Type (void *m, // Really an ACE_Module *. const ACE_TCHAR *identifier, - u_int flags = 0); + u_int flags = 0, + int stype = ACE_Service_Type::MODULE); ~ACE_Module_Type (void); @@ -164,7 +178,8 @@ public: // = Initialization method. ACE_Stream_Type (void *s, // Really an ACE_Stream *. const ACE_TCHAR *identifier, - u_int flags = 0); + u_int flags = 0, + int stype = ACE_Service_Type::STREAM); ~ACE_Stream_Type (void); diff --git a/ace/Service_Types.inl b/ace/Service_Types.inl index 9ebfd705ced..02b2d3c6c41 100644 --- a/ace/Service_Types.inl +++ b/ace/Service_Types.inl @@ -29,4 +29,15 @@ ACE_Service_Type_Impl::name (const ACE_TCHAR *n) this->name_ = ACE::strnew (n); } +ACE_INLINE int +ACE_Service_Type_Impl::service_type (void) const +{ + return service_type_; +} + +ACE_INLINE void +ACE_Service_Type_Impl::service_type (int stype) +{ + service_type_ = stype; +} ACE_END_VERSIONED_NAMESPACE_DECL |