diff options
Diffstat (limited to 'sal/osl/all/debugbase.cxx')
-rw-r--r-- | sal/osl/all/debugbase.cxx | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/sal/osl/all/debugbase.cxx b/sal/osl/all/debugbase.cxx new file mode 100644 index 000000000000..10679cb45ccb --- /dev/null +++ b/sal/osl/all/debugbase.cxx @@ -0,0 +1,161 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sal.hxx" + +#include "rtl/strbuf.hxx" +#include "rtl/string.hxx" +#include "rtl/ustring.hxx" +#include "osl/process.h" +#include "osl/diagnose.hxx" +#include "boost/bind.hpp" +#include <vector> + +// define own ones, independent of OSL_DEBUG_LEVEL: +#define DEBUGBASE_ENSURE_(c, f, l, m) \ + do \ + { \ + if (!(c) && _OSL_GLOBAL osl_assertFailedLine(f, l, m)) \ + _OSL_GLOBAL osl_breakDebug(); \ + } while (0) +#define DEBUGBASE_ENSURE(c, m) DEBUGBASE_ENSURE_(c, OSL_THIS_FILE, __LINE__, m) + +namespace { + +typedef std::vector<rtl::OString, rtl::Allocator<rtl::OString> > OStringVec; + +struct StaticDebugBaseAddressFilter + : rtl::StaticWithInit<OStringVec const, StaticDebugBaseAddressFilter> { + OStringVec const operator()() const { + OStringVec vec; + rtl_uString * pStr = 0; + rtl::OUString const name( + RTL_CONSTASCII_USTRINGPARAM("OSL_DEBUGBASE_STORE_ADDRESSES") ); + if (osl_getEnvironment( name.pData, &pStr ) == osl_Process_E_None) { + rtl::OUString const str(pStr); + rtl_uString_release(pStr); + sal_Int32 nIndex = 0; + do { + vec.push_back( rtl::OUStringToOString( + str.getToken( 0, ';', nIndex ), + RTL_TEXTENCODING_ASCII_US ) ); + } + while (nIndex >= 0); + } + return vec; + } +}; + +inline bool isSubStr( char const* pStr, rtl::OString const& subStr ) +{ + return rtl_str_indexOfStr( pStr, subStr.getStr() ) >= 0; +} + +struct DebugBaseMutex : ::rtl::Static<osl::Mutex, DebugBaseMutex> {}; + +} // anon namespace + +extern "C" { + +osl::Mutex & SAL_CALL osl_detail_ObjectRegistry_getMutex() + SAL_THROW_EXTERN_C() +{ + return DebugBaseMutex::get(); +} + +bool SAL_CALL osl_detail_ObjectRegistry_storeAddresses( char const* pName ) + SAL_THROW_EXTERN_C() +{ + OStringVec const& rVec = StaticDebugBaseAddressFilter::get(); + if (rVec.empty()) + return false; + // check for "all": + rtl::OString const& rFirst = rVec[0]; + if (rtl_str_compare_WithLength( rFirst.getStr(), rFirst.getLength(), + RTL_CONSTASCII_STRINGPARAM("all") ) == 0) + return true; + OStringVec::const_iterator const iEnd( rVec.end() ); + return std::find_if( rVec.begin(), iEnd, + boost::bind( &isSubStr, pName, _1 ) ) != iEnd; +} + +bool SAL_CALL osl_detail_ObjectRegistry_checkObjectCount( + osl::detail::ObjectRegistryData const& rData, std::size_t nExpected ) + SAL_THROW_EXTERN_C() +{ + std::size_t nSize; + if (rData.m_bStoreAddresses) + nSize = rData.m_addresses.size(); + else + nSize = static_cast<std::size_t>(rData.m_nCount); + + bool const bRet = (nSize == nExpected); + if (! bRet) { + rtl::OStringBuffer buf; + buf.append( RTL_CONSTASCII_STRINGPARAM("unexpected number of ") ); + buf.append( rData.m_pName ); + buf.append( RTL_CONSTASCII_STRINGPARAM(": ") ); + buf.append( static_cast<sal_Int64>(nSize) ); + DEBUGBASE_ENSURE( false, buf.makeStringAndClear().getStr() ); + } + return bRet; +} + +void SAL_CALL osl_detail_ObjectRegistry_registerObject( + osl::detail::ObjectRegistryData & rData, void const* pObj ) + SAL_THROW_EXTERN_C() +{ + if (rData.m_bStoreAddresses) { + osl::MutexGuard const guard( osl_detail_ObjectRegistry_getMutex() ); + std::pair<osl::detail::VoidPointerSet::iterator, bool> const insertion( + rData.m_addresses.insert(pObj) ); + DEBUGBASE_ENSURE( insertion.second, "### insertion failed!?" ); + static_cast<void>(insertion); + } + else { + osl_incrementInterlockedCount(&rData.m_nCount); + } +} + +void SAL_CALL osl_detail_ObjectRegistry_revokeObject( + osl::detail::ObjectRegistryData & rData, void const* pObj ) + SAL_THROW_EXTERN_C() +{ + if (rData.m_bStoreAddresses) { + osl::MutexGuard const guard( osl_detail_ObjectRegistry_getMutex() ); + std::size_t const n = rData.m_addresses.erase(pObj); + DEBUGBASE_ENSURE( n == 1, "erased more than 1 entry!?" ); + static_cast<void>(n); + } + else { + osl_decrementInterlockedCount(&rData.m_nCount); + } +} + +} // extern "C" + |