00001 /* -*- C++ -*- */ 00002 00003 //============================================================================= 00004 /** 00005 * @file Dump.h 00006 * 00007 * Dump.h,v 4.19 2005/10/28 16:14:52 ossama Exp 00008 * 00009 * 00010 * A prototype mechanism that allow all ACE objects to be registered 00011 * with a central in-memory "database" that can dump the state of all 00012 * live ACE objects (e.g., from within a debugger). 00013 * 00014 * The macros which allow easy registration and removal of objects to be 00015 * dumped (ACE_REGISTER_OBJECT and ACE_REMOVE_OBJECT) are turned into 00016 * no-ops by compiling with the ACE_NDEBUG macro defined. This allows 00017 * usage to be removed in "release mode" builds without changing code. 00018 * 00019 * There are several interesting aspects to this design: 00020 * 00021 * 1. It uses the External Polymorphism pattern to avoid having to 00022 * derive all ACE classes from a common base class that has virtual 00023 * methods (this is crucial to avoid unnecessary overhead). In 00024 * addition, there is no additional space added to ACE objects 00025 * (this is crucial to maintain binary layout compatibility). 00026 * 00027 * 2. This mechanism can be conditionally compiled in order to 00028 * completely disable this feature entirely. Moreover, by 00029 * using macros there are relatively few changes to ACE code. 00030 * 00031 * 3. This mechanism copes with single-inheritance hierarchies of 00032 * dumpable classes. In such cases we typically want only one 00033 * dump, corresponding to the most derived instance. Thanks to 00034 * Christian Millour (chris@etca.fr) for illustrating how to do 00035 * this. Note, however, that this scheme doesn't generalize to 00036 * work with multiple-inheritance or virtual base classes. 00037 * 00038 * Future work includes: 00039 * 00040 * 1. Using a dynamic object table rather than a static table 00041 * 00042 * 2. Adding support to allow particular classes of objects to 00043 * be selectively dumped. 00044 * 00045 * 00046 * @author Doug Schmidt 00047 */ 00048 //============================================================================= 00049 00050 00051 #ifndef ACE_DUMP_H 00052 #define ACE_DUMP_H 00053 #include /**/ "ace/pre.h" 00054 00055 #include "ace/ACE_export.h" 00056 00057 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00058 # pragma once 00059 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00060 00061 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00062 00063 /** 00064 * @class ACE_Dumpable 00065 * 00066 * @brief Base class that defines a uniform interface for all object 00067 * dumping. 00068 */ 00069 class ACE_Export ACE_Dumpable 00070 { 00071 public: 00072 friend class ACE_ODB; 00073 friend class ACE_Dumpable_Ptr; 00074 00075 /// Constructor. 00076 ACE_Dumpable (const void *); 00077 00078 /// This pure virtual method must be filled in by a subclass. 00079 virtual void dump (void) const = 0; 00080 00081 protected: 00082 virtual ~ACE_Dumpable (void); 00083 00084 private: 00085 /// Pointer to the object that is being stored. 00086 const void *this_; 00087 }; 00088 00089 /** 00090 * @class ACE_Dumpable_Ptr 00091 * 00092 * @brief A smart pointer stored in the in-memory object database 00093 * ACE_ODB. The pointee (if any) is deleted when reassigned. 00094 */ 00095 class ACE_Export ACE_Dumpable_Ptr 00096 { 00097 public: 00098 ACE_Dumpable_Ptr (const ACE_Dumpable *dumper = 0); 00099 const ACE_Dumpable *operator->() const; 00100 void operator= (const ACE_Dumpable *dumper) const; 00101 00102 private: 00103 /// "Real" pointer to the underlying abstract base class 00104 /// pointer that does the real work. 00105 const ACE_Dumpable *dumper_; 00106 }; 00107 00108 /** 00109 * @class ACE_ODB 00110 * 00111 * @brief This is the object database (ODB) that keeps track of all 00112 * live ACE objects. 00113 */ 00114 class ACE_Export ACE_ODB 00115 { 00116 public: 00117 /// @todo This is clearly inadequate and should be dynamic... 00118 enum {MAX_TABLE_SIZE = 100000}; 00119 00120 /// Iterates through the entire set of registered objects and 00121 /// dumps their state. 00122 void dump_objects (void); 00123 00124 /// Add the tuple <dumper, this_> to the list of registered ACE objects. 00125 void register_object (const ACE_Dumpable *dumper); 00126 00127 /// Use <this_> to locate and remove the associated <dumper> from the 00128 /// list of registered ACE objects. 00129 void remove_object (const void *this_); 00130 00131 /// Interface to the Singleton instance of the object database. 00132 static ACE_ODB *instance (void); 00133 00134 private: 00135 ACE_ODB (void); // Ensure we have a Singleton... 00136 00137 struct Tuple 00138 { 00139 /// Pointer to the object that is registered. 00140 const void *this_; 00141 00142 /// Smart pointer to the ACE_Dumpable object associated with this_. 00143 /// This uses an ACE_Dumpable_Ptr, instead of a bare pointer, to 00144 /// cope with hierarchies of dumpable classes. In such cases we 00145 /// typically want only one dump, corresponding to the most derived 00146 /// instance. To achieve this, the handle registered for the 00147 /// subobject corresponding to the base class is destroyed (hence 00148 /// on destruction of the subobject its handle won't exist anymore 00149 /// and we'll have to check for that). 00150 const ACE_Dumpable_Ptr dumper_; 00151 00152 Tuple (void) : dumper_(0) {} 00153 }; 00154 00155 /// Singleton instance of this class. 00156 static ACE_ODB *instance_; 00157 00158 /// The current implementation is very simple-minded and will be 00159 /// changed to be dynamic. 00160 Tuple object_table_[ACE_ODB::MAX_TABLE_SIZE]; 00161 00162 /// Current size of <object_table_>. 00163 int current_size_; 00164 }; 00165 00166 ACE_END_VERSIONED_NAMESPACE_DECL 00167 00168 // Include the templates classes at this point. 00169 #include "ace/Dump_T.h" 00170 00171 #include /**/ "ace/post.h" 00172 #endif /* ACE_DUMP_H */