summaryrefslogtreecommitdiffstats
path: root/include/salhelper
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /include/salhelper
parentInitial commit. (diff)
downloadlibreoffice-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.hxx112
-rw-r--r--include/salhelper/dynload.hxx205
-rw-r--r--include/salhelper/linkhelper.hxx75
-rw-r--r--include/salhelper/refobj.hxx98
-rw-r--r--include/salhelper/salhelperdllapi.h34
-rw-r--r--include/salhelper/simplereferenceobject.hxx118
-rw-r--r--include/salhelper/singletonref.hxx199
-rw-r--r--include/salhelper/thread.hxx93
-rw-r--r--include/salhelper/timer.hxx222
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: */