summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriliyan <iliyan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2007-02-13 17:18:59 +0000
committeriliyan <iliyan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2007-02-13 17:18:59 +0000
commitde68c990dc9a25bcf050412c23fa5983b7e9a7d5 (patch)
treee61fb67b8e973b401eb9e34061f65e1276481c2d
parentb5e4fa24bc319330b2980bf988e41cc4b2f4bb15 (diff)
downloadATCD-de68c990dc9a25bcf050412c23fa5983b7e9a7d5.tar.gz
ChangeLogTag: Tue Feb 13 15:35:54 UTC 2007 Iliyan Jeliazkov <iliyan@ociweb.com>
-rw-r--r--ACE/ChangeLog19
-rw-r--r--ACE/ace/Dynamic_Service_Base.cpp8
-rw-r--r--ACE/ace/Dynamic_Service_Dependency.cpp2
-rw-r--r--ACE/ace/Service_Config.cpp136
-rw-r--r--ACE/ace/Service_Config.h93
-rw-r--r--ACE/ace/Service_Config.inl41
-rw-r--r--ACE/ace/Service_Gestalt.cpp229
7 files changed, 299 insertions, 229 deletions
diff --git a/ACE/ChangeLog b/ACE/ChangeLog
index ebec87b0461..b160b912277 100644
--- a/ACE/ChangeLog
+++ b/ACE/ChangeLog
@@ -1,3 +1,22 @@
+Tue Feb 13 15:35:54 UTC 2007 Iliyan Jeliazkov <iliyan@ociweb.com>
+
+ * ace/Service_Config.{h,inl,cpp}:
+
+ Refactoring to simplify the TSS usage, reduce overhead and
+ eliminate a memory leak.
+
+ * ace/Service_Gestalt.cpp:
+
+ Fixed a memory leak in Service_Type_Dynamic_Guard dtor. Updated
+ logging.
+
+ * ace/Dynamic_Service_Base.cpp:
+ * ace/Dynamic_Service_Dependency.cpp:
+
+ Updated to use SC::instance () to better express the contract
+ for these classes. They simply don't need to be aware whether
+ they are using a global, or a TSS-local gestalt .
+
Tue Feb 13 14:44:06 UTC 2007 Johnny Willemsen <jwillemsen@remedy.nl>
* ace/config-vxworks5.x.h:
diff --git a/ACE/ace/Dynamic_Service_Base.cpp b/ACE/ace/Dynamic_Service_Base.cpp
index cc5e9114871..94400ddffdc 100644
--- a/ACE/ace/Dynamic_Service_Base.cpp
+++ b/ACE/ace/Dynamic_Service_Base.cpp
@@ -32,7 +32,7 @@ void *
ACE_Dynamic_Service_Base::instance (const ACE_TCHAR *name, bool no_global)
{
ACE_TRACE ("ACE_Dynamic_Service_Base::instance");
- return instance (ACE_Service_Config::current (), name, no_global);
+ return instance (ACE_Service_Config::instance (), name, no_global);
}
@@ -40,7 +40,7 @@ void *
ACE_Dynamic_Service_Base::instance (const ACE_TCHAR *name)
{
ACE_TRACE ("ACE_Dynamic_Service_Base::instance");
- return instance (ACE_Service_Config::current (), name, false);
+ return instance (ACE_Service_Config::instance (), name, false);
}
@@ -49,14 +49,14 @@ ACE_Dynamic_Service_Base::instance (const ACE_TCHAR *name)
const ACE_Service_Type *
ACE_Dynamic_Service_Base::find_i (const ACE_Service_Gestalt* &repo,
const ACE_TCHAR *name,
- bool no_global)
+ bool local_only)
{
ACE_TRACE ("ACE_Dynamic_Service_Base::find_i");
const ACE_Service_Type *svc_rec = 0;
ACE_Service_Gestalt* global = ACE_Service_Config::global ();
- for ( ; (repo->find (name, &svc_rec) == -1) && !no_global; repo = global)
+ for ( ; (repo->find (name, &svc_rec) == -1) && !local_only; repo = global)
{
// Check the static repo, too if different
if (repo == global)
diff --git a/ACE/ace/Dynamic_Service_Dependency.cpp b/ACE/ace/Dynamic_Service_Dependency.cpp
index f2a9b45d61c..a2c25c2e6bf 100644
--- a/ACE/ace/Dynamic_Service_Dependency.cpp
+++ b/ACE/ace/Dynamic_Service_Dependency.cpp
@@ -14,7 +14,7 @@ ACE_RCSID (ace,
ACE_Dynamic_Service_Dependency::ACE_Dynamic_Service_Dependency (const ACE_TCHAR *principal)
{
- this->init (ACE_Service_Config::current (), principal);
+ this->init (ACE_Service_Config::instance (), principal);
}
ACE_Dynamic_Service_Dependency::ACE_Dynamic_Service_Dependency (const ACE_Service_Gestalt *cfg,
diff --git a/ACE/ace/Service_Config.cpp b/ACE/ace/Service_Config.cpp
index 2a564868937..ab9c2c440d2 100644
--- a/ACE/ace/Service_Config.cpp
+++ b/ACE/ace/Service_Config.cpp
@@ -30,15 +30,16 @@ ACE_RCSID (ace,
///
ACE_Service_Config_Guard::ACE_Service_Config_Guard (ACE_Service_Gestalt * psg)
- : saved_ (ACE_Service_Config::current ())
+ : saved_ (ACE_Service_Config::instance ())
{
if (ACE::debug ())
ACE_DEBUG ((LM_DEBUG,
- ACE_LIB_TEXT ("(%P|%t) SCG::ctor, repo=%@ - guard with %@\n"),
+ ACE_LIB_TEXT ("ACE (%P|%t) Service_Config_Guard:<ctor>")
+ ACE_LIB_TEXT (" - repo=%@ superceded by repo=%@\n"),
this->saved_->repo_,
psg->repo_));
- // Modify the TSS - no locking needed
+ // Modify the TSS if the repo has changed
if (saved_ != psg)
(void)ACE_Service_Config::current (psg);
}
@@ -50,7 +51,8 @@ ACE_Service_Config_Guard::~ACE_Service_Config_Guard (void)
if (ACE::debug ())
ACE_DEBUG ((LM_DEBUG,
- ACE_LIB_TEXT ("(%P|%t) SCG::dtor, repo=%@ - un-guard\n"),
+ ACE_LIB_TEXT ("ACE (%P|%t) Service_Config_Guard:<dtor>")
+ ACE_LIB_TEXT (" - new repo=%@\n"),
this->saved_->repo_));
}
@@ -75,6 +77,25 @@ int ACE_Service_Config::be_a_daemon_ = 0;
int ACE_Service_Config::signum_ = SIGHUP;
+///
+ACE_Service_Config::TSS_Resources::TSS_Resources (void)
+ : ptr_ (ACE_Service_Config::global())
+{
+}
+
+///
+ACE_Service_Gestalt *ACE_Service_Config::TSS_Resources::ptr () const
+{
+ return ptr_;
+}
+
+///
+ACE_Service_Gestalt *ACE_Service_Config::TSS_Resources::ptr (ACE_Service_Gestalt *n)
+{
+ return ptr_ = n;
+}
+
+
void
ACE_Service_Config::dump (void) const
{
@@ -287,102 +308,6 @@ ACE_Service_Config::open_i (const ACE_TCHAR program_name[],
ignore_debug_flag);
}
-/// Return the global configuration instance. Allways returns the same
-/// instance
-ACE_Service_Gestalt *
-ACE_Service_Config::global (void)
-{
- return ACE_Singleton<ACE_Service_Config, ACE_SYNCH_MUTEX>::instance ();
-}
-
-
-///
-ACE_Service_Gestalt *
-ACE_Service_Config::instance (void)
-{
- return ACE_Service_Config::current ();
-}
-
-
-// A thread-specific storage to keep a pointer to the (current) global
-// configuration. Using a pointer to avoid the order of initialization
-// debacle possible when using static class instances. The memory is
-// dynamicaly allocated and leaked from current()
-
-/// Provides access to the static ptr, containing the TSS
-/// accessor. Ensures the desired order of initialization, even when
-/// other static initializers need the value.
-ACE_Service_Config::TSS_Service_Gestalt_Ptr *
-ACE_Service_Config::impl_ (void)
-{
- /// A "straight" static ptr does not work in static builds, because
- /// some static initializer may call current() method and assign
- /// value to instance_ *before* the startup code has had a chance to
- /// initialize it . This results in instance_ being "zeroed" out
- /// after it was assigned the correct value. Having a method scoped
- /// static guarantees that the first time the method is invoked, the
- /// instance_ will be initialized before returning.
-
- static TSS_Service_Gestalt_Ptr * instance_ = 0;
-
- // We can't possibly rely on ACE_STATIC_OBJECT_LOCK or any other
- // object that may be managed by the Object Manager. It is very
- // likely we are called in a static initializer context, before the
- // ACE_Object_Manager has been instantiated. This of course only
- // matters for threaded environments.
- ACE_MT (static ACE_SYNCH_RECURSIVE_MUTEX guardian_);
-
- if (instance_ == 0)
- {
- // TSS not initialized yet - first thread to hit this, so doing
- // the double-checked locking thing
- ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
- guardian_, 0));
-
- if (instance_ == 0)
- ACE_NEW_RETURN (instance_,
- TSS_Service_Gestalt_Ptr,
- 0);
- }
-
- return instance_;
-}
-
-/// Return the configuration instance, considered "global" in the
-/// current thread. This may be the same as instance(), but on some
-/// occasions, it may be a different one. For example,
-/// ACE_Service_Config_Guard provides a way of temporarily replacing
-/// the "current" configuration instance in the context of a thread.
-ACE_Service_Gestalt *
-ACE_Service_Config::current (void)
-{
- TSS_Service_Gestalt_Ptr * const impl = ACE_Service_Config::impl_ ();
- if (impl == 0)
- return 0;
-
- ACE_Service_Gestalt* & gestalt = ACE_TSS_GET (impl, TSS_Resources)->ptr_;
-
- if (gestalt == 0)
- gestalt = ACE_Service_Config::global ();
-
- return gestalt;
-}
-
-/// A mutator to set the "current" (TSS) gestalt instance.
-ACE_Service_Gestalt*
-ACE_Service_Config::current (ACE_Service_Gestalt *newcurrent)
-{
- TSS_Service_Gestalt_Ptr * const impl = ACE_Service_Config::impl_ ();
- if (impl == 0)
- return 0;
-
- ACE_Service_Gestalt* & gestalt = ACE_TSS_GET (impl, TSS_Resources)->ptr_;
-
- gestalt = newcurrent;
-
- return gestalt;
-}
-
// This method has changed to return the gestalt instead of the
// container, underlying the service repository and defined
// ACE_Service_Gestalt::insert (ACE_Static_Svc_Descriptor*). This way
@@ -394,14 +319,14 @@ ACE_Service_Config::current (ACE_Service_Gestalt *newcurrent)
ACE_Service_Gestalt *
ACE_Service_Config::static_svcs (void)
{
- return ACE_Service_Config::current ();
+ return ACE_Service_Config::instance ();
}
///
int
ACE_Service_Config::insert (ACE_Static_Svc_Descriptor* stsd)
{
- return ACE_Service_Config::current ()->insert (stsd);
+ return ACE_Service_Config::instance ()->insert (stsd);
}
@@ -574,12 +499,15 @@ ACE_Service_Config::reconfigure (void)
int
ACE_Service_Config::close (void)
{
- int result1 = ACE_Service_Config::current ()->close ();
+ int result1 = ACE_Service_Config::instance ()->close ();
// Delete the service repository. All the objects inside the
// service repository should already have been finalized.
int result2 = ACE_Service_Config::close_svcs ();
+ // Do away with the Singleton
+ ACE_SERVICE_CONFIG_SINGLETON::close ();
+
return (result1 | result2);
}
@@ -589,7 +517,7 @@ ACE_Service_Config::close_svcs (void)
ACE_TRACE ("ACE_Service_Config::close_svcs");
ACE_Service_Repository::close_singleton ();
- ACE_Service_Config::current (0);
+ ACE_Service_Config::current (global ());
return 0;
}
diff --git a/ACE/ace/Service_Config.h b/ACE/ace/Service_Config.h
index 6c7b87427e1..c0cbe2ef473 100644
--- a/ACE/ace/Service_Config.h
+++ b/ACE/ace/Service_Config.h
@@ -213,49 +213,70 @@ protected:
private:
- /// A Wrapper for the TSS-stored pointer.
- struct TSS_Resources {
- TSS_Resources (void) : ptr_ (0) {}
+ /**
+ * @c ACE_Service_Config is supposed to be a Singleton. This is the
+ * only Configuration Gestalt available for access from static
+ * initializers at proces start-up time. Using Unmanaged Singleton
+ * makes it safe since OM may not yet be fully initialized in the
+ * context of a static initializer that uses SC, and also because we
+ * know that upon process exit, the SC will be explicitely closed
+ * (in the @c ACE_Object_Manager::fini()).
+ */
+ typedef ACE_Unmanaged_Singleton<ACE_Service_Config,
+ ACE_SYNCH_RECURSIVE_MUTEX> ACE_SERVICE_CONFIG_SINGLETON;
+
+ /**
+ * A Wrapper for the TSS-stored pointer to the "current"
+ * configuration Gestalt. Static initializers from any DLL loaded
+ * through the SC will find the SC instance through the TSS pointer,
+ * instead of the global singleton. This makes it possible to ensure
+ * that the new services are loaded in the correct Gestalt,
+ * independent of which thread is actually using the SC at the time
+ * to do so.
+ */
+ class TSS_Resources
+ {
+ public:
+ TSS_Resources (void);
+ ACE_Service_Gestalt *ptr () const;
+ ACE_Service_Gestalt *ptr (ACE_Service_Gestalt *n);
+ private:
ACE_Service_Gestalt *ptr_;
};
-
- /// A type for the TSS-stored resources. The typedef helps to
- /// abstract from the particularities of single-threaded vs
- /// multi-threaded environments.
- typedef ACE_TSS_TYPE (ACE_Service_Config::TSS_Resources) TSS_Service_Gestalt_Ptr;
-
- /// Provides access to the static ptr, containing the TSS
- /// accessor. Ensures the desired order of initialization, even when
- /// other static initializers need the value.
- static TSS_Service_Gestalt_Ptr * impl_ (void);
-
-protected:
-
- /// Mutator to set the (TSS) global instance. Intended for use by helper
- /// classes, like ACE_Service_Config_Guard which when instantiated on the
- /// stack, can temporarily change which gestalt instance is viewed as
- /// global from the point of view of the static initializers in DLLs.
- static ACE_Service_Gestalt* current (ACE_Service_Gestalt*);
-
+
+ ACE_TSS_TYPE (TSS_Resources) tss_;
+
public:
-
- /// If not yet initialized, creates a process-wide instance
- /// global instance, which is registered with the ACE_Object_Manager,
- /// via ACE_Singleton. Note that this is allways the same instance,
- /// in contrast with current (), which may be different instance at
- /// different times, dependent on the context.
+ /**
+ * Mutator to set the (TSS) global instance. Intended for use by
+ * helper classes like @see ACE_Service_Config_Guard. Stack-based
+ * instances of it can temporarily change which Gestalt is
+ * considered global by any static initializer (especially those in
+ * DLLs, loaded at run-time).
+ */
+ static ACE_Service_Gestalt* current (ACE_Service_Gestalt*);
+
+ /**
+ * Returns a process-wide global singleton instance in contrast with
+ * current (), which may return a different instance at different
+ * times, dependent on the context. Use of this method is
+ * discouraged as it allows circumvention of the mechanism for
+ * dynamically loading services. Use with extreme caution!
+ */
static ACE_Service_Gestalt* global (void);
- /// Accessor for the "current" service repository through a pointer
- /// held in TSS.
+ /// Accessor for the "current" service gestalt
static ACE_Service_Gestalt* current (void);
- /// This is what the static service initializators are hard-wired
- /// to use, so in order to keep interface changes to a minimum this
- /// method merely forwards to current(). Thus it is possible to
- /// temporarily replace what those initializers think is the global
- /// service repository, for instance when dynamically loading a
- /// service from a DLL, which in turn, contains its own static services.
+ /**
+ * This is what the static service initializators are hard-wired to
+ * use, so in order to avoid interface changes this method merely
+ * forwards to @c ACE_Service_Config::current. This enables us to
+ * enforce which Service Gestalt is used for services registering
+ * through static initializers. Especially important for DLL-based
+ * dynamic services, which can contain their own static services and
+ * static initializers.
+ */
static ACE_Service_Gestalt* instance (void);
/**
diff --git a/ACE/ace/Service_Config.inl b/ACE/ace/Service_Config.inl
index 895c2340232..c0cd157d566 100644
--- a/ACE/ace/Service_Config.inl
+++ b/ACE/ace/Service_Config.inl
@@ -51,6 +51,47 @@ ACE_Service_Config::parse_args (int argc, ACE_TCHAR *argv[])
return ACE_Service_Config::current ()->parse_args (argc, argv);
}
+
+/// Return the global configuration instance. Allways returns the same
+/// instance
+ACE_INLINE ACE_Service_Gestalt *
+ACE_Service_Config::global (void)
+{
+ return ACE_SERVICE_CONFIG_SINGLETON::instance ();
+}
+
+
+/// Return the configuration instance, considered "global" in the
+/// current thread. This may be the same as instance(), but on some
+/// occasions, it may be a different one. For example,
+/// ACE_Service_Config_Guard provides a way of temporarily replacing
+/// the "current" configuration instance in the context of a thread.
+ACE_INLINE ACE_Service_Gestalt *
+ACE_Service_Config::instance (void)
+{
+ return ACE_SERVICE_CONFIG_SINGLETON::instance ()->tss_->ptr ();
+}
+
+
+/// Return the configuration instance, considered "global" in the
+/// current thread. This may be the same as instance(), but on some
+/// occasions, it may be a different one. For example,
+/// ACE_Service_Config_Guard provides a way of temporarily replacing
+/// the "current" configuration instance in the context of a thread.
+ACE_INLINE ACE_Service_Gestalt *
+ACE_Service_Config::current (void)
+{
+ return ACE_SERVICE_CONFIG_SINGLETON::instance ()->tss_->ptr ();
+}
+
+/// A mutator to set the "current" (TSS) gestalt instance.
+ACE_INLINE ACE_Service_Gestalt*
+ACE_Service_Config::current (ACE_Service_Gestalt *newcurrent)
+{
+ return ACE_SERVICE_CONFIG_SINGLETON::instance ()->tss_->ptr (newcurrent);
+}
+
+
// Compare two service descriptors for equality.
ACE_INLINE bool
diff --git a/ACE/ace/Service_Gestalt.cpp b/ACE/ace/Service_Gestalt.cpp
index 8b6eeb9fc97..90f7a7b49e5 100644
--- a/ACE/ace/Service_Gestalt.cpp
+++ b/ACE/ace/Service_Gestalt.cpp
@@ -104,118 +104,180 @@ ACE_Service_Type_Dynamic_Guard::ACE_Service_Type_Dynamic_Guard
#endif
{
ACE_ASSERT (this->name_ != 0); // No name?
- ACE_NEW_NORETURN (this->dummy_, // Allocate the forward declaration ...
+
+ // Heap-allocate the forward declaration because that's where the
+ // repository exects them to be ...
+ ACE_NEW_NORETURN (this->dummy_,
ACE_Service_Type (this->name_, // ... use the same name
0, // ... inactive
this->dummy_dll_, // ... bogus ACE_DLL
0)); // ... no type_impl
- ACE_ASSERT (this->dummy_ != 0); // No memory?
-
+#ifndef ACE_NLOGGING
if(ACE::debug ())
ACE_DEBUG ((LM_DEBUG,
- ACE_LIB_TEXT ("ACE (%P|%t) STDG::<ctor>, repo=%@ [%d], ")
- ACE_LIB_TEXT ("name=%s, type=%@, impl=%@, object=%@, active=%d - inserting dummy forward\n"),
- &this->repo_, this->repo_begin_, this->name_, this->dummy_,
+ ACE_LIB_TEXT ("ACE (%P|%t) Service_Type_Dynamic_Guard")
+ ACE_LIB_TEXT (":<ctor> - new fwd decl")
+ ACE_LIB_TEXT (", repo[%d]=%@, name=%s, type=%@")
+ ACE_LIB_TEXT (", impl=%@, object=%@, active=%d\n"),
+ this->repo_begin_,
+ &this->repo_,
+ this->name_,
+ this->dummy_,
this->dummy_->type (),
- (this->dummy_->type () != 0) ? this->dummy_->type ()->object () : 0,
+ (this->dummy_->type () != 0)
+ ? this->dummy_->type ()->object ()
+ : 0,
this->dummy_->active ()));
+#endif /* ACE_NLOGGING */
+
+ // No memory ...
+ if (this->dummy_ == 0)
+ return;
// Note that the dummy_'s memory may be deallocated between invoking
- // the ctor and dtor, if the expected ("real") dynamic service is
+ // the ctor and dtor. For example, if the real dynamic service is
// inserted in the repository. See how this affects the destructor's
// behavior, below.
- this->repo_.insert (this->dummy_);
+ if (this->repo_.insert (this->dummy_) != 0)
+ {
+ delete this->dummy_;
+ this->dummy_ = 0;
+ };
}
/// Destructor
-
ACE_Service_Type_Dynamic_Guard::~ACE_Service_Type_Dynamic_Guard (void)
{
- const ACE_Service_Type *tmp = 0;
-
- // Lookup without ignoring suspended services. Making sure
- // not to ignore any inactive services, since those may be forward
+ // Lookup without ignoring suspended services. Making sure not to
+ // ignore any inactive services, since those may be forward
// declarations
size_t slot = 0;
+ const ACE_Service_Type *tmp = 0;
int const ret = this->repo_.find_i (this->name_, slot, &tmp, false);
// We inserted it (as inactive), so we expect to find it, right?
if (ret < 0 && ret != -2)
{
+#ifndef ACE_NLOGGING
if (ACE::debug ())
ACE_ERROR ((LM_WARNING,
- ACE_LIB_TEXT ("ACE (%P|%t) STDG::<dtor> - Failed (%d) to find %s\n"),
- ret, this->name_));
- return;
- }
-
- if (tmp != 0 && tmp->type () != 0)
- {
- // Something has registered a proper (non-forward-decl) service with
- // the same name as our dummy.
-
- if(ACE::debug ())
- ACE_DEBUG ((LM_DEBUG,
- ACE_LIB_TEXT ("ACE (%P|%t) STDG::<dtor>, repo=%@, name=%s - updating [%d - %d]\n"),
- &this->repo_,
- this->name_,
- this->repo_begin_,
- this->repo_.current_size ()));
-
- // Relocate any static services. If any have been registered in
- // the context of this guard, those really aren't static
- // services because their code is in the DLL's code segment
- this->repo_.relocate_i (this->repo_begin_, this->repo_.current_size (), tmp->dll());
-
- // The ACE_Service_Gestalt::insert() modifies the memory for the
- // original ACE_Service_Type instance. It deletes our dummy
- // instance when replacing it with the actual implementation, so
- // we are hereby simply giving up ownership.
- this->dummy_ = 0;
-
- if(ACE::debug ())
- ACE_DEBUG ((LM_DEBUG,
- ACE_LIB_TEXT ("ACE (%P|%t) STDG::<dtor>, repo=%@ [%d], ")
- ACE_LIB_TEXT ("name=%s, type=%@, impl=%@, object=%@, active=%d - loaded\n"),
- &this->repo_, this->repo_begin_, this->name_, tmp, tmp->type (),
- (tmp->type () != 0) ? tmp->type ()->object () : 0,
- tmp->active ()));
- }
+ ACE_LIB_TEXT ("ACE (%P|%t) Service_Type_Dynamic_Guard")
+ ACE_LIB_TEXT (":<dtor> - find %s failed, returns %d/%d\n"),
+ this->name_,
+ ret,
+ errno));
+#endif /* ACE_NLOGGING */
+
+ delete this->dummy_;
+ }
else
- {
- if(ACE::debug ())
- ACE_DEBUG ((LM_DEBUG,
- ACE_LIB_TEXT ("ACE (%P|%t) STDG::<dtor>, repo=%@, ")
- ACE_LIB_TEXT ("name=%s, type=%@, impl=%@, object=%@, active=%d - removing dummy forward\n"),
- &this->repo_, this->name_, this->dummy_, this->dummy_->type (),
- (this->dummy_->type () != 0) ? this->dummy_->type ()->object () : 0,
- this->dummy_->active ()));
-
- // The (dummy) forward declaration is still there and is
- // the same, which means that no actual declaration was
- // provided inside the guarded scope. Therefore, the forward
- // declaration is no longer necessary.
- if (this->repo_.remove_i (this->name_,
- const_cast< ACE_Service_Type**> (&this->dummy_)) == 0)
- {
- // If it is a dummy then deleting it while holding the repo lock is okay. There will be no
- // call to service object's fini() and no possibility for deadlocks.
- delete this->dummy_;
- }
- else
- {
- ACE_ERROR ((LM_WARNING,
- ACE_LIB_TEXT ("ACE (%P|%t) STDG::<dtor>, repo=%@, name=%s, ")
- ACE_LIB_TEXT ("type=%@, impl=%@, object=%@, active=%d - dummy remove failed\n"),
- &this->repo_, this->name_, this->dummy_, this->dummy_->type (),
- (this->dummy_->type () != 0) ? this->dummy_->type ()->object () : 0,
+ {
+ // So we found a service with the same name
+ if (tmp != 0 && tmp->type () != 0)
+ {
+ // If something did register a proper (non-forward-decl)
+ // service with the same name as our dummy, then it has
+ // acquired the ownership of the instance dummy_ points to.
+#ifndef ACE_NLOGGING
+ if(ACE::debug ())
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_LIB_TEXT ("ACE (%P|%t) Service_Type_Dynamic_Guard")
+ ACE_LIB_TEXT (":<dtor> - relocating [%d-%d]")
+ ACE_LIB_TEXT (", repo=%@, name=%s\n"),
+ this->repo_begin_,
+ this->repo_.current_size (),
+ &this->repo_,
+ this->name_));
+#endif /* ACE_NLOGGING */
+
+ // Relocate any related static services. If any have been
+ // registered in the context of this guard, those really
+ // aren't static services because their code is in the DLL's
+ // code segment
+ this->repo_.relocate_i (this->repo_begin_,
+ this->repo_.current_size (),
+ tmp->dll());
+
+ // The ACE_Service_Gestalt::insert() modifies the memory for
+ // the original ACE_Service_Type instance. It will delete our
+ // dummy instance when replacing it with the actual
+ // implementation. We are hereby simply giving up ownership of
+ // something that no longer exists.
+ this->dummy_ = 0;
+
+#ifndef ACE_NLOGGING
+ if(ACE::debug ())
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_LIB_TEXT ("ACE (%P|%t) Service_Type_Dynamic_Guard")
+ ACE_LIB_TEXT (":<dtor> - done loading of %s")
+ ACE_LIB_TEXT (", repo[%d]=%@, type=%@, impl=%@")
+ ACE_LIB_TEXT (", object=%@, active=%d\n"),
+ this->name_,
+ this->repo_begin_,
+ &this->repo_,
+ tmp,
+ tmp->type (),
+ (tmp->type () != 0) ? tmp->type ()->object () : 0,
+ tmp->active ()));
+#endif /* ACE_NLOGGING */
+ }
+ else
+ {
+#ifndef ACE_NLOGGING
+ if(ACE::debug ())
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_LIB_TEXT ("ACE (%P|%t) Service_Type_Dynamic_Guard")
+ ACE_LIB_TEXT (":<dtor> - removing fwd decl for %s")
+ ACE_LIB_TEXT (", repo=%@, type=%@, impl=%@")
+ ACE_LIB_TEXT (", object=%@, active=%d\n"),
+ this->name_,
+ &this->repo_,
+ this->dummy_,
+ this->dummy_->type (),
+ (this->dummy_->type () != 0)
+ ? this->dummy_->type ()->object ()
+ : 0,
this->dummy_->active ()));
- }
- }
-
- // Clean up
+#endif /* ACE_NLOGGING */
+
+ // The (dummy) forward declaration is still there and is the
+ // same, which means that no actual declaration was provided
+ // inside the guarded scope. Therefore, the forward
+ // declaration is no longer necessary.
+ if (this->repo_.remove_i (this->name_,
+ const_cast< ACE_Service_Type**>
+ (&this->dummy_)) == 0)
+ {
+ // If it is a dummy then deleting it while holding the
+ // repo lock is okay. There will be no call to service
+ // object's fini() and no possibility for deadlocks.
+ delete this->dummy_;
+ }
+ else
+ {
+#ifndef ACE_NLOGGING
+ ACE_ERROR ((LM_WARNING,
+ ACE_LIB_TEXT ("ACE (%P|%t) Service_Type_Dynamic_Guard")
+ ACE_LIB_TEXT (":<dtor> - failed to remove fwd decl %s")
+ ACE_LIB_TEXT (", repo=%@, type=%@, impl=%@")
+ ACE_LIB_TEXT (", object=%@, active=%d: -1/%d\n"),
+ this->name_,
+ &this->repo_,
+ this->dummy_,
+ this->dummy_->type (),
+ (this->dummy_->type () != 0)
+ ? this->dummy_->type ()->object ()
+ : 0,
+ this->dummy_->active (),
+ errno));
+#endif /* ACE_NLOGGING */
+ }
+ }
+ }
+
+ // Clean up and bail ...
this->dummy_ = 0;
}
@@ -256,7 +318,7 @@ ACE_Service_Gestalt::~ACE_Service_Gestalt (void)
ACE_DEBUG ((LM_DEBUG,
ACE_LIB_TEXT ("ACE (%P|%t) SG::dtor - this=%@, pss = %@\n"),
this, this->processed_static_svcs_));
-#endif
+#endif /* ACE_NLOGGING */
if (this->processed_static_svcs_ &&
!this->processed_static_svcs_->is_empty())
@@ -532,7 +594,6 @@ ACE_Service_Gestalt::initialize (const ACE_TCHAR *svc_name,
const ACE_Service_Type *srp = 0;
for (int i = 0; this->find (svc_name, &srp) == -1 && i < 2; i++)
- // if (this->repo_->find (svc_name, &srp) == -1)
{
const ACE_Static_Svc_Descriptor *assd =
ACE_Service_Config::global()->find_processed_static_svc(svc_name);