libcwd: The C++ Debugging Support Library - Reference Manual
Author: Carlo Wood
Description: C++ debugging support library with ostream debug output
Keywords: libcwd, debug output, debug facility, debug channel, object orientation, OO, C++, nested debug output, ostream, memory allocation, debugging, source file and line number

Main Page Reference Manual Namespace List Compound List Namespace Members Compound Members File Members

# libcwd/macro_ForAllDebugObjects.h

Go to the documentation of this file.

    00001 // $Header$
    00002 //
    00003 // Copyright (C) 2000 - 2004, by
    00004 //
    00005 // Carlo Wood, Run on IRC <carlo@alinoe.com>
    00006 // RSA-1024 0x624ACAD5 1997-01-26                    Sign & Encrypt
    00007 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6  F6 F6 55 DD 1C DC FF 61
    00008 //
    00009 // This file may be distributed under the terms of the Q Public License
    00010 // version 1.0 as appearing in the file LICENSE.QPL included in the
    00011 // packaging of this file.
    00012 //
    00013
    00018 #ifndef LIBCWD_MACRO_FORALLDEBUGOBJECTS_H
    00019 #define LIBCWD_MACRO_FORALLDEBUGOBJECTS_H
    00020
    00021 #ifndef LIBCWD_CONFIG_H
    00022 #include <libcwd/config.h>
    00023 #endif
    00024 #ifndef LIBCWD_PRIVATE_ASSERT_H
    00025 #include <libcwd/private_assert.h>
    00026 #endif
    00027 #ifndef LIBCWD_PRIVATE_INTERNAL_VECTOR_H
    00028 #include <libcwd/private_internal_vector.h>
    00029 #endif
    00030
    00031 //===================================================================================================
    00032 // Macro ForAllDebugObjects
    00033 //
    00034
    00035 namespace libcwd {
    00036
    00037   class debug_ct;
    00038
    00039   namespace _private_ {
    00040
    00041 class debug_objects_ct {
    00042 public:
    00043   typedef internal_vector<debug_ct*> container_type;
    00044 private:
    00045   container_type* WNS_debug_objects;
    00046 public:
    00047   void init(LIBCWD_TSD_PARAM);
    00048 #if LIBCWD_THREAD_SAFE
    00049   void init_and_rdlock(void);
    00050 #endif
    00051   void ST_uninit(void);
    00052   container_type& write_locked(void);
    00053   container_type const& read_locked(void) const;
    00054
    00055   // debug_objects is a global object. If it is destructed then in principle
    00056   // all other global objects could already have been destructed, including
    00057   // debug_ct objects. Therefore, destructing the container with with pointers
    00058   // to the debug objects isn't wrong: accessing it (by using the macro
    00059   // ForAllDebugObjects) is wrong. Call ST_uninit to delete WNS_debug_objects.
    00060   ~debug_objects_ct() { ST_uninit(); }
    00061 };
    00062
    00063 inline
    00064 debug_objects_ct::container_type&
    00065 debug_objects_ct::write_locked(void)
    00066 {
    00067 #if CWDEBUG_DEBUG
    00068   LIBCWD_ASSERT( WNS_debug_objects );
    00069 #endif
    00070   return *WNS_debug_objects;
    00071 }
    00072
    00073 inline
    00074 debug_objects_ct::container_type const&
    00075 debug_objects_ct::read_locked(void) const
    00076 {
    00077 #if CWDEBUG_DEBUG
    00078   LIBCWD_ASSERT( WNS_debug_objects );
    00079 #endif
    00080   return *WNS_debug_objects;
    00081 }
    00082
    00083 extern debug_objects_ct debug_objects;
    00084
    00085   } // namespace _private_
    00086 } // namespace libcwd
    00087
    00088 #if LIBCWD_THREAD_SAFE
    00089 #if CWDEBUG_DEBUGT
    00090 #define LIBCWD_ForAllDebugObjects_LOCK_TSD_DECLARATION LIBCWD_TSD_DECLARATION
    00091 #else
    00092 #define LIBCWD_ForAllDebugObjects_LOCK_TSD_DECLARATION
    00093 #endif
    00094 #define LIBCWD_ForAllDebugObjects_LOCK \
    00095     LIBCWD_ForAllDebugObjects_LOCK_TSD_DECLARATION; \
    00096     LIBCWD_DEFER_CLEANUP_PUSH(&::libcwd::_private_::rwlock_tct< ::libcwd::_private_::debug_objects_instance>::cleanup, NULL); \
    00097     ::libcwd::_private_::debug_objects.init_and_rdlock()
    00098 #define LIBCWD_ForAllDebugObjects_UNLOCK \
    00099     ::libcwd::_private_::rwlock_tct< ::libcwd::_private_::debug_objects_instance>::rdunlock(); \
    00100     LIBCWD_CLEANUP_POP_RESTORE(false);
    00101 #else // !LIBCWD_THREAD_SAFE
    00102 #define LIBCWD_ForAllDebugObjects_LOCK ::libcwd::_private_::debug_objects.init(LIBCWD_TSD)
    00103 #define LIBCWD_ForAllDebugObjects_UNLOCK
    00104 #endif // !LIBCWD_THREAD_SAFE
    00105
    00106 #define LibcwdForAllDebugObjects(dc_namespace, STATEMENT...) \
    00107        do { \
    00108          LIBCWD_ForAllDebugObjects_LOCK; \
    00109          for( ::libcwd::_private_::debug_objects_ct::container_type::\
    00110              const_iterator __libcwd_i(::libcwd::_private_::debug_objects.read_locked().begin());\
    00111              __libcwd_i != ::libcwd::_private_::debug_objects.read_locked().end(); ++__libcwd_i) \
    00112          { \
    00113            using namespace ::libcwd; \
    00114            using namespace dc_namespace; \
    00115            ::libcwd::debug_ct& debugObject(*(*__libcwd_i)); \
    00116            { STATEMENT; } \
    00117          } \
    00118          LIBCWD_ForAllDebugObjects_UNLOCK \
    00119        } \
    00120        while(0)
    00121
    00122 #endif // LIBCWD_MACRO_FORALLDEBUGOBJECTS_H