summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcbeaulac <cbeaulac@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2010-04-17 17:19:29 +0000
committercbeaulac <cbeaulac@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2010-04-17 17:19:29 +0000
commitc63a521ce457dbba44c5d272e53675bbd891d774 (patch)
tree63f2ed1fc70851018e25ddf8752ce3c008b6c7a5
parentf3a83b0dbe837270f45c225ef697efad170fdc6b (diff)
downloadATCD-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.cpp80
-rw-r--r--ace/Service_Types.cpp30
-rw-r--r--ace/Service_Types.h23
-rw-r--r--ace/Service_Types.inl11
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