diff options
Diffstat (limited to 'ace/Dump.h')
-rw-r--r-- | ace/Dump.h | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/ace/Dump.h b/ace/Dump.h new file mode 100644 index 00000000000..51e8e0d5a9b --- /dev/null +++ b/ace/Dump.h @@ -0,0 +1,166 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Dump.h +// +// = DESCRIPTION +// +// A prototype mechanism that allow all ACE objects to be registered +// with a central in-memory "database" that can dump the state of all +// live ACE objects (e.g., from within a debugger). +// +// To turn on this feature simply compile with -DACE_NDEBUG +// +// There are several interesting aspects to this design: +// +// 1. It uses the External Polymorphism pattern to avoid having to +// derive all ACE classes from a common base class that has virtual +// methods (this is crucial to avoid unnecessary overhead). In +// addition, there is no additional space added to ACE objects +// (this is crucial to maintain binary layout compatibility). +// +// 2. This mechanism can be conditionally compiled in order to +// completely disable this feature entirely. Moreover, by +// using macros there are relatively few changes to ACE code. +// +// 3. This mechanism copes with single-inheritance hierarchies of +// dumpable classes. In such cases we typically want only one +// dump, corresponding to the most derived instance. Thanks to +// Christian Millour (chris@etca.fr) for illustrating how to do +// this. Note, however, that this scheme doesn't generalize to +// work with multiple-inheritance or virtual base classes. +// +// Future work includes: +// +// 1. Using a dynamic object table rather than a static table +// +// 2. Adding support to allow particular classes of objects to +// be selectively dumped. +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_DUMP_H) +#define ACE_DUMP_H + +#include "ace/Synch.h" + +class ACE_Export ACE_Dumpable + // = TITLE + // Base class that defines a uniform interface for all object + // dumping. +{ +friend class ACE_ODB; +friend class ACE_Dumpable_Ptr; +public: + ACE_Dumpable (const void *); + + virtual void dump (void) const = 0; + // This pure virtual method must be filled in by a subclass. + +protected: + virtual ~ACE_Dumpable (void); + +private: + const void *this_; + // Pointer to the object that is being stored. +}; + +class ACE_Export ACE_Dumpable_Ptr + // = TITLE + // A smart pointer stored in the in-memory object database + // ACE_ODB. The pointee (if any) is deleted when reassigned. +{ +public: + ACE_Dumpable_Ptr (const ACE_Dumpable *dumper = 0); + const ACE_Dumpable *operator->() const; + void operator= (const ACE_Dumpable *dumper) const; + +private: + const ACE_Dumpable *dumper_; + // "Real" pointer to the underlying abstract base class + // pointer that does the real work. +}; + +class ACE_Export ACE_ODB + // = TITLE + // This is the object database (ODB) that keeps track of all + // live ACE objects. +{ +public: + enum {MAX_TABLE_SIZE = 100000}; // This is clearly inadequate and should be dynamic... + + void dump_objects (void); + // Iterates through the entire set of registered objects and + // dumps their state. + + void register_object (const ACE_Dumpable *dumper); + // Add the tuple <dumper, this_> to the list of registered ACE objects. + + void remove_object (const void *this_); + // Use <this_> to locate and remove the associated <dumper> from the + // list of registered ACE objects. + + static ACE_ODB *instance (void); + // Interface to the Singleton instance of the object database. + +private: + ACE_ODB (void); // Ensure we have a Singleton... + + struct Tuple + { + const void *this_; + // Pointer to the object that is registered. + + const ACE_Dumpable_Ptr dumper_; + // Smart pointer to the ACE_Dumpable object associated with this_. + // This uses an ACE_Dumpable_Ptr, instead of a bare pointer, to + // cope with hierarchies of dumpable classes. In such cases we + // typically want only one dump, corresponding to the most derived + // instance. To achieve this, the handle registered for the + // subobject corresponding to the base class is destroyed (hence + // on destruction of the subobject its handle won't exist anymore + // and we'll have to check for that). + Tuple() : dumper_(0) {} + }; + + static ACE_ODB *instance_; + // Singleton instance of this class. + + Tuple object_table_[ACE_ODB::MAX_TABLE_SIZE]; + // The current implementation is very simple-minded and will be + // changed to be dynamic. + + int current_size_; + // Current size of <object_table_>. + +#if defined (ACE_MT_SAFE) + static ACE_Thread_Mutex ace_dump_lock_; + // Double-Check lock. +#endif /* ACE_MT_SAFE */ +}; + +#include "ace/Dump_T.h" + +// Some useful macros for conditionally compiling this feature... +#if defined (ACE_NDEBUG) +#define ACE_REGISTER_OBJECT(CLASS) +#define ACE_REMOVE_OBJECT +#else +#define ACE_REGISTER_OBJECT(CLASS) \ + ACE_ODB::instance ()->register_object \ + (new ACE_Dumpable_Adapter<CLASS> (this)); +#define ACE_REMOVE_OBJECT \ + ACE_ODB::instance ()->remove_object \ + ((void *) this); +#endif /* ACE_NDEBUG */ +#endif /* ACE_DUMP_H */ |