summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2000-08-07 20:47:18 +0000
committernobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2000-08-07 20:47:18 +0000
commit684f97ab634c5fcc5caf7f59ec8575004cf47caf (patch)
treef08d3d5031369527a11659d901953f6adbe7b21b
parent0e39dd45e5c58320c64ddc21191814db3fab2ed1 (diff)
downloadATCD-684f97ab634c5fcc5caf7f59ec8575004cf47caf.tar.gz
This commit was manufactured by cvs2svn to create branch 'ft_tao_2'.
-rw-r--r--TAO/tao/DLL_ORB.cpp148
-rw-r--r--TAO/tao/DLL_ORB.h88
-rw-r--r--TAO/tao/TAO_Export.h40
-rw-r--r--TAO/tao/TAO_Singleton.cpp206
-rw-r--r--TAO/tao/TAO_Singleton.h129
-rw-r--r--TAO/tao/TAO_Singleton_Manager.cpp266
-rw-r--r--TAO/tao/TAO_Singleton_Manager.h188
7 files changed, 1065 insertions, 0 deletions
diff --git a/TAO/tao/DLL_ORB.cpp b/TAO/tao/DLL_ORB.cpp
new file mode 100644
index 00000000000..f8a8e289d45
--- /dev/null
+++ b/TAO/tao/DLL_ORB.cpp
@@ -0,0 +1,148 @@
+// -*- C++ -*-
+
+#include "ace/ARGV.h"
+#include "ace/Dynamic_Service.h"
+#include "tao/DLL_ORB.h"
+#include "tao/TAO_Singleton_Manager.h"
+
+ACE_RCSID (tao, DLL_ORB, "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "tao/DLL_ORB.inl"
+#endif /* ! __ACE_INLINE__ */
+
+TAO_DLL_ORB::TAO_DLL_ORB (void)
+ : orb_ ()
+{
+ // Nothing
+}
+
+TAO_DLL_ORB::~TAO_DLL_ORB (void)
+{
+ // Nothing
+}
+
+int
+TAO_DLL_ORB::init (int argc, ACE_TCHAR *argv[])
+{
+ // Make sure TAO's singleton manager is initialized, and set to not
+ // register itself with the ACE_Object_Manager since it is under the
+ // control of the Service Configurator.
+ int register_with_object_manager = 0;
+
+ if (TAO_Singleton_Manager::instance ()->init (
+ register_with_object_manager) == -1)
+ return -1; // No exceptions yet.
+
+ ACE_TRY_NEW_ENV
+ {
+ ACE_ARGV new_argv;
+
+ // Respect the argc supplied by the user instead of the one
+ // calculated by the ACE_ARGV class. Also, add two to the new
+ // argc since "dummy -ORBSkipServiceConfigOpen" is being added
+ // to the argv vector.
+ int new_argc = argc + 2;
+
+ // Prevent the ORB from opening the Service Configurator file
+ // again since the Service Configurator file is already in the
+ // process of being opened.
+ if (new_argv.add (ACE_TEXT ("dummy -ORBSkipServiceConfigOpen")) == -1
+ || new_argv.add (argv) == -1)
+ return -1;
+
+ // Initialize the ORB.
+ this->orb_ = CORBA::ORB_init (new_argc,
+ new_argv.argv (),
+ 0,
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (this->orb_.in ()))
+ return -1;
+ }
+ ACE_CATCHANY
+ {
+// ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+// ACE_TEXT ("TAO_DLL_ORB::init"));
+
+ return -1;
+ }
+ ACE_ENDTRY;
+
+#if defined (ACE_HAS_THREADS)
+ // Become an Active Object so that the ORB
+ // will execute in a separate thread.
+ return this->activate ();
+#else
+ return 0;
+#endif /* ACE_HAS_THREADS */
+}
+
+int
+TAO_DLL_ORB::fini (void)
+{
+ ACE_TRY_NEW_ENV
+ {
+ this->orb_->destroy (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+
+ if (TAO_Singleton_Manager::instance ()->fini () == -1)
+ return -1;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ ACE_TEXT ("TAO_DLL_ORB::fini"));
+ return -1;
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+int
+TAO_DLL_ORB::svc (void)
+{
+ ACE_TRY_NEW_ENV
+ {
+ // Run the ORB event loop in its own thread.
+ this->orb_->run (ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ ACE_TEXT ("TAO_DLL_ORB::svc"));
+ return -1;
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+
+ACE_STATIC_SVC_DEFINE (TAO_DLL_ORB,
+ ACE_TEXT ("DLL_ORB"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_DLL_ORB),
+ ACE_Service_Type::DELETE_THIS
+ | ACE_Service_Type::DELETE_OBJ,
+ 0)
+
+ACE_FACTORY_DEFINE (TAO, TAO_DLL_ORB)
+
+
+
+// Template instantiations necessary for use when dynamically load the
+// TAO_DLL_ORB.
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+
+template class ACE_Dynamic_Service<TAO_DLL_ORB>;
+
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+
+#pragma instantiate ACE_Dynamic_Service<TAO_DLL_ORB>
+
+#endif
diff --git a/TAO/tao/DLL_ORB.h b/TAO/tao/DLL_ORB.h
new file mode 100644
index 00000000000..a6d5e856fe7
--- /dev/null
+++ b/TAO/tao/DLL_ORB.h
@@ -0,0 +1,88 @@
+// -*- C++ -*-
+//
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// TAO
+//
+// = FILENAME
+// DLL_ORB.h
+//
+// = DESCRIPTION
+// Header file for the TAO_DLL_ORB helper class.
+//
+// = AUTHOR
+// Ossama Othman <ossama@uci.edu>
+//
+// ============================================================================
+
+#ifndef TAO_DLL_ORB_H
+#define TAO_DLL_ORB_H
+
+#include "ace/pre.h"
+
+#include "ace/Task.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/ORB.h"
+
+class TAO_Export TAO_DLL_ORB : public ACE_Task_Base
+{
+ // = TITLE
+ // Manager for TAO library services and singleton cleanup.
+ //
+ // = DESCRIPTION
+ // The <TAO_Singleton_Manager> is basically simplified version of
+ // the ACE_Object_Manager. It is designed specifically to
+ // manage singletons created by TAO. For example, Singleton
+ // instances created by TAO will be automatically registered
+ // with the Singleton instance of this Singleton Manager.
+ //
+ // This class is necessary to ensure that TAO-specific
+ // Singletons are centrally isolated. The idea is that
+ // destruction of the instance of the <TAO_Singleton_Manager>
+ // triggers destruction of all objects/services registered with
+ // it.
+
+public:
+
+ TAO_DLL_ORB (void);
+ // Constructor
+
+ ~TAO_DLL_ORB (void);
+ // Destructor
+
+ virtual int init (int argc, ACE_TCHAR *argv[]);
+ // Initializes ORB when dynamic linking occurs.
+
+ virtual int fini (void);
+ // Terminates ORB when dynamic unlinking occurs.
+
+ virtual int svc (void);
+ // Run by a daemon thread to handle deferred processing.
+
+ CORBA::ORB_ptr orb (void);
+ // Returns a duplicate reference to the ORB.
+
+private:
+
+ CORBA::ORB_var orb_;
+ // Reference to the ORB.
+
+};
+
+#if defined (__ACE_INLINE__)
+# include "tao/DLL_ORB.inl"
+#endif /* ! __ACE_INLINE__ */
+
+ACE_STATIC_SVC_DECLARE (TAO_DLL_ORB)
+ACE_FACTORY_DECLARE (TAO, TAO_DLL_ORB)
+
+#include "ace/post.h"
+
+#endif /* TAO_DLL_ORB_H */
diff --git a/TAO/tao/TAO_Export.h b/TAO/tao/TAO_Export.h
new file mode 100644
index 00000000000..51fd5c981e2
--- /dev/null
+++ b/TAO/tao/TAO_Export.h
@@ -0,0 +1,40 @@
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by
+// generate_export_file.pl
+// ------------------------------
+#ifndef TAO_EXPORT_H
+#define TAO_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if !defined (TAO_HAS_DLL)
+#define TAO_HAS_DLL 1
+#endif /* ! TAO_HAS_DLL */
+
+#if defined (TAO_HAS_DLL)
+# if (TAO_HAS_DLL == 1)
+# if defined (TAO_BUILD_DLL)
+# define TAO_Export ACE_Proper_Export_Flag
+# define TAO_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define TAO_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else
+# define TAO_Export ACE_Proper_Import_Flag
+# define TAO_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define TAO_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* TAO_BUILD_DLL */
+# else
+# define TAO_Export
+# define TAO_SINGLETON_DECLARATION(T)
+# define TAO_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* ! TAO_HAS_DLL == 1 */
+#else
+# define TAO_Export
+# define TAO_SINGLETON_DECLARATION(T)
+# define TAO_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* TAO_HAS_DLL */
+
+#endif /* TAO_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/tao/TAO_Singleton.cpp b/TAO/tao/TAO_Singleton.cpp
new file mode 100644
index 00000000000..f41683c33e7
--- /dev/null
+++ b/TAO/tao/TAO_Singleton.cpp
@@ -0,0 +1,206 @@
+// -*- C++ -*-
+//
+// $Id$
+
+#ifndef TAO_SINGLETON_CPP
+#define TAO_SINGLETON_CPP
+
+#include "tao/TAO_Singleton.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Synch_T.h"
+#include "ace/Object_Manager.h"
+#include "ace/Log_Msg.h"
+#include "tao/TAO_Singleton_Manager.h"
+
+#if !defined (__ACE_INLINE__)
+#include "tao/TAO_Singleton.inl"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID (tao, TAO_Singleton, "$Id$")
+
+template <class TYPE, class ACE_LOCK> void
+TAO_Singleton<TYPE, ACE_LOCK>::dump (void)
+{
+ ACE_TRACE ("TAO_Singleton<TYPE, ACE_LOCK>::dump");
+
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"),
+ TAO_Singleton<TYPE, ACE_LOCK>::instance_i ()));
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+}
+
+template <class TYPE, class ACE_LOCK> TAO_Singleton<TYPE, ACE_LOCK> *&
+TAO_Singleton<TYPE, ACE_LOCK>::instance_i (void)
+{
+#if defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ // Pointer to the Singleton instance. This works around a bug with
+ // G++ and it's (mis-)handling of templates and statics...
+ static TAO_Singleton<TYPE, ACE_LOCK> *singleton_ = 0;
+
+ return singleton_;
+#else
+ return TAO_Singleton<TYPE, ACE_LOCK>::singleton_;
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+}
+
+template <class TYPE, class ACE_LOCK> TYPE *
+TAO_Singleton<TYPE, ACE_LOCK>::instance (void)
+{
+ ACE_TRACE ("TAO_Singleton<TYPE, ACE_LOCK>::instance");
+
+ TAO_Singleton<TYPE, ACE_LOCK> *&singleton =
+ TAO_Singleton<TYPE, ACE_LOCK>::instance_i ();
+
+ // Perform the Double-Check pattern...
+ if (singleton == 0)
+ {
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ if (TAO_Singleton_Manager::starting_up () ||
+ TAO_Singleton_Manager::shutting_down ())
+ {
+ // The program is still starting up, and therefore assumed
+ // to be single threaded. There's no need to double-check.
+ // Or, the TAO_Singleton_Manager instance has been destroyed,
+ // so the preallocated lock is not available. Either way,
+ // don't register for destruction with the
+ // TAO_Singleton_Manager: we'll have to leak this instance.
+#endif /* ACE_MT_SAFE */
+
+ ACE_NEW_RETURN (singleton, (TAO_Singleton<TYPE, ACE_LOCK>), 0);
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ }
+ else
+ {
+ // Obtain a lock from the ACE_Object_Manager. The pointer
+ // is static, so we only obtain one per TAO_Singleton
+ // instantiation.
+ static ACE_LOCK *lock = 0;
+ if (ACE_Object_Manager::get_singleton_lock (lock) != 0)
+ // Failed to acquire the lock!
+ return 0;
+
+ ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0);
+
+ if (singleton == 0)
+ {
+ ACE_NEW_RETURN (singleton, (TAO_Singleton<TYPE, ACE_LOCK>), 0);
+
+ // Register for destruction with TAO_Singleton_Manager.
+ TAO_Singleton_Manager::at_exit (singleton);
+ }
+ }
+#endif /* ACE_MT_SAFE */
+ }
+
+ return &singleton->instance_;
+}
+
+template <class TYPE, class ACE_LOCK> void
+TAO_Singleton<TYPE, ACE_LOCK>::cleanup (void *)
+{
+ delete this;
+ TAO_Singleton<TYPE, ACE_LOCK>::instance_i () = 0;
+}
+
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+// Pointer to the Singleton instance.
+template <class TYPE, class ACE_LOCK> TAO_Singleton<TYPE, ACE_LOCK> *
+TAO_Singleton<TYPE, ACE_LOCK>::singleton_ = 0;
+
+template <class TYPE, class ACE_LOCK> TAO_TSS_Singleton<TYPE, ACE_LOCK> *
+TAO_TSS_Singleton<TYPE, ACE_LOCK>::singleton_ = 0;
+#endif /* !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */
+
+
+template <class TYPE, class ACE_LOCK> void
+TAO_TSS_Singleton<TYPE, ACE_LOCK>::dump (void)
+{
+ ACE_TRACE ("TAO_TSS_Singleton<TYPE, ACE_LOCK>::dump");
+
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"),
+ TAO_TSS_Singleton<TYPE, ACE_LOCK>::instance_i ()));
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+}
+
+template <class TYPE, class ACE_LOCK> TAO_TSS_Singleton<TYPE, ACE_LOCK> *&
+TAO_TSS_Singleton<TYPE, ACE_LOCK>::instance_i (void)
+{
+#if defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ // Pointer to the Singleton instance. This works around a bug with
+ // G++ and it's (mis-)handling of templates and statics...
+ static TAO_TSS_Singleton<TYPE, ACE_LOCK> *singleton_ = 0;
+
+ return singleton_;
+#else
+ return TAO_TSS_Singleton<TYPE, ACE_LOCK>::singleton_;
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+}
+
+template <class TYPE, class ACE_LOCK> TYPE *
+TAO_TSS_Singleton<TYPE, ACE_LOCK>::instance (void)
+{
+ ACE_TRACE ("TAO_TSS_Singleton<TYPE, ACE_LOCK>::instance");
+
+ TAO_TSS_Singleton<TYPE, ACE_LOCK> *&singleton =
+ TAO_TSS_Singleton<TYPE, ACE_LOCK>::instance_i ();
+
+ // Perform the Double-Check pattern...
+ if (singleton == 0)
+ {
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ if (TAO_Singleton_Manager::starting_up () ||
+ TAO_Singleton_Manager::shutting_down ())
+ {
+ // The program is still starting up, and therefore assumed
+ // to be single threaded. There's no need to double-check.
+ // Or, the TAO_Singleton_Manager instance has been destroyed,
+ // so the preallocated lock is not available. Either way,
+ // don't register for destruction with the
+ // TAO_Singleton_Manager: we'll have to leak this instance.
+#endif /* ACE_MT_SAFE */
+
+ ACE_NEW_RETURN (singleton, (TAO_TSS_Singleton<TYPE, ACE_LOCK>), 0);
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ }
+ else
+ {
+ // Obtain a lock from the ACE_Object_Manager. The pointer
+ // is static, so we only obtain one per TAO_Singleton
+ // instantiation.
+ static ACE_LOCK *lock = 0;
+ if (ACE_Object_Manager::get_singleton_lock (lock) != 0)
+ // Failed to acquire the lock!
+ return 0;
+
+ ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0);
+
+ if (singleton == 0)
+ {
+ ACE_NEW_RETURN (singleton, (TAO_TSS_Singleton<TYPE, ACE_LOCK>),
+ 0);
+
+ // Register for destruction with TAO_Singleton_Manager.
+ TAO_Singleton_Manager::at_exit (singleton);
+ }
+ }
+#endif /* ACE_MT_SAFE */
+ }
+
+ return ACE_TSS_GET (&singleton->instance_, TYPE);
+}
+
+template <class TYPE, class ACE_LOCK> void
+TAO_TSS_Singleton<TYPE, ACE_LOCK>::cleanup (void *)
+{
+ delete this;
+ TAO_TSS_Singleton<TYPE, ACE_LOCK>::instance_i () = 0;
+}
+
+#endif /* TAO_SINGLETON_CPP */
diff --git a/TAO/tao/TAO_Singleton.h b/TAO/tao/TAO_Singleton.h
new file mode 100644
index 00000000000..f6dc4d6c024
--- /dev/null
+++ b/TAO/tao/TAO_Singleton.h
@@ -0,0 +1,129 @@
+// -*- C++ -*-
+//
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// TAO
+//
+// = FILENAME
+// TAO_Singleton.h
+//
+// = DESCRIPTION
+// Header file for the TAO-specific Singleton implementation.
+// Based entirely on tao/TAO_Singleton.*.
+//
+// = AUTHOR
+// Ossama Othman <ossama@uci.edu>
+//
+// ============================================================================
+
+#ifndef TAO_SINGLETON_H
+#define TAO_SINGLETON_H
+
+#include "ace/pre.h"
+
+#include "ace/Synch.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+
+template <class TYPE, class ACE_LOCK>
+class TAO_Singleton : public ACE_Cleanup
+{
+ // = TITLE
+ // TAO-specific Singleton class
+ //
+ // = DESCRIPTION
+ // TAO_Singletons are used by TAO to register TAO-specific
+ // singleton instances with the TAO_Object_Manager. This
+ // ensures that TAO singletons are isolated from ACE's
+ // Object_Manager, thus allowing TAO to be safely dynamically
+ // unloaded.
+
+public:
+ static TYPE *instance (void);
+ // Global access point to the Singleton.
+
+ virtual void cleanup (void *param = 0);
+ // Cleanup method, used by <ace_cleanup_destroyer> to destroy the
+ // singleton.
+
+ static void dump (void);
+ // Dump the state of the object.
+
+protected:
+ TAO_Singleton (void);
+ // Default constructor.
+
+ TYPE instance_;
+ // Contained instance.
+
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ static TAO_Singleton<TYPE, ACE_LOCK> *singleton_;
+ // Pointer to the Singleton (ACE_Cleanup) instance.
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+
+ static TAO_Singleton<TYPE, ACE_LOCK> *&instance_i (void);
+ // Get pointer to the TAO Singleton instance.
+};
+
+template <class TYPE, class ACE_LOCK>
+class TAO_TSS_Singleton : public ACE_Cleanup
+{
+ // = TITLE
+ // TAO-specific Singleton class
+ //
+ // = DESCRIPTION
+ // TAO_Singletons are used by TAO to register TAO-specific
+ // singleton instances with the TAO_Object_Manager. This
+ // ensures that TAO singletons are isolated from ACE's
+ // Object_Manager, thus allowing TAO to be safely dynamically
+ // unloaded.
+
+public:
+ static TYPE *instance (void);
+ // Global access point to the Singleton.
+
+ virtual void cleanup (void *param = 0);
+ // Cleanup method, used by <ace_cleanup_destroyer> to destroy the
+ // singleton.
+
+ static void dump (void);
+ // Dump the state of the object.
+
+protected:
+ TAO_TSS_Singleton (void);
+ // Default constructor.
+
+ ACE_TSS_TYPE (TYPE) instance_;
+ // Contained instance.
+
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ static TAO_TSS_Singleton<TYPE, ACE_LOCK> *singleton_;
+ // Pointer to the Singleton (ACE_Cleanup) instance.
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+
+ static TAO_TSS_Singleton<TYPE, ACE_LOCK> *&instance_i (void);
+ // Get pointer to the TAO TSS Singleton instance.
+};
+
+#if defined (__ACE_INLINE__)
+#include "tao/TAO_Singleton.inl"
+#endif /* __ACE_INLINE__ */
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "tao/TAO_Singleton.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("TAO_Singleton.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+
+#include "ace/post.h"
+
+#endif /* TAO_SINGLETON_H */
diff --git a/TAO/tao/TAO_Singleton_Manager.cpp b/TAO/tao/TAO_Singleton_Manager.cpp
new file mode 100644
index 00000000000..aa1d8d9148e
--- /dev/null
+++ b/TAO/tao/TAO_Singleton_Manager.cpp
@@ -0,0 +1,266 @@
+// $Id$
+
+#include "ace/Log_Msg.h"
+#include "ace/Synch.h"
+
+#include "tao/TAO_Singleton_Manager.h"
+
+#include "tao/Exception.h"
+#include "tao/Typecode.h"
+
+#if !defined (__ACE_INLINE__)
+# include "tao/TAO_Singleton_Manager.inl"
+#endif /* ! __ACE_INLINE__ */
+
+ACE_RCSID (tao, TAO_Singleton_Manager, "$Id$")
+
+
+extern "C" void
+TAO_Singleton_Manager_cleanup_destroyer (void *, void *)
+{
+ if (TAO_Singleton_Manager::instance_)
+ (void) TAO_Singleton_Manager::instance ()->fini ();
+}
+
+TAO_Singleton_Manager *TAO_Singleton_Manager::instance_ = 0;
+
+void *TAO_Singleton_Manager::preallocated_object[
+ TAO_Singleton_Manager::TAO_PREALLOCATED_OBJECTS] = { 0 };
+
+TAO_Singleton_Manager::TAO_Singleton_Manager (void)
+ // default_mask_ isn't initialized, because it's defined by <init>.
+ : thread_hook_ (0),
+ exit_info_ (),
+ registered_with_object_manager_ (0)
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ , internal_lock_ (new ACE_Recursive_Thread_Mutex)
+# endif /* ACE_MT_SAFE */
+{
+ // Be sure that no further instances are created via instance ().
+ if (instance_ == 0)
+ instance_ = this;
+
+ (void) this->init ();
+}
+
+TAO_Singleton_Manager::~TAO_Singleton_Manager (void)
+{
+ this->dynamically_allocated_ = 0; // Don't delete this again in fini()
+ (void) this->fini ();
+}
+
+sigset_t *
+TAO_Singleton_Manager::default_mask (void)
+{
+ return TAO_Singleton_Manager::instance ()->default_mask_;
+}
+
+ACE_Thread_Hook *
+TAO_Singleton_Manager::thread_hook (void)
+{
+ return TAO_Singleton_Manager::instance ()->thread_hook_;
+}
+
+ACE_Thread_Hook *
+TAO_Singleton_Manager::thread_hook (ACE_Thread_Hook *new_thread_hook)
+{
+ TAO_Singleton_Manager *tao_om = TAO_Singleton_Manager::instance ();
+ ACE_Thread_Hook *old_hook = tao_om->thread_hook_;
+ tao_om->thread_hook_ = new_thread_hook;
+ return old_hook;
+}
+
+TAO_Singleton_Manager *
+TAO_Singleton_Manager::instance (void)
+{
+ // This function should be called during construction of static
+ // instances, or before any other threads have been created in the
+ // process. So, it's not thread safe.
+
+ if (instance_ == 0)
+ {
+ TAO_Singleton_Manager *instance_pointer;
+
+ ACE_NEW_RETURN (instance_pointer,
+ TAO_Singleton_Manager,
+ 0);
+ ACE_ASSERT (instance_pointer == instance_);
+
+ instance_pointer->dynamically_allocated_ = 1;
+
+ }
+
+ return instance_;
+}
+
+int
+TAO_Singleton_Manager::init (void)
+{
+ // Register the TAO_Singleton_Manager with the ACE_Object_Manager.
+ int register_with_object_manager = 1;
+
+ return this->init (register_with_object_manager);
+}
+
+int
+TAO_Singleton_Manager::init (int register_with_object_manager)
+{
+ if (this->starting_up_i ())
+ {
+ // First, indicate that this TAO_Singleton_Manager instance is being
+ // initialized.
+ this->object_manager_state_ = OBJ_MAN_INITIALIZING;
+
+ if (this == instance_)
+ {
+# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ // @@ No MT-specific pre-allocated objects.
+# endif /* ACE_MT_SAFE */
+ }
+
+ ACE_NEW_RETURN (this->default_mask_, sigset_t, -1);
+ ACE_OS::sigfillset (this->default_mask_);
+
+ if (register_with_object_manager == 1
+ && ACE_Object_Manager::instance ()->at_exit (
+ this,
+ (ACE_CLEANUP_FUNC) TAO_Singleton_Manager_cleanup_destroyer,
+ 0) != 0)
+ return -1;
+
+ this->registered_with_object_manager_ =
+ register_with_object_manager;
+
+ // Finally, indicate that the TAO_Singleton_Manager instance has
+ // been initialized.
+ this->object_manager_state_ = OBJ_MAN_INITIALIZED;
+
+ return 0;
+ }
+ else if (this->registered_with_object_manager_
+ != register_with_object_manager)
+ {
+ // An attempt was made to register the TAO_Singleton_Manager
+ // with a manager of a different type from the one it is
+ // currently registered with. This indicates a problem with the
+ // caller's logic.
+
+ errno = EINVAL;
+ return -1;
+ }
+
+ // Had already initialized.
+ return 1;
+}
+
+// Clean up a TAO_Singleton_Manager. There can be instances of this object
+// other than The Instance. This can happen if a user creates one for some
+// reason. All objects clean up their per-object information and managed
+// objects, but only The Instance cleans up the static preallocated objects.
+int
+TAO_Singleton_Manager::fini (void)
+{
+ if (instance_ == 0 || this->shutting_down_i ())
+ // Too late. Or, maybe too early. Either fini () has already
+ // been called, or init () was never called.
+ return this->object_manager_state_ == OBJ_MAN_SHUT_DOWN ? 1 : -1;
+
+ // No mutex here. Only the main thread should destroy the singleton
+ // TAO_Singleton_Manager instance.
+
+ // Indicate that the TAO_Singleton_Manager instance is being shut
+ // down. This object manager should be the last one to be shut
+ // down.
+ this->object_manager_state_ = OBJ_MAN_SHUTTING_DOWN;
+
+ // If another Object_Manager has registered for termination, do it.
+ if (this->next_)
+ {
+ this->next_->fini ();
+ this->next_ = 0; // Protect against recursive calls.
+ }
+
+ // Call all registered cleanup hooks, in reverse order of
+ // registration.
+ this->exit_info_.call_hooks ();
+
+ // Only clean up preallocated objects when the singleton Instance is being
+ // destroyed.
+ if (this == instance_)
+ {
+#if ! defined (ACE_HAS_STATIC_PREALLOCATION)
+ // Cleanup the dynamically preallocated objects.
+# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ // @@ No MT-specific preallocated objects yet.
+# endif /* ACE_MT_SAFE */
+ // @@ No preallocated objects yet.
+#endif /* ! ACE_HAS_STATIC_PREALLOCATION */
+ }
+
+ delete this-> default_mask_;
+ this->default_mask_ = 0;
+
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ delete this->internal_lock_;
+ this->internal_lock_ = 0;
+#endif /* ACE_MT_SAFE */
+
+ // Indicate that this TAO_Singleton_Manager instance has been shut down.
+ this->object_manager_state_ = OBJ_MAN_SHUT_DOWN;
+
+ if (this == instance_)
+ instance_ = 0;
+
+ if (this->dynamically_allocated_)
+ {
+ delete this;
+ }
+
+ // Clean up all ORB owned Exceptions (before TypeCode clean up).
+ TAO_Exceptions::fini ();
+
+ // Clean up all ORB owned TypeCodes.
+ TAO_TypeCodes::fini ();
+
+ return 0;
+}
+
+int
+TAO_Singleton_Manager::starting_up (void)
+{
+ return TAO_Singleton_Manager::instance_
+ ? instance_->starting_up_i ()
+ : 1;
+}
+
+int
+TAO_Singleton_Manager::shutting_down (void)
+{
+ return TAO_Singleton_Manager::instance_
+ ? instance_->shutting_down_i ()
+ : 1;
+}
+
+int
+TAO_Singleton_Manager::at_exit_i (void *object,
+ ACE_CLEANUP_FUNC cleanup_hook,
+ void *param)
+{
+ ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
+ *instance_->internal_lock_, -1));
+
+ if (this->shutting_down_i ())
+ {
+ errno = EAGAIN;
+ return -1;
+ }
+
+ if (this->exit_info_.find (object))
+ {
+ // The object has already been registered.
+ errno = EEXIST;
+ return -1;
+ }
+
+ return this->exit_info_.at_exit_i (object, cleanup_hook, param);
+}
diff --git a/TAO/tao/TAO_Singleton_Manager.h b/TAO/tao/TAO_Singleton_Manager.h
new file mode 100644
index 00000000000..97faf5dda2d
--- /dev/null
+++ b/TAO/tao/TAO_Singleton_Manager.h
@@ -0,0 +1,188 @@
+// -*- C++ -*-
+//
+// $Id$
+
+
+// ============================================================================
+//
+// = LIBRARY
+// TAO
+//
+// = FILENAME
+// TAO_Singleton_Manager.h
+//
+// = DESCRIPTION
+// Header file for the TAO-specific Singleton Manager. Based
+// entirely on ace/Object_Manager.{h,i,cpp}.
+//
+// = AUTHOR
+// Ossama Othman <ossama@uci.edu>
+//
+// ============================================================================
+
+#ifndef TAO_OBJECT_MANAGER_H
+#define TAO_OBJECT_MANAGER_H
+
+#include "ace/pre.h"
+
+#include "tao/TAO_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/OS.h"
+
+// Forward declarations
+class ACE_Recursive_Thread_Mutex;
+
+// Adapter for cleanup, used to register cleanup function with the
+// ACE_Object_Manager.
+extern "C"
+void
+TAO_Singleton_Manager_cleanup_destroyer (void *, void *);
+
+class TAO_Export TAO_Singleton_Manager : public ACE_Object_Manager_Base
+{
+ // = TITLE
+ // Manager for TAO library services and singleton cleanup.
+ //
+ // = DESCRIPTION
+ // The <TAO_Singleton_Manager> is basically simplified version of
+ // the ACE_Object_Manager. It is designed specifically to
+ // manage singletons created by TAO. For example, Singleton
+ // instances created by TAO will be automatically registered
+ // with the Singleton instance of this Singleton Manager.
+ //
+ // This class is necessary to ensure that TAO-specific
+ // Singletons are centrally isolated. The idea is that
+ // destruction of the instance of the <TAO_Singleton_Manager>
+ // triggers destruction of all objects/services registered with
+ // it.
+
+ friend void TAO_Singleton_Manager_cleanup_destroyer (void *, void *);
+
+public:
+ virtual int init (void);
+ // Explicitly initialize.
+
+ int init (int register_with_object_manager);
+ // Explicitly initialize the TAO_Singleton_Manager, in addition to
+ // explicitly registering (or not registering) with the
+ // ACE_Object_Manager.
+
+ virtual int fini (void);
+ // Explicitly destroy.
+
+ static int starting_up (void);
+ // Returns 1 before the <TAO_Singleton_Manager> has been
+ // constructed. See <ACE_Object_Manager::starting_up> for more
+ // information.
+
+ static int shutting_down (void);
+ // Returns 1 after the <TAO_Singleton_Manager> has been destroyed.
+ // See <ACE_Object_Manager::shutting_down> for more information.
+
+ enum Preallocated_Object
+ {
+# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ // @@ No MT-specific preallocated objects (yet). Remove the
+ // below dummy enum once a preallocated object is added.
+ TAO_EMPTY_PREALLOCATED_OBJECT,
+# else
+ // Without ACE_MT_SAFE, There are no preallocated objects. Make
+ // sure that the preallocated_array size is at least one by
+ // declaring this dummy . . .
+ TAO_EMPTY_PREALLOCATED_OBJECT,
+# endif /* ACE_MT_SAFE */
+
+ TAO_PREALLOCATED_OBJECTS // This enum value must be last!
+ };
+ // Unique identifiers for preallocated objects.
+
+ static sigset_t *default_mask (void);
+ // Accesses a default signal set used, for example, in
+ // <ACE_Sig_Guard> methods.
+
+ static ACE_Thread_Hook *thread_hook (void);
+ // Returns the current thread hook for the process.
+
+ static ACE_Thread_Hook *thread_hook (ACE_Thread_Hook *new_thread_hook);
+ // Returns the existing thread hook and assign a <new_thread_hook>.
+
+ static TAO_Singleton_Manager *instance (void);
+ // Accessor to singleton instance.
+
+ static int at_exit (ACE_Cleanup *object, void *param = 0);
+ // Register an ACE_Cleanup object for cleanup at process
+ // termination. The object is deleted via the
+ // <ace_cleanup_destroyer>. If you need more flexiblity, see the
+ // <other at_exit> method below. For OS's that do not have
+ // processes, cleanup takes place at the end of <main>. Returns 0
+ // on success. On failure, returns -1 and sets errno to: EAGAIN if
+ // shutting down, ENOMEM if insufficient virtual memory, or EEXIST
+ // if the object (or array) had already been registered.
+
+ static int at_exit (void *object,
+ ACE_CLEANUP_FUNC cleanup_hook,
+ void *param);
+ // Register an object (or array) for cleanup at process termination.
+ // "cleanup_hook" points to a (global, or static member) function
+ // that is called for the object or array when it to be destroyed.
+ // It may perform any necessary cleanup specific for that object or
+ // its class. "param" is passed as the second parameter to the
+ // "cleanup_hook" function; the first parameter is the object (or
+ // array) to be destroyed. "cleanup_hook", for example, may delete
+ // the object (or array). For OS's that do not have processes, this
+ // function is the same as <at_thread_exit>. Returns 0 on success.
+ // On failure, returns -1 and sets errno to: EAGAIN if shutting
+ // down, ENOMEM if insufficient virtual memory, or EEXIST if the
+ // object (or array) had already been registered.
+
+private:
+ // Force allocation on the heap.
+ TAO_Singleton_Manager (void);
+ ~TAO_Singleton_Manager (void);
+
+ // Disallow copying by not implementing the following . . .
+ TAO_Singleton_Manager (const TAO_Singleton_Manager &);
+ TAO_Singleton_Manager &operator= (const TAO_Singleton_Manager &);
+
+ int at_exit_i (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param);
+ // Register an object or array for deletion at program termination.
+ // See description of static version above for return values.
+
+private:
+
+ static TAO_Singleton_Manager *instance_;
+ // Singleton instance pointer.
+
+ static void *preallocated_object[TAO_PREALLOCATED_OBJECTS];
+ // Table of preallocated objects.
+
+ sigset_t *default_mask_;
+ // Default signal set used, for example, in ACE_Sig_Guard.
+
+ ACE_Thread_Hook *thread_hook_;
+ // Thread hook that's used by this process.
+
+ ACE_OS_Exit_Info exit_info_;
+ // For at_exit support.
+
+ int registered_with_object_manager_;
+ // Indicates if TAO_Singleton_Manager is registered with the
+ // ACE_Object_Manager.
+
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ ACE_Recursive_Thread_Mutex *internal_lock_;
+ // Lock that is used to guard internal structures.
+#endif /* ACE_MT_SAFE */
+};
+
+#if defined (__ACE_INLINE__)
+# include "tao/TAO_Singleton_Manager.inl"
+#endif /* __ACE_INLINE__ */
+
+#include "ace/post.h"
+
+#endif /* TAO_OBJECT_MANAGER_H */