diff options
author | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-08-07 20:47:18 +0000 |
---|---|---|
committer | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-08-07 20:47:18 +0000 |
commit | 684f97ab634c5fcc5caf7f59ec8575004cf47caf (patch) | |
tree | f08d3d5031369527a11659d901953f6adbe7b21b | |
parent | 0e39dd45e5c58320c64ddc21191814db3fab2ed1 (diff) | |
download | ATCD-684f97ab634c5fcc5caf7f59ec8575004cf47caf.tar.gz |
This commit was manufactured by cvs2svn to create branch 'ft_tao_2'.
-rw-r--r-- | TAO/tao/DLL_ORB.cpp | 148 | ||||
-rw-r--r-- | TAO/tao/DLL_ORB.h | 88 | ||||
-rw-r--r-- | TAO/tao/TAO_Export.h | 40 | ||||
-rw-r--r-- | TAO/tao/TAO_Singleton.cpp | 206 | ||||
-rw-r--r-- | TAO/tao/TAO_Singleton.h | 129 | ||||
-rw-r--r-- | TAO/tao/TAO_Singleton_Manager.cpp | 266 | ||||
-rw-r--r-- | TAO/tao/TAO_Singleton_Manager.h | 188 |
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 */ |