UDK 3.2.7 C/C++ API Reference
|
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: */