00001 /* -*- C++ -*- */ 00002 00003 //============================================================================= 00004 /** 00005 * @file Dump.h 00006 * 00007 * $Id: Dump.h,v 1.1.1.4 2003/02/21 18:36:32 chad 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/Synch.h" 00056 00057 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00058 # pragma once 00059 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00060 00061 /** 00062 * @class ACE_Dumpable 00063 * 00064 * @brief Base class that defines a uniform interface for all object 00065 * dumping. 00066 */ 00067 class ACE_Export ACE_Dumpable 00068 { 00069 public: 00070 friend class ACE_ODB; 00071 friend class ACE_Dumpable_Ptr; 00072 00073 /// Constructor. 00074 ACE_Dumpable (const void *); 00075 00076 /// This pure virtual method must be filled in by a subclass. 00077 virtual void dump (void) const = 0; 00078 00079 protected: 00080 virtual ~ACE_Dumpable (void); 00081 00082 private: 00083 /// Pointer to the object that is being stored. 00084 const void *this_; 00085 }; 00086 00087 /** 00088 * @class ACE_Dumpable_Ptr 00089 * 00090 * @brief A smart pointer stored in the in-memory object database 00091 * ACE_ODB. The pointee (if any) is deleted when reassigned. 00092 */ 00093 class ACE_Export ACE_Dumpable_Ptr 00094 { 00095 public: 00096 ACE_Dumpable_Ptr (const ACE_Dumpable *dumper = 0); 00097 const ACE_Dumpable *operator->() const; 00098 void operator= (const ACE_Dumpable *dumper) const; 00099 00100 private: 00101 /// "Real" pointer to the underlying abstract base class 00102 /// pointer that does the real work. 00103 const ACE_Dumpable *dumper_; 00104 }; 00105 00106 /** 00107 * @class ACE_ODB 00108 * 00109 * @brief This is the object database (ODB) that keeps track of all 00110 * live ACE objects. 00111 */ 00112 class ACE_Export ACE_ODB 00113 { 00114 public: 00115 /// @todo This is clearly inadequate and should be dynamic... 00116 enum {MAX_TABLE_SIZE = 100000}; 00117 00118 /// Iterates through the entire set of registered objects and 00119 /// dumps their state. 00120 void dump_objects (void); 00121 00122 /// Add the tuple <dumper, this_> to the list of registered ACE objects. 00123 void register_object (const ACE_Dumpable *dumper); 00124 00125 /// Use <this_> to locate and remove the associated <dumper> from the 00126 /// list of registered ACE objects. 00127 void remove_object (const void *this_); 00128 00129 /// Interface to the Singleton instance of the object database. 00130 static ACE_ODB *instance (void); 00131 00132 private: 00133 ACE_ODB (void); // Ensure we have a Singleton... 00134 00135 struct Tuple 00136 { 00137 /// Pointer to the object that is registered. 00138 const void *this_; 00139 00140 /// Smart pointer to the ACE_Dumpable object associated with this_. 00141 /// This uses an ACE_Dumpable_Ptr, instead of a bare pointer, to 00142 /// cope with hierarchies of dumpable classes. In such cases we 00143 /// typically want only one dump, corresponding to the most derived 00144 /// instance. To achieve this, the handle registered for the 00145 /// subobject corresponding to the base class is destroyed (hence 00146 /// on destruction of the subobject its handle won't exist anymore 00147 /// and we'll have to check for that). 00148 const ACE_Dumpable_Ptr dumper_; 00149 00150 Tuple (void) : dumper_(0) {} 00151 }; 00152 00153 /// Singleton instance of this class. 00154 static ACE_ODB *instance_; 00155 00156 /// The current implementation is very simple-minded and will be 00157 /// changed to be dynamic. 00158 Tuple object_table_[ACE_ODB::MAX_TABLE_SIZE]; 00159 00160 /// Current size of <object_table_>. 00161 int current_size_; 00162 }; 00163 00164 // Include the templates classes at this point. 00165 #include "ace/Dump_T.h" 00166 00167 #include "ace/post.h" 00168 #endif /* ACE_DUMP_H */
1.2.14 written by Dimitri van Heesch,
© 1997-2002