UDK 3.2.7 C/C++ API Reference
osl/diagnose.hxx
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /*************************************************************************
00003  *
00004  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
00005  *
00006  * Copyright 2000, 2010 Oracle and/or its affiliates.
00007  *
00008  * OpenOffice.org - a multi-platform office productivity suite
00009  *
00010  * This file is part of OpenOffice.org.
00011  *
00012  * OpenOffice.org is free software: you can redistribute it and/or modify
00013  * it under the terms of the GNU Lesser General Public License version 3
00014  * only, as published by the Free Software Foundation.
00015  *
00016  * OpenOffice.org is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU Lesser General Public License version 3 for more details
00020  * (a copy is included in the LICENSE file that accompanied this code).
00021  *
00022  * You should have received a copy of the GNU Lesser General Public License
00023  * version 3 along with OpenOffice.org.  If not, see
00024  * <http://www.openoffice.org/license.html>
00025  * for a copy of the LGPLv3 License.
00026  *
00027  ************************************************************************/
00028 #ifndef OSL_DIAGNOSE_HXX_INCLUDED
00029 #define OSL_DIAGNOSE_HXX_INCLUDED
00030 
00031 #include "sal/config.h"
00032 
00033 #include <functional>
00034 #include <typeinfo>
00035 
00036 #ifndef HAVE_CXX0X
00037 #define BOOST_NO_0X_HDR_TYPEINDEX
00038 #endif
00039 #include "boost/unordered_set.hpp"
00040 #include "osl/diagnose.h"
00041 #include "osl/interlck.h"
00042 #include "osl/mutex.hxx"
00043 #include "rtl/allocator.hxx"
00044 #include "rtl/instance.hxx"
00045 #include "sal/log.hxx"
00046 #include "sal/types.h"
00047 
00049 
00050 namespace osl {
00051 namespace detail {
00052 
00053 struct ObjectRegistryData;
00054 
00055 } // namespace detail
00056 } // namespace osl
00057 
00058 extern "C" {
00059 
00060 SAL_DLLPUBLIC bool SAL_CALL osl_detail_ObjectRegistry_storeAddresses(
00061         char const* pName )
00062     SAL_THROW_EXTERN_C();
00063 
00064 SAL_DLLPUBLIC bool SAL_CALL osl_detail_ObjectRegistry_checkObjectCount(
00065     ::osl::detail::ObjectRegistryData const& rData, ::std::size_t nExpected )
00066     SAL_THROW_EXTERN_C();
00067 
00068 SAL_DLLPUBLIC void SAL_CALL osl_detail_ObjectRegistry_registerObject(
00069     ::osl::detail::ObjectRegistryData & rData, void const* pObj )
00070     SAL_THROW_EXTERN_C();
00071 
00072 SAL_DLLPUBLIC void SAL_CALL osl_detail_ObjectRegistry_revokeObject(
00073     ::osl::detail::ObjectRegistryData & rData, void const* pObj )
00074     SAL_THROW_EXTERN_C();
00075 
00076 // These functions presumably should not be extern "C", but changing
00077 // that would break binary compatibility.
00078 #if SUPD < 400
00079 #ifdef __clang__
00080 #pragma clang diagnostic push
00081 // Guard against slightly older clang versions that don't have
00082 // -Wreturn-type-c-linkage...
00083 #pragma clang diagnostic ignored "-Wunknown-pragmas"
00084 #pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
00085 #endif
00086 #endif
00087 SAL_DLLPUBLIC ::osl::Mutex & SAL_CALL osl_detail_ObjectRegistry_getMutex()
00088     SAL_THROW_EXTERN_C();
00089 #if SUPD < 400
00090 #ifdef __clang__
00091 #pragma clang diagnostic pop
00092 #endif
00093 #endif
00094 
00095 } // extern "C"
00096 
00097 namespace osl {
00098 
00099 namespace detail {
00100 
00101 struct VoidPtrHash : ::std::unary_function<void const*, ::std::size_t> {
00102     ::std::size_t operator()( void const* p ) const {
00103         ::std::size_t const d = static_cast< ::std::size_t >(
00104             reinterpret_cast< ::std::ptrdiff_t >(p) );
00105         return d + (d >> 3);
00106     }
00107 };
00108 
00109 typedef ::boost::unordered_set<void const*, VoidPtrHash, ::std::equal_to<void const*>,
00110                         ::rtl::Allocator<void const*> > VoidPointerSet;
00111 
00112 struct ObjectRegistryData {
00113     ObjectRegistryData( ::std::type_info const& rTypeInfo )
00114         : m_pName(rTypeInfo.name()), m_nCount(0), m_addresses(),
00115           m_bStoreAddresses(osl_detail_ObjectRegistry_storeAddresses(m_pName)){}
00116 
00117     char const* const m_pName;
00118     oslInterlockedCount m_nCount;
00119     VoidPointerSet m_addresses;
00120     bool const m_bStoreAddresses;
00121 };
00122 
00123 template <typename T>
00124 class ObjectRegistry
00125 {
00126 public:
00127     ObjectRegistry() : m_data( typeid(T) ) {}
00128     ~ObjectRegistry() { checkObjectCount(0); }
00129 
00130     bool checkObjectCount( ::std::size_t nExpected ) const {
00131         bool const bRet = osl_detail_ObjectRegistry_checkObjectCount(
00132             m_data, nExpected );
00133         if (!bRet && m_data.m_bStoreAddresses) {
00134             MutexGuard const guard( osl_detail_ObjectRegistry_getMutex() );
00135             // following loop is for debugging purposes, iterating over map:
00136             VoidPointerSet::const_iterator iPos(m_data.m_addresses.begin());
00137             VoidPointerSet::const_iterator const iEnd(m_data.m_addresses.end());
00138             for ( ; iPos != iEnd; ++iPos ) {
00139                 SAL_WARN_IF( *iPos == 0, "sal.debug", "null pointer" );
00140             }
00141         }
00142         return bRet;
00143     }
00144 
00145     void registerObject( void const* pObj ) {
00146         osl_detail_ObjectRegistry_registerObject(m_data, pObj);
00147     }
00148 
00149     void revokeObject( void const* pObj ) {
00150         osl_detail_ObjectRegistry_revokeObject(m_data, pObj);
00151     }
00152 
00153 private:
00154     // not impl:
00155     ObjectRegistry( ObjectRegistry const& );
00156     ObjectRegistry const& operator=( ObjectRegistry const& );
00157 
00158     ObjectRegistryData m_data;
00159 };
00160 
00161 } // namespace detail
00162 
00184 template <typename InheritingClassT>
00185 class DebugBase
00186 {
00187 public:
00188 #if OSL_DEBUG_LEVEL <= 0
00189     static bool checkObjectCount( ::std::size_t = 0 ) { return true; }
00190 #else // OSL_DEBUG_LEVEL > 0
00191 
00194     static bool checkObjectCount( ::std::size_t nExpected = 0 ) {
00195         return StaticObjectRegistry::get().checkObjectCount(nExpected);
00196     }
00197 
00198 protected:
00199     DebugBase() {
00200         StaticObjectRegistry::get().registerObject( this );
00201     }
00202     ~DebugBase() {
00203         StaticObjectRegistry::get().revokeObject( this );
00204     }
00205 
00206 private:
00207     struct StaticObjectRegistry
00208         : ::rtl::Static<detail::ObjectRegistry<InheritingClassT>,
00209                         StaticObjectRegistry> {};
00210 #endif
00211 };
00212 
00213 } // namespace osl
00214 
00216 
00217 #endif // ! defined(OSL_DIAGNOSE_HXX_INCLUDED)
00218 
00219 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines