diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
commit | 940b4d1848e8c70ab7642901a68594e8016caffc (patch) | |
tree | eb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /include/salhelper | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream.tar.xz libreoffice-upstream.zip |
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'include/salhelper')
-rw-r--r-- | include/salhelper/condition.hxx | 112 | ||||
-rw-r--r-- | include/salhelper/dynload.hxx | 205 | ||||
-rw-r--r-- | include/salhelper/linkhelper.hxx | 75 | ||||
-rw-r--r-- | include/salhelper/refobj.hxx | 98 | ||||
-rw-r--r-- | include/salhelper/salhelperdllapi.h | 34 | ||||
-rw-r--r-- | include/salhelper/simplereferenceobject.hxx | 118 | ||||
-rw-r--r-- | include/salhelper/singletonref.hxx | 199 | ||||
-rw-r--r-- | include/salhelper/thread.hxx | 93 | ||||
-rw-r--r-- | include/salhelper/timer.hxx | 222 |
9 files changed, 1156 insertions, 0 deletions
diff --git a/include/salhelper/condition.hxx b/include/salhelper/condition.hxx new file mode 100644 index 000000000..0f936d4e5 --- /dev/null +++ b/include/salhelper/condition.hxx @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#ifndef INCLUDED_SALHELPER_CONDITION_HXX +#define INCLUDED_SALHELPER_CONDITION_HXX + + +#include "osl/conditn.hxx" +#include "salhelper/salhelperdllapi.h" + +namespace osl { class Mutex; } + +namespace salhelper +{ + + class SALHELPER_DLLPUBLIC Condition + { + friend class ConditionModifier; + friend class ConditionWaiter; + + public: + + Condition(osl::Mutex& aMutex); + + virtual ~Condition(); + + + protected: + + virtual bool applies() const = 0; + + + private: + Condition(Condition &) SAL_DELETED_FUNCTION; + void operator =(Condition &) SAL_DELETED_FUNCTION; + + osl::Mutex& m_aMutex; + osl::Condition m_aCondition; + }; + + + class SALHELPER_DLLPUBLIC ConditionModifier + { + public: + + ConditionModifier(Condition& aCond); + + ~ConditionModifier(); + + + private: + ConditionModifier(ConditionModifier &) SAL_DELETED_FUNCTION; + void operator =(ConditionModifier &) SAL_DELETED_FUNCTION; + + Condition& m_aCond; + }; + + + class SALHELPER_DLLPUBLIC ConditionWaiter + { + public: + + ConditionWaiter(Condition& aCond); + + struct SALHELPER_DLLPUBLIC timedout { + timedout(); + + timedout(timedout const &); + + virtual ~timedout(); + + timedout & operator =(timedout const &); + }; + + /// @throws timedout + ConditionWaiter(Condition& aCond,sal_uInt32 milliSec); + + + ~ConditionWaiter(); + + + private: + ConditionWaiter(ConditionWaiter &) SAL_DELETED_FUNCTION; + void operator =(ConditionWaiter &) SAL_DELETED_FUNCTION; + + Condition& m_aCond; + }; + + +} // namespace salhelper + + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/salhelper/dynload.hxx b/include/salhelper/dynload.hxx new file mode 100644 index 000000000..e24645f9f --- /dev/null +++ b/include/salhelper/dynload.hxx @@ -0,0 +1,205 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SALHELPER_DYNLOAD_HXX +#define INCLUDED_SALHELPER_DYNLOAD_HXX + +#include "sal/types.h" +#include "rtl/ustring.hxx" +#include "osl/module.h" +#include "salhelper/salhelperdllapi.h" + +namespace salhelper +{ + +/** The ORealDynamicLoader is an implementation helper class for the template loader ODynamicLoader. + */ +class SALHELPER_DLLPUBLIC ORealDynamicLoader +{ +public: + /** initializes the loader, loads the library and call the initialization function. + + @param ppSetToZeroInDestructor points to the loader instance which must be set to NULL + if the loader will be destroyed. + @param strModuleName specifies the library name. + @param strInitFunction specifies the name of the initialization function. + */ + static ORealDynamicLoader* SAL_CALL newInstance( + ORealDynamicLoader ** ppSetToZeroInDestructor, + const ::rtl::OUString& strModuleName, + const ::rtl::OUString& strInitFunction ); + + /// increase the reference count. + sal_uInt32 SAL_CALL acquire(); + /// decrease the reference count and delete the last instance. + sal_uInt32 SAL_CALL release(); + + /// returns a pointer to the initialized API function structure. + void* SAL_CALL getApi() const; + +protected: + /** Constructor. + + @param ppSetToZeroInDestructor points to the loader instance which must be set to NULL + if the loader will be destroyed. + @param strModuleName specifies the library name. + @param strInitFunction specifies the name of the initialization function. + @param pApi points to a structure with the initialized API function pointers. + @param pModule points to the loaded library handle. + */ + ORealDynamicLoader( ORealDynamicLoader ** ppSetToZeroInDestructor, + const ::rtl::OUString& strModuleName, + const ::rtl::OUString& strInitFunction, + void* pApi, + oslModule pModule ); + + /// Destructor, try to unload the library. + virtual ~ORealDynamicLoader(); + + /// points to the structure with the initialized API function pointers. + void* m_pApi; + /// stores the reference count. + sal_uInt32 m_refCount; + /// stores the library handle. + oslModule m_pModule; + /// stores the library name. + ::rtl::OUString m_strModuleName; + /// stores the name of the initialization function. + ::rtl::OUString m_strInitFunction; + /** stores a pointer to itself, which must be reset in the destructor to signal + that the loader is invalid. + */ + ORealDynamicLoader ** ppSetToZeroInDestructor; +}; + + +/** The ODynamicLoader provides a special load on call mechanism for dynamic libraries + which support a C-API. + + The libraries must provide a struct with function pointers for all supported C functions. + The loader loads the specified library and call the specified initialization function + to initialize the function pointers with the real functions. Furthermore provides the + loader a reference counter for the library. When the last instance of the laoder will + be destroyed the loader will unload the library. + + @deprecated + Do not use. + */ +template<class API> +class ODynamicLoader +{ +public: + /// Default constructor + ODynamicLoader() + { + m_pLoader = NULL; + } + + /** Constructor, loads the library if necessary otherwise the reference count will + be increased. + + @param strModuleName specifies the library name. + @param strInitFunction specifies the name of the initialization function. + */ + ODynamicLoader( const ::rtl::OUString& strModuleName, + const ::rtl::OUString& strInitFunction ) + { + if (!m_pStaticLoader) + { + m_pStaticLoader = ORealDynamicLoader::newInstance( + &m_pStaticLoader, + strModuleName, + strInitFunction); + } + else + { + m_pStaticLoader->acquire(); + } + + m_pLoader = m_pStaticLoader; + } + + /// Copy constructor + ODynamicLoader(const ODynamicLoader<API>& toCopy) + { + m_pLoader = toCopy.m_pLoader; + if( m_pLoader ) + m_pLoader->acquire(); + } + + /// Destructor, decrease the reference count and unload the library if it is the last instance. + ~ODynamicLoader() + { + if( m_pLoader ) + if (m_pLoader->release()==0) + m_pStaticLoader = NULL; + } + + /// Assign operator + ODynamicLoader<API>& SAL_CALL operator = (const ODynamicLoader<API>& toAssign) + { + if( m_pLoader != toAssign.m_pLoader ) + { + if( toAssign.m_pLoader ) + { + toAssign.m_pLoader->acquire(); + } + if( m_pLoader ) + { + m_pLoader->release(); + } + m_pLoader = toAssign.m_pLoader; + } + + return (*this); + } + + /// returns a pointer to the initialized API function structure. + API* SAL_CALL getApi() const + { + return static_cast<API*>(m_pLoader->getApi()); + } + + /// cast operator, which cast to a pointer with the initialized API function structure. + API* SAL_CALL operator->() const + { + return static_cast<API*>(m_pLoader->getApi()); + } + + /// checks if the loader works on a loaded and initialized library. + bool SAL_CALL isLoaded() const + { + return (m_pLoader != NULL); + } + +protected: + /// stores the real loader helper instance + static ORealDynamicLoader* m_pStaticLoader; + ORealDynamicLoader* m_pLoader; +}; + + +template<class API> +ORealDynamicLoader* ODynamicLoader<API>::m_pStaticLoader = NULL; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/salhelper/linkhelper.hxx b/include/salhelper/linkhelper.hxx new file mode 100644 index 000000000..5eb5b051d --- /dev/null +++ b/include/salhelper/linkhelper.hxx @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_SALHELPER_LINKHELPER_HXX +#define INCLUDED_SALHELPER_LINKHELPER_HXX + +#include "rtl/ustring.hxx" +#include "osl/file.hxx" + +namespace salhelper +{ + class SAL_WARN_UNUSED LinkResolver + { + public: + osl::FileStatus m_aStatus; + + LinkResolver(sal_uInt32 nMask) + : m_aStatus(nMask | + osl_FileStatus_Mask_FileURL | + osl_FileStatus_Mask_Type | + osl_FileStatus_Mask_LinkTargetURL) + { + } + + /** Resolve a file url if it's a symbolic link, to a maximum depth of + * nDepth and fill in m_aStatus with the requested ctor flags + * + * @return osl::FileBase::E_None on success + * + * @see DirectoryItem::getFileStatus + */ + osl::FileBase::RC fetchFileStatus(const rtl::OUString &rURL, + int nDepth = 128) + { + //In an ideal world this wouldn't be inline, but I want to use this + //in jvmfwk hence salhelper, but salhelper is .map controlled and + //getting all the mangled names right is a misery, moving it over + //to visibility markup would drop per-symbol versioning + osl::FileBase::RC eReturn; + + osl::DirectoryItem item; + rtl::OUString sURL(rURL); + while ((eReturn = osl::DirectoryItem::get(sURL, item)) + == osl::File::E_None) + { + if (--nDepth == 0) + { + eReturn = osl::FileBase::E_MULTIHOP; + break; + } + eReturn = item.getFileStatus(m_aStatus); + if (eReturn != osl::File::E_None) + break; + if (m_aStatus.getFileType() != osl::FileStatus::Link) + { + eReturn = osl::FileBase::E_None; + break; + } + sURL = m_aStatus.getLinkTargetURL(); + } + + return eReturn; + } + }; +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/salhelper/refobj.hxx b/include/salhelper/refobj.hxx new file mode 100644 index 000000000..65e636e12 --- /dev/null +++ b/include/salhelper/refobj.hxx @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SALHELPER_REFOBJ_HXX +#define INCLUDED_SALHELPER_REFOBJ_HXX + +#include <cassert> + +#include "sal/types.h" +#include "rtl/alloc.h" +#include "osl/interlck.h" + +namespace salhelper +{ + +/** A base implementation for reference-counted objects. + + @deprecated use salhelper::SimpleReferenceObject instead +*/ +class ReferenceObject +{ + /** Representation. + */ + oslInterlockedCount m_nReferenceCount; + + ReferenceObject (const ReferenceObject&) SAL_DELETED_FUNCTION; + ReferenceObject& operator= (const ReferenceObject&) SAL_DELETED_FUNCTION; + +public: + /** Allocation. + */ + static void* operator new (size_t n) + { + return ::rtl_allocateMemory (n); + } + static void operator delete (void* p) + { + ::rtl_freeMemory (p); + } + static void* operator new (size_t, void* p) + { + return p; + } + static void operator delete (void*, void*) + {} + +public: + /** Construction. + */ + ReferenceObject() : m_nReferenceCount(0) + {} + + + void SAL_CALL acquire() + { + osl_atomic_increment(&m_nReferenceCount); + } + + void SAL_CALL release() + { + if (osl_atomic_decrement(&m_nReferenceCount) == 0) + { + // Last reference released. + delete this; + } + } + +protected: + /** Destruction. + */ + virtual ~ReferenceObject() + { + assert(m_nReferenceCount == 0); + } +}; + + +} // namespace salhelper + +#endif /* ! INCLUDED_SALHELPER_REFOBJ_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/salhelper/salhelperdllapi.h b/include/salhelper/salhelperdllapi.h new file mode 100644 index 000000000..3fec05760 --- /dev/null +++ b/include/salhelper/salhelperdllapi.h @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SALHELPER_SALHELPERDLLAPI_H +#define INCLUDED_SALHELPER_SALHELPERDLLAPI_H + +#include "sal/types.h" + +#if defined(SALHELPER_DLLIMPLEMENTATION) +#define SALHELPER_DLLPUBLIC SAL_DLLPUBLIC_EXPORT +#else +#define SALHELPER_DLLPUBLIC SAL_DLLPUBLIC_IMPORT +#endif +#define SALHELPER_DLLPRIVATE SAL_DLLPRIVATE + +#endif // INCLUDED_SALHELPER_SALHELPERDLLAPI_H + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/salhelper/simplereferenceobject.hxx b/include/salhelper/simplereferenceobject.hxx new file mode 100644 index 000000000..2745f0d84 --- /dev/null +++ b/include/salhelper/simplereferenceobject.hxx @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SALHELPER_SIMPLEREFERENCEOBJECT_HXX +#define INCLUDED_SALHELPER_SIMPLEREFERENCEOBJECT_HXX + +#include "osl/interlck.h" +#include "salhelper/salhelperdllapi.h" + +#include <cstddef> +#include <new> + +namespace salhelper { + +/** A simple base implementation for reference-counted objects. + + Classes that want to implement a reference-counting mechanism based on the + acquire()/release() interface should derive from this class. + + The reason to have class local operators new and delete here is technical. + Imagine a class D derived from SimpleReferenceObject, but implemented in + another shared library that happens to use different global operators new + and delete from those used in this shared library (which, sadly, seems to + be possible with shared libraries). Now, without the class local + operators new and delete here, a code sequence like "new D" would use the + global operator new as found in the other shared library, while the code + sequence "delete this" in release() would use the global operator delete + as found in this shared library---and these two operators would not be + guaranteed to match. + + There are no overloaded operators new and delete for placement new here, + because it is felt that the concept of placement new does not work well + with the concept of reference-counted objects; so it seems best to simply + leave those operators out. + + The same problem as with operators new and delete would also be there with + operators new[] and delete[]. But since arrays of reference-counted + objects are of no use, anyway, it seems best to simply + define operators new[] and delete[] as deleted. + */ +class SALHELPER_DLLPUBLIC SimpleReferenceObject +{ +public: + SimpleReferenceObject(): m_nCount(0) {} + + /** @attention + The results are undefined if, for any individual instance of + SimpleReferenceObject, the total number of calls to acquire() exceeds + the total number of calls to release() by a platform dependent amount + (which, hopefully, is quite large). + */ + void acquire() + { osl_atomic_increment(&m_nCount); } + + void release() + { if (osl_atomic_decrement(&m_nCount) == 0) delete this; } + + /** see general class documentation + */ + static void * operator new(std::size_t nSize); + + /** see general class documentation + */ + static void * operator new(std::size_t nSize, + std::nothrow_t const & rNothrow); + + /** see general class documentation + */ + static void operator delete(void * pPtr); + + /** see general class documentation + */ + static void operator delete(void * pPtr, std::nothrow_t const & rNothrow); + +protected: + virtual ~SimpleReferenceObject() COVERITY_NOEXCEPT_FALSE; + + oslInterlockedCount m_nCount; + +private: + /** not implemented + */ + SimpleReferenceObject(SimpleReferenceObject &) SAL_DELETED_FUNCTION; + + /** not implemented + */ + void operator =(SimpleReferenceObject) SAL_DELETED_FUNCTION; + + /** see general class documentation + */ + static void * operator new[](std::size_t) SAL_DELETED_FUNCTION; + + /** see general class documentation + */ + static void operator delete[](void * pPtr) SAL_DELETED_FUNCTION; +}; + +} + +#endif // INCLUDED_SALHELPER_SIMPLEREFERENCEOBJECT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/salhelper/singletonref.hxx b/include/salhelper/singletonref.hxx new file mode 100644 index 000000000..c6e9cbe2a --- /dev/null +++ b/include/salhelper/singletonref.hxx @@ -0,0 +1,199 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SALHELPER_SINGLETONREF_HXX +#define INCLUDED_SALHELPER_SINGLETONREF_HXX + +#include "sal/config.h" + +#include <cstddef> + +#include "osl/mutex.hxx" +#include "rtl/instance.hxx" +#include "osl/diagnose.h" +#include "osl/getglobalmutex.hxx" + + +namespace salhelper{ + + +/** @short template for implementing singleton classes. + + Such classes can be instantiated every time they + are needed. But the internal wrapped object will + be created one times only. Of course it's used + resources are referenced one times only too. + This template hold it alive till the last + reference is gone. Further all operations + on this reference are threadsafe. Only + calls directly to the internal object (which modify + its state) must be made threadsafe by the object itself + or from outside. + + @attention To prevent the code against race conditions, it's not + allowed to start operations inside the ctor + of the internal wrapped object - especially operations + which needs a reference to the same singleton too. + + The only chance to suppress such strange constellations + is a lazy-init mechanism. + + <ul> + <li>a) The singleton class can provide a special init() + method, which must be called as first after creation.</li> + <li>b) The singleton class can call a special impl_init() + method implicit for every called interface method.</li> + </ul> + + Note further that this singleton pattern can work only, if + all user of such singleton are located inside the same library! + Because static values can't be exported - e.g. from windows libraries. + */ +template< class SingletonClass > +class SingletonRef +{ + + // member + + private: + + /** @short pointer to the internal wrapped singleton. */ + static SingletonClass* m_pInstance; + + /** @short ref count, which regulate creation and removing of m_pInstance. */ + static sal_Int32 m_nRef; + + + // interface + + public: + + + /** @short standard ctor. + + The internal wrapped object is created only, + if its ref count was 0. Otherwise this method + does nothing ... except increasing of the internal + ref count! + */ + SingletonRef() + { + // GLOBAL SAFE -> + ::osl::MutexGuard aLock(SingletonRef::ownStaticLock()); + + // must be increased before(!) the check is done. + // Otherwise this check can fail inside the same thread ... + ++m_nRef; + if (m_nRef == 1) + m_pInstance = new SingletonClass(); + + OSL_ENSURE(m_nRef>0 && m_pInstance, "Race? Ref count of singleton >0, but instance is NULL!"); + // <- GLOBAL SAFE + } + + + /** @short standard dtor. + + The internal wrapped object is removed only, + if its ref count will be 0. Otherwise this method + does nothing ... except decreasing of the internal + ref count! + */ + ~SingletonRef() + { + // GLOBAL SAFE -> + ::osl::MutexGuard aLock(SingletonRef::ownStaticLock()); + + // must be decreased before(!) the check is done. + // Otherwise this check can fail inside the same thread ... + --m_nRef; + if (m_nRef == 0) + { + delete m_pInstance; + m_pInstance = NULL; + } + // <- GLOBAL SAFE + } + +#if defined LIBO_INTERNAL_ONLY + SingletonRef & operator =(SingletonRef const &) = default; +#endif + + /** @short Allows rSingle->someBodyOp(). + */ + SingletonClass* operator->() const + { + // GLOBAL SAFE -> + ::osl::MutexGuard aLock(SingletonRef::ownStaticLock()); + return m_pInstance; + // <- GLOBAL SAFE + } + + + /** @short Allows (*rSingle).someBodyOp(). + */ + SingletonClass& operator*() const + { + // GLOBAL SAFE -> + ::osl::MutexGuard aLock(SingletonRef::ownStaticLock()); + return *m_pInstance; + // <- GLOBAL SAFE + } + + + // helper + + private: + SingletonRef(SingletonRef &) SAL_DELETED_FUNCTION; + + /** @short creates an own mutex for guarding static contents. + + The global mutex the osl library is used one times + only to create an own static mutex, which can be used + next time to guard own static member operations. + */ + struct SingletonLockInit + { + ::osl::Mutex* operator()() + { + static ::osl::Mutex aInstance; + return &aInstance; + } + }; + + ::osl::Mutex& ownStaticLock() const + { + return *rtl_Instance< ::osl::Mutex, + SingletonLockInit, + ::osl::MutexGuard, + ::osl::GetGlobalMutex >::create(SingletonLockInit(), ::osl::GetGlobalMutex()); + } +}; + +template< class SingletonClass > +SingletonClass* SingletonRef< SingletonClass >::m_pInstance = NULL; + +template< class SingletonClass > +sal_Int32 SingletonRef< SingletonClass >::m_nRef = 0; + +} // namespace salhelper + +#endif // INCLUDED_SALHELPER_SINGLETONREF_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/salhelper/thread.hxx b/include/salhelper/thread.hxx new file mode 100644 index 000000000..b4fac5493 --- /dev/null +++ b/include/salhelper/thread.hxx @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_SALHELPER_THREAD_HXX +#define INCLUDED_SALHELPER_THREAD_HXX + +#include "sal/config.h" + +#include <cstddef> + +#include "osl/thread.hxx" +#include "sal/types.h" +#include "salhelper/salhelperdllapi.h" +#include "salhelper/simplereferenceobject.hxx" + +namespace salhelper { + +/** + A safe encapsulation of ::osl::Thread. + + @since LibreOffice 3.6 +*/ +class SALHELPER_DLLPUBLIC Thread: + public salhelper::SimpleReferenceObject, private osl::Thread +{ +public: + /** + @param name the thread name, see ::osl_setThreadName; must be a non-null + null terminated string + */ + Thread(char const * name); + + /** + Launch the thread. + + This function must be called at most once. + + Each call of this function should eventually be followed by a call to + ::osl::Thread::join before exit(3), to ensure the thread is no longer + relying on any infrastructure while that infrastructure is being shut + down in atexit handlers. + */ + void launch(); + + using osl::Thread::getIdentifier; + using osl::Thread::join; + using osl::Thread::schedule; + using osl::Thread::terminate; + + // While the below static member functions should arguably always be called + // with qualified (osl::Thread) names, compilers would still complain that + // they are inaccessible from within derivations of salhelper::Thread (an + // alternative would be to force such derivations to use global names, + // prefixed with ::osl::Thread): + using osl::Thread::getCurrentIdentifier; + using osl::Thread::wait; + using osl::Thread::yield; + + static void * operator new(std::size_t size) + { return SimpleReferenceObject::operator new(size); } + + static void operator delete(void * pointer) + { SimpleReferenceObject::operator delete(pointer); } + +protected: + virtual ~Thread() SAL_OVERRIDE; + + /** + The main function executed by the thread. + + Any uncaught exceptions lead to std::terminate. + */ + virtual void execute() = 0; + +private: + virtual void SAL_CALL run() SAL_OVERRIDE; + + virtual void SAL_CALL onTerminated() SAL_OVERRIDE; + + char const * name_; +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/salhelper/timer.hxx b/include/salhelper/timer.hxx new file mode 100644 index 000000000..f6e67f454 --- /dev/null +++ b/include/salhelper/timer.hxx @@ -0,0 +1,222 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#ifndef INCLUDED_SALHELPER_TIMER_HXX +#define INCLUDED_SALHELPER_TIMER_HXX + +#include "salhelper/simplereferenceobject.hxx" +#include "osl/time.h" +#include "salhelper/salhelperdllapi.h" + +namespace salhelper +{ + +/** Helper class for easier manipulation with TimeValue. + * + * Times are seconds in UTC since 01.01.1970 + */ +struct SAL_WARN_UNUSED TTimeValue : public TimeValue +{ + TTimeValue() + { + Seconds = 0; + Nanosec = 0; + } + + TTimeValue( sal_uInt32 Secs, sal_uInt32 Nano ) + { + Seconds = Secs; + Nanosec = Nano; + + normalize(); + } + + TTimeValue(sal_uInt32 MilliSecs) + { + Seconds = MilliSecs / 1000; + Nanosec = (MilliSecs % 1000) * 1000000L; + + normalize(); + } + + TTimeValue( const TimeValue& rTimeValue ) + { + Seconds = rTimeValue.Seconds; + Nanosec = rTimeValue.Nanosec; + + normalize(); + } + + void SAL_CALL normalize() + { + if ( Nanosec > 1000000000 ) + { + Seconds += Nanosec / 1000000000; + Nanosec %= 1000000000; + } + } + + void SAL_CALL addTime( const TTimeValue& Delta ) + { + Seconds += Delta.Seconds; + Nanosec += Delta.Nanosec; + + normalize(); + } + + bool SAL_CALL isEmpty() const + { + return ( ( Seconds == 0 ) && ( Nanosec == 0 ) ); + } +}; + +inline bool operator<( const TTimeValue& rTimeA, const TTimeValue& rTimeB ) +{ + if ( rTimeA.Seconds < rTimeB.Seconds ) + return true; + else if ( rTimeA.Seconds > rTimeB.Seconds ) + return false; + else + return ( rTimeA.Nanosec < rTimeB.Nanosec ); +} + +inline bool operator>( const TTimeValue& rTimeA, const TTimeValue& rTimeB ) +{ + if ( rTimeA.Seconds > rTimeB.Seconds ) + return true; + else if ( rTimeA.Seconds < rTimeB.Seconds ) + return false; + else + return ( rTimeA.Nanosec > rTimeB.Nanosec ); +} + +inline bool operator==( const TTimeValue& rTimeA, const TTimeValue& rTimeB ) +{ + return ( ( rTimeA.Seconds == rTimeB.Seconds ) && + ( rTimeA.Nanosec == rTimeB.Nanosec ) ); +} + +class TimerManager; + +/** Interface for the Timer and handling the event +*/ +class SALHELPER_DLLPUBLIC Timer : public salhelper::SimpleReferenceObject +{ +public: + + /** Constructor. + */ + Timer(); + + /** Constructor. + */ + Timer( const TTimeValue& Time ); + + /** Constructor. + */ + Timer( const TTimeValue& Time, const TTimeValue& RepeatTime ); + + /** Start timer. + */ + void SAL_CALL start(); + + /** Abort timer prematurely. + */ + void SAL_CALL stop(); + + /** Returns sal_True if timer is running. + */ + sal_Bool SAL_CALL isTicking() const; + + /** Is the timer expired? + */ + sal_Bool SAL_CALL isExpired() const; + + /** Does pTimer expires before us? + */ + sal_Bool SAL_CALL expiresBefore( const Timer* pTimer ) const; + + /** Set the absolute time when the timer should fire. + */ + void SAL_CALL setAbsoluteTime( const TTimeValue& Time ); + + /** Set the time to fire to 'now' + Remaining. + */ + void SAL_CALL setRemainingTime( const TTimeValue& Remaining ); + + /** Set the time to fire to 'now' + Remaining with repeat interveal + * Repeat. + */ + void SAL_CALL setRemainingTime( const TTimeValue& Remaining, const TTimeValue& Repeat ); + + /** Adds Time to the 'fire time'. + */ + void SAL_CALL addTime( const TTimeValue& Time ); + + /** Returns the remaining time before timer expiration relative to now. + */ + TTimeValue SAL_CALL getRemainingTime() const; + +protected: + + /** Destructor. + */ + virtual ~Timer() SAL_OVERRIDE; + + /** What should be done when the 'timer fires'. + */ + virtual void SAL_CALL onShot() = 0; + +protected: + + /** holds (initial) expiration time of this timer. + */ + TTimeValue m_aTimeOut; + + /** holds the time of expiration of this timer. + */ + TTimeValue m_aExpired; + + /** holds the time interveal of successive expirations. + */ + TTimeValue m_aRepeatDelta; + + /** Pointer to the next timer (to fire). + */ + Timer* m_pNext; + +private: + + /** Copy constructor deleted. + */ + Timer( const Timer& rTimer ) SAL_DELETED_FUNCTION; + + /** Copy assignment operator deleted. + */ + void SAL_CALL operator=( const Timer& rTimer ) SAL_DELETED_FUNCTION; + + friend class TimerManager; +}; + +} + +#endif // INCLUDED_SALHELPER_TIMER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |