00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Thread_Exit.h 00006 * 00007 * $Id: Thread_Exit.h 78460 2007-05-23 13:33:56Z johnnyw $ 00008 * 00009 * @author Carlos O'Ryan <coryan@uci.edu> 00010 */ 00011 //============================================================================= 00012 00013 00014 #ifndef ACE_THREAD_EXIT_H 00015 #define ACE_THREAD_EXIT_H 00016 #include /**/ "ace/pre.h" 00017 00018 #include /**/ "ace/config-all.h" 00019 00020 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00021 # pragma once 00022 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00023 00024 #include "ace/Thread_Control.h" 00025 00026 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00027 00028 /** 00029 * @class ACE_Thread_Exit 00030 * 00031 * @brief Keep exit information for a Thread in thread specific storage. 00032 * so that the thread-specific exit hooks will get called no 00033 * matter how the thread exits (e.g., via <ACE_Thread::exit>, C++ 00034 * or Win32 exception, "falling off the end" of the thread entry 00035 * point function, etc.). 00036 * 00037 * This clever little helper class is stored in thread-specific 00038 * storage using the <ACE_TSS> wrapper. When a thread exits the 00039 * <ACE_TSS::cleanup> function deletes this object, thereby 00040 * closing it down gracefully. 00041 */ 00042 class ACE_Export ACE_Thread_Exit 00043 { 00044 public: 00045 /// Capture the Thread that will be cleaned up automatically. 00046 ACE_Thread_Exit (void); 00047 00048 /// Set the ACE_Thread_Manager. 00049 void thr_mgr (ACE_Thread_Manager *tm); 00050 00051 /// Destructor calls the thread-specific exit hooks when a thread 00052 /// exits. 00053 ~ACE_Thread_Exit (void); 00054 00055 /// Singleton access point. 00056 static ACE_Thread_Exit *instance (void); 00057 00058 /// Cleanup method, used by the ACE_Object_Manager to destroy the 00059 /// singleton. 00060 static void cleanup (void *instance); 00061 00062 private: 00063 /// Automatically add/remove the thread from the 00064 /// ACE_Thread_Manager. 00065 ACE_Thread_Control thread_control_; 00066 00067 /** 00068 * Used to detect whether we should create a new instance (or not) 00069 * within the instance method -- we don't trust the instance_ ptr 00070 * because the destructor may have run (if ACE::fini() was called). 00071 * See bug #526. 00072 * We don't follow the singleton pattern due to dependency issues. 00073 */ 00074 static unsigned int is_constructed_; 00075 }; 00076 00077 /** 00078 * @class ACE_Thread_Exit_Maybe 00079 * 00080 * @brief A version of ACE_Thread_Exit that is created dynamically 00081 * under the hood if the flag is set to TRUE. 00082 * 00083 * Allows the appearance of a "smart pointer", but is not 00084 * always created. 00085 */ 00086 class ACE_Export ACE_Thread_Exit_Maybe 00087 { 00088 public: 00089 /// Don't create an ACE_Thread_Exit instance by default. 00090 ACE_Thread_Exit_Maybe (int flag = 0); 00091 00092 /// Destroys the underlying ACE_Thread_Exit instance if it exists. 00093 ~ACE_Thread_Exit_Maybe (void); 00094 00095 /// Delegates to underlying instance. 00096 ACE_Thread_Exit * operator -> (void) const; 00097 00098 /// Returns the underlying instance. 00099 ACE_Thread_Exit * instance (void) const; 00100 00101 private: 00102 00103 /// Holds the underlying instance. 00104 ACE_Thread_Exit *instance_; 00105 00106 }; 00107 00108 ACE_END_VERSIONED_NAMESPACE_DECL 00109 00110 #include /**/ "ace/post.h" 00111 #endif /* ACE_THREAD_EXIT_H */