1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
21 #include "rtl/strbuf.hxx"
22 #include "rtl/string.hxx"
23 #include "rtl/ustring.hxx"
24 #include "osl/process.h"
25 #include "osl/diagnose.hxx"
26 #include "boost/bind.hpp"
29 // define own ones, independent of OSL_DEBUG_LEVEL:
30 #define DEBUGBASE_ENSURE_(c, f, l, m) \
33 if (!(c) && _OSL_GLOBAL osl_assertFailedLine(f, l, m)) \
34 _OSL_GLOBAL osl_breakDebug(); \
36 #define DEBUGBASE_ENSURE(c, m) DEBUGBASE_ENSURE_(c, OSL_THIS_FILE, __LINE__, m)
40 typedef std::vector
<rtl::OString
, rtl::Allocator
<rtl::OString
> > OStringVec
;
42 struct StaticDebugBaseAddressFilter
43 : rtl::StaticWithInit
<OStringVec
, StaticDebugBaseAddressFilter
> {
44 OStringVec
operator()() const {
46 rtl_uString
* pStr
= 0;
47 rtl::OUString
const name(
48 "OSL_DEBUGBASE_STORE_ADDRESSES" );
49 if (osl_getEnvironment( name
.pData
, &pStr
) == osl_Process_E_None
) {
50 rtl::OUString
const str(pStr
);
51 rtl_uString_release(pStr
);
54 vec
.push_back( rtl::OUStringToOString(
55 str
.getToken( 0, ';', nIndex
),
56 RTL_TEXTENCODING_ASCII_US
) );
64 inline bool isSubStr( char const* pStr
, rtl::OString
const& subStr
)
66 return rtl_str_indexOfStr( pStr
, subStr
.getStr() ) >= 0;
69 struct DebugBaseMutex
: ::rtl::Static
<osl::Mutex
, DebugBaseMutex
> {};
75 // These functions presumably should not be extern "C", but changing
76 // that would break binary compatibility.
78 #pragma clang diagnostic push
79 // Guard against slightly older clang versions that don't have
80 // -Wreturn-type-c-linkage...
81 #pragma clang diagnostic ignored "-Wunknown-pragmas"
82 #pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
85 osl::Mutex
& SAL_CALL
osl_detail_ObjectRegistry_getMutex()
88 return DebugBaseMutex::get();
91 #pragma clang diagnostic pop
94 bool SAL_CALL
osl_detail_ObjectRegistry_storeAddresses( char const* pName
)
97 OStringVec
const& rVec
= StaticDebugBaseAddressFilter::get();
101 rtl::OString
const& rFirst
= rVec
[0];
102 if (rtl_str_compare_WithLength( rFirst
.getStr(), rFirst
.getLength(),
103 RTL_CONSTASCII_STRINGPARAM("all") ) == 0)
105 OStringVec::const_iterator
const iEnd( rVec
.end() );
106 return std::find_if( rVec
.begin(), iEnd
,
107 boost::bind( &isSubStr
, pName
, _1
) ) != iEnd
;
110 bool SAL_CALL
osl_detail_ObjectRegistry_checkObjectCount(
111 osl::detail::ObjectRegistryData
const& rData
, std::size_t nExpected
)
115 if (rData
.m_bStoreAddresses
)
116 nSize
= rData
.m_addresses
.size();
118 nSize
= static_cast<std::size_t>(rData
.m_nCount
);
120 bool const bRet
= (nSize
== nExpected
);
122 rtl::OStringBuffer buf
;
123 buf
.append( RTL_CONSTASCII_STRINGPARAM("unexpected number of ") );
124 buf
.append( rData
.m_pName
);
125 buf
.append( RTL_CONSTASCII_STRINGPARAM(": ") );
126 buf
.append( static_cast<sal_Int64
>(nSize
) );
127 buf
.append("; Expected: ");
128 buf
.append( static_cast<sal_Int64
>(nExpected
) );
129 DEBUGBASE_ENSURE( false, buf
.makeStringAndClear().getStr() );
134 void SAL_CALL
osl_detail_ObjectRegistry_registerObject(
135 osl::detail::ObjectRegistryData
& rData
, void const* pObj
)
138 if (rData
.m_bStoreAddresses
) {
139 osl::MutexGuard
const guard( osl_detail_ObjectRegistry_getMutex() );
140 std::pair
<osl::detail::VoidPointerSet::iterator
, bool> const insertion(
141 rData
.m_addresses
.insert(pObj
) );
142 DEBUGBASE_ENSURE( insertion
.second
, "### insertion failed!?" );
143 static_cast<void>(insertion
);
146 osl_atomic_increment(&rData
.m_nCount
);
150 void SAL_CALL
osl_detail_ObjectRegistry_revokeObject(
151 osl::detail::ObjectRegistryData
& rData
, void const* pObj
)
154 if (rData
.m_bStoreAddresses
) {
155 osl::MutexGuard
const guard( osl_detail_ObjectRegistry_getMutex() );
156 std::size_t const n
= rData
.m_addresses
.erase(pObj
);
157 DEBUGBASE_ENSURE( n
== 1, "erased more than 1 entry!?" );
158 static_cast<void>(n
);
161 osl_atomic_decrement(&rData
.m_nCount
);
167 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */