diff options
author | Rüdiger Timm <rt@openoffice.org> | 2006-07-26 06:42:17 +0000 |
---|---|---|
committer | Rüdiger Timm <rt@openoffice.org> | 2006-07-26 06:42:17 +0000 |
commit | f56adb887ab43c1c9d34201d5f062acefce7f00b (patch) | |
tree | bda9624d71f4af9abad6c6f0918d812981ac5f54 /sal | |
parent | 143d8de1f293eaca50dd695d6ac365ce6f03fa6c (diff) |
INTEGRATION: CWS presfixes10 (1.1.2); FILE ADDED
2005/11/25 12:41:54 dbo 1.1.2.6: fixed includes
2005/11/25 11:16:00 dbo 1.1.2.5: outlining mutex, supporting "all"
2005/11/25 10:30:27 dbo 1.1.2.4: documentation
2005/11/22 17:11:31 dbo 1.1.2.3: new revised DebugBase
2005/11/10 15:27:18 dbo 1.1.2.2: missing include
2005/11/10 14:06:42 dbo 1.1.2.1: new
Diffstat (limited to 'sal')
-rw-r--r-- | sal/inc/osl/diagnose.hxx | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/sal/inc/osl/diagnose.hxx b/sal/inc/osl/diagnose.hxx new file mode 100644 index 000000000000..0b646c1a8cfb --- /dev/null +++ b/sal/inc/osl/diagnose.hxx @@ -0,0 +1,217 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: diagnose.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2006-07-26 07:42:17 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ +#if ! defined(OSL_DIAGNOSE_HXX_INCLUDED) +#define OSL_DIAGNOSE_HXX_INCLUDED + +#if ! defined(_OSL_DIAGNOSE_H_) +#include "osl/diagnose.h" +#endif +#if ! defined(_OSL_INTERLOCK_H_) +#include "osl/interlck.h" +#endif +#if ! defined(_OSL_MUTEX_HXX_) +#include "osl/mutex.hxx" +#endif +#if ! defined(INCLUDED_RTL_ALLOCATOR_HXX) +#include "rtl/allocator.hxx" +#endif +#if ! defined(_RTL_INSTANCE_HXX_) +#include "rtl/instance.hxx" +#endif +#include <hash_set> +#include <functional> +#include <typeinfo> + +namespace osl { +/// @internal +namespace detail { + +struct ObjectRegistryData; + +} // namespace detail +} // namespace osl + +extern "C" { + +/** @internal */ +bool SAL_CALL osl_detail_ObjectRegistry_storeAddresses( char const* pName ) + SAL_THROW_EXTERN_C(); + +/** @internal */ +bool SAL_CALL osl_detail_ObjectRegistry_checkObjectCount( + ::osl::detail::ObjectRegistryData const& rData, ::std::size_t nExpected ) + SAL_THROW_EXTERN_C(); + +/** @internal */ +void SAL_CALL osl_detail_ObjectRegistry_registerObject( + ::osl::detail::ObjectRegistryData & rData, void const* pObj ) + SAL_THROW_EXTERN_C(); + +/** @internal */ +void SAL_CALL osl_detail_ObjectRegistry_revokeObject( + ::osl::detail::ObjectRegistryData & rData, void const* pObj ) + SAL_THROW_EXTERN_C(); + +/** @internal */ +::osl::Mutex & SAL_CALL osl_detail_ObjectRegistry_getMutex() + SAL_THROW_EXTERN_C(); + +} // extern "C" + +namespace osl { + +/// @internal +namespace detail { + +struct VoidPtrHash : ::std::unary_function<void const*, ::std::size_t> { + ::std::size_t operator()( void const* p ) const { + ::std::size_t const d = static_cast< ::std::size_t >( + reinterpret_cast< ::std::ptrdiff_t >(p) ); + return d + (d >> 3); + } +}; + +typedef ::std::hash_set<void const*, VoidPtrHash, ::std::equal_to<void const*>, + ::rtl::Allocator<void const*> > VoidPointerSet; + +struct ObjectRegistryData { + ObjectRegistryData( ::std::type_info const& rTypeInfo ) + : m_pName(rTypeInfo.name()), m_nCount(0), m_addresses(), + m_bStoreAddresses(osl_detail_ObjectRegistry_storeAddresses(m_pName)){} + + char const* const m_pName; + oslInterlockedCount m_nCount; + VoidPointerSet m_addresses; + bool const m_bStoreAddresses; +}; + +template <typename T> +class ObjectRegistry +{ +public: + ObjectRegistry() : m_data( typeid(T) ) {} + ~ObjectRegistry() { checkObjectCount(0); } + + bool checkObjectCount( ::std::size_t nExpected ) const { + bool const bRet = osl_detail_ObjectRegistry_checkObjectCount( + m_data, nExpected ); + if (!bRet && m_data.m_bStoreAddresses) { + MutexGuard const guard( osl_detail_ObjectRegistry_getMutex() ); + // following loop is for debugging purposes, iterating over map: + VoidPointerSet::const_iterator iPos(m_data.m_addresses.begin()); + VoidPointerSet::const_iterator const iEnd(m_data.m_addresses.end()); + for ( ; iPos != iEnd; ++iPos ) { + T const* pLeakingObj = static_cast<T const*>(*iPos); + OSL_ASSERT( pLeakingObj != 0 ); + static_cast<void>(pLeakingObj); + } + } + return bRet; + } + + void registerObject( T const* pObj ) { + osl_detail_ObjectRegistry_registerObject(m_data, pObj); + } + + void revokeObject( T const* pObj ) { + osl_detail_ObjectRegistry_revokeObject(m_data, pObj); + } + +private: + // not impl: + ObjectRegistry( ObjectRegistry const& ); + ObjectRegistry const& operator=( ObjectRegistry const& ); + + ObjectRegistryData m_data; +}; + +} // namespace detail + +/** Helper class which indicates leaking object(s) of a particular class in + non-pro builds; use e.g. + + <pre> + class MyClass : private osl::DebugBase<MyClass> {...}; + </pre> + + Using the environment variable + + OSL_DEBUGBASE_STORE_ADDRESSES=MyClass;YourClass;... + + you can specify a ';'-separated list of strings matching to class names + (or "all" for all classes), for which DebugBase stores addresses to created + objects instead of just counting them. This enables you to iterate over + leaking objects in your debugger. + + @tpl InheritingClassT binds the template instance to that class + @internal Use at own risk. + For now this is just public (yet unpublished) API and may change + in the future! +*/ +template <typename InheritingClassT> +class DebugBase +{ +public: +#if OSL_DEBUG_LEVEL <= 0 + static bool checkObjectCount( ::std::size_t = 0 ) { return true; } +#else // OSL_DEBUG_LEVEL > 0 + /** @return whether the expected number of objects is alive, + else this function OSL_ASSERTs + */ + static bool checkObjectCount( ::std::size_t nExpected = 0 ) { + return StaticObjectRegistry::get().checkObjectCount(nExpected); + } + +protected: + DebugBase() { + StaticObjectRegistry::get().registerObject( + static_cast<InheritingClassT const*>(this) ); + } + ~DebugBase() { + StaticObjectRegistry::get().revokeObject( + static_cast<InheritingClassT const*>(this) ); + } + +private: + struct StaticObjectRegistry + : ::rtl::Static<detail::ObjectRegistry<InheritingClassT>, + StaticObjectRegistry> {}; +#endif +}; + +} // namespace osl + +#endif // ! defined(OSL_DIAGNOSE_HXX_INCLUDED) + |