fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / include / osl / diagnose.hxx
blobbbf1fa7231c47d5e461e33c133fc018fe722885f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #ifndef OSL_DIAGNOSE_HXX_INCLUDED
20 #define OSL_DIAGNOSE_HXX_INCLUDED
22 #include "sal/config.h"
24 #include <functional>
25 #include <typeinfo>
27 #ifndef HAVE_CXX0X
28 #define BOOST_NO_0X_HDR_TYPEINDEX
29 #endif
30 #include "boost/unordered_set.hpp"
31 #include "osl/diagnose.h"
32 #include "osl/interlck.h"
33 #include "osl/mutex.hxx"
34 #include "rtl/allocator.hxx"
35 #include "rtl/instance.hxx"
36 #include "sal/log.hxx"
37 #include "sal/saldllapi.h"
38 #include "sal/types.h"
40 /// @cond INTERNAL
42 namespace osl {
43 namespace detail {
45 struct ObjectRegistryData;
47 } // namespace detail
48 } // namespace osl
50 extern "C" {
52 SAL_DLLPUBLIC bool SAL_CALL osl_detail_ObjectRegistry_storeAddresses(
53 char const* pName )
54 SAL_THROW_EXTERN_C();
56 SAL_DLLPUBLIC bool SAL_CALL osl_detail_ObjectRegistry_checkObjectCount(
57 ::osl::detail::ObjectRegistryData const& rData, ::std::size_t nExpected )
58 SAL_THROW_EXTERN_C();
60 SAL_DLLPUBLIC void SAL_CALL osl_detail_ObjectRegistry_registerObject(
61 ::osl::detail::ObjectRegistryData & rData, void const* pObj )
62 SAL_THROW_EXTERN_C();
64 SAL_DLLPUBLIC void SAL_CALL osl_detail_ObjectRegistry_revokeObject(
65 ::osl::detail::ObjectRegistryData & rData, void const* pObj )
66 SAL_THROW_EXTERN_C();
68 // These functions presumably should not be extern "C", but changing
69 // that would break binary compatibility.
70 #ifdef __clang__
71 #pragma clang diagnostic push
72 // Guard against slightly older clang versions that don't have
73 // -Wreturn-type-c-linkage...
74 #pragma clang diagnostic ignored "-Wunknown-pragmas"
75 #pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
76 #endif
78 SAL_DLLPUBLIC ::osl::Mutex & SAL_CALL osl_detail_ObjectRegistry_getMutex()
79 SAL_THROW_EXTERN_C();
81 #ifdef __clang__
82 #pragma clang diagnostic pop
83 #endif
85 } // extern "C"
87 namespace osl {
89 namespace detail {
91 struct VoidPtrHash : ::std::unary_function<void const*, ::std::size_t> {
92 ::std::size_t operator()( void const* p ) const {
93 ::std::size_t const d = static_cast< ::std::size_t >(
94 reinterpret_cast< ::std::ptrdiff_t >(p) );
95 return d + (d >> 3);
99 typedef ::boost::unordered_set<void const*, VoidPtrHash, ::std::equal_to<void const*>,
100 ::rtl::Allocator<void const*> > VoidPointerSet;
102 struct ObjectRegistryData {
103 ObjectRegistryData( ::std::type_info const& rTypeInfo )
104 : m_pName(rTypeInfo.name()), m_nCount(0), m_addresses(),
105 m_bStoreAddresses(osl_detail_ObjectRegistry_storeAddresses(m_pName)){}
107 char const* const m_pName;
108 oslInterlockedCount m_nCount;
109 VoidPointerSet m_addresses;
110 bool const m_bStoreAddresses;
113 template <typename T>
114 class ObjectRegistry
116 public:
117 ObjectRegistry() : m_data( typeid(T) ) {}
118 ~ObjectRegistry() { checkObjectCount(0); }
120 bool checkObjectCount( ::std::size_t nExpected ) const {
121 bool const bRet = osl_detail_ObjectRegistry_checkObjectCount(
122 m_data, nExpected );
123 if (!bRet && m_data.m_bStoreAddresses) {
124 MutexGuard const guard( osl_detail_ObjectRegistry_getMutex() );
125 // following loop is for debugging purposes, iterating over map:
126 VoidPointerSet::const_iterator iPos(m_data.m_addresses.begin());
127 VoidPointerSet::const_iterator const iEnd(m_data.m_addresses.end());
128 for ( ; iPos != iEnd; ++iPos ) {
129 SAL_WARN_IF( *iPos == 0, "sal.debug", "null pointer" );
132 return bRet;
135 void registerObject( void const* pObj ) {
136 osl_detail_ObjectRegistry_registerObject(m_data, pObj);
139 void revokeObject( void const* pObj ) {
140 osl_detail_ObjectRegistry_revokeObject(m_data, pObj);
143 private:
144 // not impl:
145 ObjectRegistry( ObjectRegistry const& );
146 ObjectRegistry const& operator=( ObjectRegistry const& );
148 ObjectRegistryData m_data;
151 } // namespace detail
153 /** Helper class which indicates leaking object(s) of a particular class in
154 non-pro builds; use e.g.
156 <pre>
157 class MyClass : private osl::DebugBase<MyClass> {...};
158 </pre>
160 Using the environment variable
162 OSL_DEBUGBASE_STORE_ADDRESSES=MyClass;YourClass;...
164 you can specify a ';'-separated list of strings matching to class names
165 (or "all" for all classes), for which DebugBase stores addresses to created
166 objects instead of just counting them. This enables you to iterate over
167 leaking objects in your debugger.
169 @tparam InheritingClassT binds the template instance to that class
170 @attention Use at own risk.
171 For now this is just public (yet unpublished) API and may change
172 in the future!
174 template <typename InheritingClassT>
175 class DebugBase
177 public:
178 #if OSL_DEBUG_LEVEL <= 0
179 static bool checkObjectCount( ::std::size_t = 0 ) { return true; }
180 #else // OSL_DEBUG_LEVEL > 0
181 /** @return whether the expected number of objects is alive,
182 else this function SAL_WARNs
184 static bool checkObjectCount( ::std::size_t nExpected = 0 ) {
185 return StaticObjectRegistry::get().checkObjectCount(nExpected);
188 protected:
189 DebugBase() {
190 StaticObjectRegistry::get().registerObject( this );
192 ~DebugBase() {
193 StaticObjectRegistry::get().revokeObject( this );
196 private:
197 struct StaticObjectRegistry
198 : ::rtl::Static<detail::ObjectRegistry<InheritingClassT>,
199 StaticObjectRegistry> {};
200 #endif
203 } // namespace osl
205 /// @endcond
207 #endif // ! defined(OSL_DIAGNOSE_HXX_INCLUDED)
209 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */