summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcbeaulac <cbeaulac@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2008-10-10 13:52:57 +0000
committercbeaulac <cbeaulac@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2008-10-10 13:52:57 +0000
commit6f1d1712af4f502bf20b37caa9de3d885a222f05 (patch)
tree7e2bab579dbb8f21540189fb19c2b66530886e6f
parent11346eac5b83d49538f8b74efe1638d03547d60d (diff)
downloadATCD-6f1d1712af4f502bf20b37caa9de3d885a222f05.tar.gz
Mods for Bugzilla #3334. Chagnes ensure that ACE_Streams are deleted before ACE_Modules and the lifecycle of ACE_Modules is managed by ACE_Streams
-rw-r--r--ace/Service_Object.cpp34
-rw-r--r--ace/Service_Object.h4
-rw-r--r--ace/Service_Repository.cpp120
-rw-r--r--ace/Service_Types.cpp45
-rw-r--r--ace/Service_Types.h23
-rw-r--r--ace/Service_Types.inl12
6 files changed, 177 insertions, 61 deletions
diff --git a/ace/Service_Object.cpp b/ace/Service_Object.cpp
index f3ca42b25f3..9f3aa8e527f 100644
--- a/ace/Service_Object.cpp
+++ b/ace/Service_Object.cpp
@@ -119,6 +119,40 @@ ACE_Service_Type::fini (void)
}
int
+ACE_Service_Type::fini_delete (void)
+{
+ if (ACE::debug ())
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ACE (%P|%t) ST::fini_delete - destroying name=%s, dll=%s\n"),
+ this->name_,
+ this->dll_.dll_name_));
+
+ if (this->fini_already_called_)
+ return 0;
+
+ this->fini_already_called_ = true;
+
+ if (this->type_ == 0)
+ {
+ // Returning 1 currently only makes sense for dummy instances, used
+ // to "reserve" a spot (kind of like forward-declarations) for a
+ // dynamic service. This is necessary to help enforce the correct
+ // finalization order, when such service also has any (dependent)
+ // static services
+
+ return 1; // No implementation was found.
+ }
+
+ int ret = this->type_->fini_delete ();
+
+ // Ensure that closing the DLL is done after type_->fini() as it may
+ // require access to the code for the service object destructor,
+ // which resides in the DLL
+ return (ret | this->dll_.close());
+
+}
+
+int
ACE_Service_Type::suspend (void) const
{
ACE_TRACE ("ACE_Service_Type::suspend");
diff --git a/ace/Service_Object.h b/ace/Service_Object.h
index 10f733fe54e..f3444a7b9f1 100644
--- a/ace/Service_Object.h
+++ b/ace/Service_Object.h
@@ -119,6 +119,10 @@ public:
/// Calls <fini> on <type_>
int fini (void);
+ /// Calls <fini_delete> on <type_>. Only used on ACE_Module_Type instances to cleanup
+ /// during shutdown.
+ int fini_delete (void);
+
/// Check if the service has been fini'ed.
bool fini_called (void) const;
diff --git a/ace/Service_Repository.cpp b/ace/Service_Repository.cpp
index e8aae6dd649..0bd7a8d8fba 100644
--- a/ace/Service_Repository.cpp
+++ b/ace/Service_Repository.cpp
@@ -131,8 +131,11 @@ ACE_Service_Repository::ACE_Service_Repository (size_t size)
ACE_TEXT ("ACE_Service_Repository")));
}
-// Finalize (call <fini> and possibly delete) all the services.
+// Finalize (call <fini> and possibly delete) all the services.
+// ACE_Stream_Types instances are closed first to get ACE_Module cleanup to occur first.
+// Then, ACE_Service_Type and ACE_Module_Type instances are finalized.
+// <fini_delete> is called on ACE_Module_Type(s) only to perform cleanup.
int
ACE_Service_Repository::fini (void)
{
@@ -143,47 +146,96 @@ ACE_Service_Repository::fini (void)
return 0;
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->current_size_; i-- != 0; )
+
+ bool removeStreams = true;
+ for (int i = 0; i < 2; i++)
{
- // <fini> the services in reverse order.
- ACE_Service_Type *s =
- const_cast<ACE_Service_Type *> (this->service_vector_[i]);
-
-#ifndef ACE_NLOGGING
- if (ACE::debug ())
+ if (i == 1)
{
- if (s != 0)
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] (%d), ")
- ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"),
- this,
- i,
- this->total_size_,
- 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] (%d) -> 0\n"),
- this,
- i,
- this->total_size_));
+ removeStreams = false;
}
+ // 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->current_size_; i-- != 0;)
+ {
+ // <fini> the services in reverse order.
+ ACE_Service_Type *s =
+ const_cast<ACE_Service_Type *> (this->service_vector_[i]);
+
+ if (s != 0)
+ {
+ if (s->type()->service_type() == ACE_Service_Type::STREAM && removeStreams)
+ {
+#ifndef ACE_NLOGGING
+ if (ACE::debug())
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT("ACE (%P|%t) SR::fini, repo=%@ [%d] (%d), ")
+ ACE_TEXT("name=%s, type=%@, object=%@, active=%d\n"),
+ this,
+ i,
+ this->total_size_,
+ s->name(),
+ s->type(),
+ (s->type() != 0) ? s->type()->object() : 0,
+ s->active()));
+ }
#endif
-
- // Collect any errors.
- if (s != 0)
- retval += s->fini ();
+
+ retval += s->fini();
+ }
+
+ if (s->type()->service_type() != ACE_Service_Type::STREAM && !removeStreams)
+ {
+ if (s->type()->service_type() == ACE_Service_Type::MODULE)
+ {
+#ifndef ACE_NLOGGING
+ if (ACE::debug())
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT("ACE (%P|%t) SR::fini_delete, repo=%@ [%d] (%d), ")
+ ACE_TEXT("name=%s, type=%@, object=%@, active=%d\n"),
+ this,
+ i,
+ this->total_size_,
+ s->name(),
+ s->type(),
+ (s->type() != 0) ? s->type()->object() : 0,
+ s->active()));
+ }
+#endif
+ retval += s->fini_delete();
+ }
+ else
+ {
+#ifndef ACE_NLOGGING
+ if (ACE::debug())
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT("ACE (%P|%t) SR::fini, repo=%@ [%d] (%d), ")
+ ACE_TEXT("name=%s, type=%@, object=%@, active=%d\n"),
+ this,
+ i,
+ this->total_size_,
+ s->name(),
+ s->type(),
+ (s->type() != 0) ? s->type()->object() : 0,
+ s->active()));
+ }
+#endif
+ retval += s->fini();
+ }
+ }
+
+ }
+ }
}
-
+
return (retval == 0) ? 0 : -1;
}
+
// Close down all the services.
int
diff --git a/ace/Service_Types.cpp b/ace/Service_Types.cpp
index ce5d0bb9a52..684c0de6ac7 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);
@@ -79,11 +81,19 @@ ACE_Service_Type_Impl::fini (void) const
return 0;
}
+int
+ACE_Service_Type_Impl::fini_delete (void) const
+{
+ ACE_TRACE ("ACE_Service_Type_Impl::fini_delete");
+ return ACE_Service_Type_Impl::fini ();
+}
+
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 +174,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,21 +241,8 @@ 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 ();
- MT_Task *writer = mod->writer ();
-
- if (reader != 0)
- reader->fini ();
-
- if (writer != 0)
- writer->fini ();
-
- // Close the module and delete the memory.
- mod->close (MT_Module::M_DELETE);
- return ACE_Service_Type_Impl::fini ();
+ // ACE_Module_Type(s) get deleted by fini_delete Bugzilla #3334
+ return 0;
}
int
@@ -324,8 +322,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");
diff --git a/ace/Service_Types.h b/ace/Service_Types.h
index fccf76b5f02..eed14e8ed2f 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).
@@ -51,6 +52,7 @@ public:
virtual int resume (void) const = 0;
virtual int init (int argc, ACE_TCHAR *argv[]) const = 0;
virtual int fini (void) const;
+ virtual int fini_delete (void) const;
virtual int info (ACE_TCHAR **str, size_t len) const = 0;
/// The pointer to the service.
@@ -65,6 +67,10 @@ public:
/// Dump the state of an object.
void dump (void) const;
+ /// Getter and setter for service_type_.
+ int service_type(void) const;
+ void service_type(int stype);
+
/// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
@@ -81,6 +87,11 @@ protected:
/// Flags that control serivce behavior (particularly deletion).
u_int flags_;
+
+ /// Stores the enum that represents the concrete type of this ACE_Service_Type_Impl.
+ /// Possible values are ACE_Service_Type::SERVICE_OBJECT, ACE_Service_Type::MODULE, and
+ /// ACE_Service_Type::STREAM.
+ int service_type_;
};
/**
@@ -96,7 +107,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 +136,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 +177,9 @@ 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..f91e7716c2e 100644
--- a/ace/Service_Types.inl
+++ b/ace/Service_Types.inl
@@ -29,4 +29,16 @@ 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