summaryrefslogtreecommitdiff
path: root/sal
diff options
context:
space:
mode:
authorRüdiger Timm <rt@openoffice.org>2006-07-26 06:42:17 +0000
committerRüdiger Timm <rt@openoffice.org>2006-07-26 06:42:17 +0000
commitf56adb887ab43c1c9d34201d5f062acefce7f00b (patch)
treebda9624d71f4af9abad6c6f0918d812981ac5f54 /sal
parent143d8de1f293eaca50dd695d6ac365ce6f03fa6c (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.hxx217
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)
+